summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/app')
-rw-r--r--src/com/android/gallery3d/app/AbstractGalleryActivity.java343
-rw-r--r--src/com/android/gallery3d/app/ActivityState.java276
-rw-r--r--src/com/android/gallery3d/app/AlbumDataLoader.java397
-rw-r--r--src/com/android/gallery3d/app/AlbumPage.java786
-rw-r--r--src/com/android/gallery3d/app/AlbumPicker.java40
-rw-r--r--src/com/android/gallery3d/app/AlbumSetDataLoader.java393
-rw-r--r--src/com/android/gallery3d/app/AlbumSetPage.java764
-rw-r--r--src/com/android/gallery3d/app/AppBridge.java72
-rw-r--r--src/com/android/gallery3d/app/BatchService.java48
-rw-r--r--src/com/android/gallery3d/app/CommonControllerOverlay.java346
-rw-r--r--src/com/android/gallery3d/app/Config.java127
-rw-r--r--src/com/android/gallery3d/app/ControllerOverlay.java56
-rw-r--r--src/com/android/gallery3d/app/DialogPicker.java41
-rw-r--r--src/com/android/gallery3d/app/EyePosition.java226
-rw-r--r--src/com/android/gallery3d/app/FilmstripPage.java21
-rw-r--r--src/com/android/gallery3d/app/FilterUtils.java257
-rw-r--r--src/com/android/gallery3d/app/Gallery.java274
-rw-r--r--src/com/android/gallery3d/app/GalleryActionBar.java438
-rw-r--r--src/com/android/gallery3d/app/GalleryApp.java41
-rw-r--r--src/com/android/gallery3d/app/GalleryAppImpl.java127
-rw-r--r--src/com/android/gallery3d/app/GalleryContext.java34
-rw-r--r--src/com/android/gallery3d/app/LoadingListener.java27
-rw-r--r--src/com/android/gallery3d/app/Log.java53
-rw-r--r--src/com/android/gallery3d/app/ManageCachePage.java419
-rw-r--r--src/com/android/gallery3d/app/MovieActivity.java263
-rw-r--r--src/com/android/gallery3d/app/MovieControllerOverlay.java185
-rw-r--r--src/com/android/gallery3d/app/MoviePlayer.java525
-rw-r--r--src/com/android/gallery3d/app/MuteVideo.java104
-rw-r--r--src/com/android/gallery3d/app/NotificationIds.java22
-rw-r--r--src/com/android/gallery3d/app/OrientationManager.java166
-rw-r--r--src/com/android/gallery3d/app/PackagesMonitor.java71
-rw-r--r--src/com/android/gallery3d/app/PanoramaMetadataSupport.java93
-rw-r--r--src/com/android/gallery3d/app/PhotoDataAdapter.java1133
-rw-r--r--src/com/android/gallery3d/app/PhotoPage.java1571
-rw-r--r--src/com/android/gallery3d/app/PhotoPageBottomControls.java137
-rw-r--r--src/com/android/gallery3d/app/PhotoPageProgressBar.java50
-rw-r--r--src/com/android/gallery3d/app/PickerActivity.java83
-rw-r--r--src/com/android/gallery3d/app/SinglePhotoDataAdapter.java263
-rw-r--r--src/com/android/gallery3d/app/SinglePhotoPage.java21
-rw-r--r--src/com/android/gallery3d/app/SlideshowDataAdapter.java204
-rw-r--r--src/com/android/gallery3d/app/SlideshowPage.java366
-rw-r--r--src/com/android/gallery3d/app/StateManager.java339
-rw-r--r--src/com/android/gallery3d/app/StitchingChangeListener.java27
-rw-r--r--src/com/android/gallery3d/app/TimeBar.java266
-rw-r--r--src/com/android/gallery3d/app/TransitionStore.java46
-rw-r--r--src/com/android/gallery3d/app/TrimControllerOverlay.java111
-rw-r--r--src/com/android/gallery3d/app/TrimTimeBar.java339
-rw-r--r--src/com/android/gallery3d/app/TrimVideo.java337
-rw-r--r--src/com/android/gallery3d/app/VideoUtils.java328
-rw-r--r--src/com/android/gallery3d/app/Wallpaper.java135
50 files changed, 0 insertions, 12791 deletions
diff --git a/src/com/android/gallery3d/app/AbstractGalleryActivity.java b/src/com/android/gallery3d/app/AbstractGalleryActivity.java
deleted file mode 100644
index ac39aa560..000000000
--- a/src/com/android/gallery3d/app/AbstractGalleryActivity.java
+++ /dev/null
@@ -1,343 +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.app;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.Window;
-import android.view.WindowManager;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.ui.GLRoot;
-import com.android.gallery3d.ui.GLRootView;
-import com.android.gallery3d.util.LightCycleHelper.PanoramaViewHelper;
-import com.android.gallery3d.util.ThreadPool;
-import com.android.photos.data.GalleryBitmapPool;
-
-public class AbstractGalleryActivity extends Activity implements GalleryContext {
- @SuppressWarnings("unused")
- private static final String TAG = "AbstractGalleryActivity";
- private GLRootView mGLRootView;
- private StateManager mStateManager;
- private GalleryActionBar mActionBar;
- private OrientationManager mOrientationManager;
- private TransitionStore mTransitionStore = new TransitionStore();
- private boolean mDisableToggleStatusBar;
- private PanoramaViewHelper mPanoramaViewHelper;
-
- private AlertDialog mAlertDialog = null;
- private BroadcastReceiver mMountReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (getExternalCacheDir() != null) onStorageReady();
- }
- };
- private IntentFilter mMountFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mOrientationManager = new OrientationManager(this);
- toggleStatusBarByOrientation();
- getWindow().setBackgroundDrawable(null);
- mPanoramaViewHelper = new PanoramaViewHelper(this);
- mPanoramaViewHelper.onCreate();
- doBindBatchService();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- mGLRootView.lockRenderThread();
- try {
- super.onSaveInstanceState(outState);
- getStateManager().saveState(outState);
- } finally {
- mGLRootView.unlockRenderThread();
- }
- }
-
- @Override
- public void onConfigurationChanged(Configuration config) {
- super.onConfigurationChanged(config);
- mStateManager.onConfigurationChange(config);
- getGalleryActionBar().onConfigurationChanged();
- invalidateOptionsMenu();
- toggleStatusBarByOrientation();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- return getStateManager().createOptionsMenu(menu);
- }
-
- @Override
- public Context getAndroidContext() {
- return this;
- }
-
- @Override
- public DataManager getDataManager() {
- return ((GalleryApp) getApplication()).getDataManager();
- }
-
- @Override
- public ThreadPool getThreadPool() {
- return ((GalleryApp) getApplication()).getThreadPool();
- }
-
- public synchronized StateManager getStateManager() {
- if (mStateManager == null) {
- mStateManager = new StateManager(this);
- }
- return mStateManager;
- }
-
- public GLRoot getGLRoot() {
- return mGLRootView;
- }
-
- public OrientationManager getOrientationManager() {
- return mOrientationManager;
- }
-
- @Override
- public void setContentView(int resId) {
- super.setContentView(resId);
- mGLRootView = (GLRootView) findViewById(R.id.gl_root_view);
- }
-
- protected void onStorageReady() {
- if (mAlertDialog != null) {
- mAlertDialog.dismiss();
- mAlertDialog = null;
- unregisterReceiver(mMountReceiver);
- }
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- if (getExternalCacheDir() == null) {
- OnCancelListener onCancel = new OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- finish();
- }
- };
- OnClickListener onClick = new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- };
- AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setTitle(R.string.no_external_storage_title)
- .setMessage(R.string.no_external_storage)
- .setNegativeButton(android.R.string.cancel, onClick)
- .setOnCancelListener(onCancel);
- if (ApiHelper.HAS_SET_ICON_ATTRIBUTE) {
- setAlertDialogIconAttribute(builder);
- } else {
- builder.setIcon(android.R.drawable.ic_dialog_alert);
- }
- mAlertDialog = builder.show();
- registerReceiver(mMountReceiver, mMountFilter);
- }
- mPanoramaViewHelper.onStart();
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- private static void setAlertDialogIconAttribute(
- AlertDialog.Builder builder) {
- builder.setIconAttribute(android.R.attr.alertDialogIcon);
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- if (mAlertDialog != null) {
- unregisterReceiver(mMountReceiver);
- mAlertDialog.dismiss();
- mAlertDialog = null;
- }
- mPanoramaViewHelper.onStop();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mGLRootView.lockRenderThread();
- try {
- getStateManager().resume();
- getDataManager().resume();
- } finally {
- mGLRootView.unlockRenderThread();
- }
- mGLRootView.onResume();
- mOrientationManager.resume();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mOrientationManager.pause();
- mGLRootView.onPause();
- mGLRootView.lockRenderThread();
- try {
- getStateManager().pause();
- getDataManager().pause();
- } finally {
- mGLRootView.unlockRenderThread();
- }
- GalleryBitmapPool.getInstance().clear();
- MediaItem.getBytesBufferPool().clear();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mGLRootView.lockRenderThread();
- try {
- getStateManager().destroy();
- } finally {
- mGLRootView.unlockRenderThread();
- }
- doUnbindBatchService();
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- mGLRootView.lockRenderThread();
- try {
- getStateManager().notifyActivityResult(
- requestCode, resultCode, data);
- } finally {
- mGLRootView.unlockRenderThread();
- }
- }
-
- @Override
- public void onBackPressed() {
- // send the back event to the top sub-state
- GLRoot root = getGLRoot();
- root.lockRenderThread();
- try {
- getStateManager().onBackPressed();
- } finally {
- root.unlockRenderThread();
- }
- }
-
- public GalleryActionBar getGalleryActionBar() {
- if (mActionBar == null) {
- mActionBar = new GalleryActionBar(this);
- }
- return mActionBar;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- GLRoot root = getGLRoot();
- root.lockRenderThread();
- try {
- return getStateManager().itemSelected(item);
- } finally {
- root.unlockRenderThread();
- }
- }
-
- protected void disableToggleStatusBar() {
- mDisableToggleStatusBar = true;
- }
-
- // Shows status bar in portrait view, hide in landscape view
- private void toggleStatusBarByOrientation() {
- if (mDisableToggleStatusBar) return;
-
- Window win = getWindow();
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
- win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- } else {
- win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- }
- }
-
- public TransitionStore getTransitionStore() {
- return mTransitionStore;
- }
-
- public PanoramaViewHelper getPanoramaViewHelper() {
- return mPanoramaViewHelper;
- }
-
- protected boolean isFullscreen() {
- return (getWindow().getAttributes().flags
- & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
- }
-
- private BatchService mBatchService;
- private boolean mBatchServiceIsBound = false;
- private ServiceConnection mBatchServiceConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- mBatchService = ((BatchService.LocalBinder)service).getService();
- }
-
- public void onServiceDisconnected(ComponentName className) {
- mBatchService = null;
- }
- };
-
- private void doBindBatchService() {
- bindService(new Intent(this, BatchService.class), mBatchServiceConnection, Context.BIND_AUTO_CREATE);
- mBatchServiceIsBound = true;
- }
-
- private void doUnbindBatchService() {
- if (mBatchServiceIsBound) {
- // Detach our existing connection.
- unbindService(mBatchServiceConnection);
- mBatchServiceIsBound = false;
- }
- }
-
- public ThreadPool getBatchServiceThreadPoolIfAvailable() {
- if (mBatchServiceIsBound && mBatchService != null) {
- return mBatchService.getThreadPool();
- } else {
- throw new RuntimeException("Batch service unavailable");
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/ActivityState.java b/src/com/android/gallery3d/app/ActivityState.java
deleted file mode 100644
index 2f1e0c9d9..000000000
--- a/src/com/android/gallery3d/app/ActivityState.java
+++ /dev/null
@@ -1,276 +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.app;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Configuration;
-import android.os.BatteryManager;
-import android.os.Bundle;
-import android.view.HapticFeedbackConstants;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.Window;
-import android.view.WindowManager;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.anim.StateTransitionAnimation;
-import com.android.gallery3d.glrenderer.RawTexture;
-import com.android.gallery3d.ui.GLView;
-import com.android.gallery3d.ui.PreparePageFadeoutTexture;
-import com.android.gallery3d.util.GalleryUtils;
-
-abstract public class ActivityState {
- protected static final int FLAG_HIDE_ACTION_BAR = 1;
- protected static final int FLAG_HIDE_STATUS_BAR = 2;
- protected static final int FLAG_SCREEN_ON_WHEN_PLUGGED = 4;
- protected static final int FLAG_SCREEN_ON_ALWAYS = 8;
- protected static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 16;
- protected static final int FLAG_SHOW_WHEN_LOCKED = 32;
-
- protected AbstractGalleryActivity mActivity;
- protected Bundle mData;
- protected int mFlags;
-
- protected ResultEntry mReceivedResults;
- protected ResultEntry mResult;
-
- protected static class ResultEntry {
- public int requestCode;
- public int resultCode = Activity.RESULT_CANCELED;
- public Intent resultData;
- }
-
- private boolean mDestroyed = false;
- private boolean mPlugged = false;
- boolean mIsFinishing = false;
-
- private static final String KEY_TRANSITION_IN = "transition-in";
-
- private StateTransitionAnimation.Transition mNextTransition =
- StateTransitionAnimation.Transition.None;
- private StateTransitionAnimation mIntroAnimation;
- private GLView mContentPane;
-
- protected ActivityState() {
- }
-
- protected void setContentPane(GLView content) {
- mContentPane = content;
- if (mIntroAnimation != null) {
- mContentPane.setIntroAnimation(mIntroAnimation);
- mIntroAnimation = null;
- }
- mContentPane.setBackgroundColor(getBackgroundColor());
- mActivity.getGLRoot().setContentPane(mContentPane);
- }
-
- void initialize(AbstractGalleryActivity activity, Bundle data) {
- mActivity = activity;
- mData = data;
- }
-
- public Bundle getData() {
- return mData;
- }
-
- protected void onBackPressed() {
- mActivity.getStateManager().finishState(this);
- }
-
- protected void setStateResult(int resultCode, Intent data) {
- if (mResult == null) return;
- mResult.resultCode = resultCode;
- mResult.resultData = data;
- }
-
- protected void onConfigurationChanged(Configuration config) {
- }
-
- protected void onSaveState(Bundle outState) {
- }
-
- protected void onStateResult(int requestCode, int resultCode, Intent data) {
- }
-
- protected float[] mBackgroundColor;
-
- protected int getBackgroundColorId() {
- return R.color.default_background;
- }
-
- protected float[] getBackgroundColor() {
- return mBackgroundColor;
- }
-
- protected void onCreate(Bundle data, Bundle storedState) {
- mBackgroundColor = GalleryUtils.intColorToFloatARGBArray(
- mActivity.getResources().getColor(getBackgroundColorId()));
- }
-
- protected void clearStateResult() {
- }
-
- BroadcastReceiver mPowerIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
- boolean plugged = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
-
- if (plugged != mPlugged) {
- mPlugged = plugged;
- setScreenFlags();
- }
- }
- }
- };
-
- private void setScreenFlags() {
- final Window win = mActivity.getWindow();
- final WindowManager.LayoutParams params = win.getAttributes();
- if ((0 != (mFlags & FLAG_SCREEN_ON_ALWAYS)) ||
- (mPlugged && 0 != (mFlags & FLAG_SCREEN_ON_WHEN_PLUGGED))) {
- params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
- } else {
- params.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
- }
- if (0 != (mFlags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON)) {
- params.flags |= WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
- } else {
- params.flags &= ~WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
- }
- if (0 != (mFlags & FLAG_SHOW_WHEN_LOCKED)) {
- params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
- } else {
- params.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
- }
- win.setAttributes(params);
- }
-
- protected void transitionOnNextPause(Class<? extends ActivityState> outgoing,
- Class<? extends ActivityState> incoming, StateTransitionAnimation.Transition hint) {
- if (outgoing == SinglePhotoPage.class && incoming == AlbumPage.class) {
- mNextTransition = StateTransitionAnimation.Transition.Outgoing;
- } else if (outgoing == AlbumPage.class && incoming == SinglePhotoPage.class) {
- mNextTransition = StateTransitionAnimation.Transition.PhotoIncoming;
- } else {
- mNextTransition = hint;
- }
- }
-
- protected void performHapticFeedback(int feedbackConstant) {
- mActivity.getWindow().getDecorView().performHapticFeedback(feedbackConstant,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
- }
-
- protected void onPause() {
- if (0 != (mFlags & FLAG_SCREEN_ON_WHEN_PLUGGED)) {
- ((Activity) mActivity).unregisterReceiver(mPowerIntentReceiver);
- }
- if (mNextTransition != StateTransitionAnimation.Transition.None) {
- mActivity.getTransitionStore().put(KEY_TRANSITION_IN, mNextTransition);
- PreparePageFadeoutTexture.prepareFadeOutTexture(mActivity, mContentPane);
- mNextTransition = StateTransitionAnimation.Transition.None;
- }
- }
-
- // should only be called by StateManager
- void resume() {
- AbstractGalleryActivity activity = mActivity;
- ActionBar actionBar = activity.getActionBar();
- if (actionBar != null) {
- if ((mFlags & FLAG_HIDE_ACTION_BAR) != 0) {
- actionBar.hide();
- } else {
- actionBar.show();
- }
- int stateCount = mActivity.getStateManager().getStateCount();
- mActivity.getGalleryActionBar().setDisplayOptions(stateCount > 1, true);
- // Default behavior, this can be overridden in ActivityState's onResume.
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
- }
-
- activity.invalidateOptionsMenu();
-
- setScreenFlags();
-
- boolean lightsOut = ((mFlags & FLAG_HIDE_STATUS_BAR) != 0);
- mActivity.getGLRoot().setLightsOutMode(lightsOut);
-
- ResultEntry entry = mReceivedResults;
- if (entry != null) {
- mReceivedResults = null;
- onStateResult(entry.requestCode, entry.resultCode, entry.resultData);
- }
-
- if (0 != (mFlags & FLAG_SCREEN_ON_WHEN_PLUGGED)) {
- // we need to know whether the device is plugged in to do this correctly
- final IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_BATTERY_CHANGED);
- activity.registerReceiver(mPowerIntentReceiver, filter);
- }
-
- onResume();
-
- // the transition store should be cleared after resume;
- mActivity.getTransitionStore().clear();
- }
-
- // a subclass of ActivityState should override the method to resume itself
- protected void onResume() {
- RawTexture fade = mActivity.getTransitionStore().get(
- PreparePageFadeoutTexture.KEY_FADE_TEXTURE);
- mNextTransition = mActivity.getTransitionStore().get(
- KEY_TRANSITION_IN, StateTransitionAnimation.Transition.None);
- if (mNextTransition != StateTransitionAnimation.Transition.None) {
- mIntroAnimation = new StateTransitionAnimation(mNextTransition, fade);
- mNextTransition = StateTransitionAnimation.Transition.None;
- }
- }
-
- protected boolean onCreateActionBar(Menu menu) {
- // TODO: we should return false if there is no menu to show
- // this is a workaround for a bug in system
- return true;
- }
-
- protected boolean onItemSelected(MenuItem item) {
- return false;
- }
-
- protected void onDestroy() {
- mDestroyed = true;
- }
-
- boolean isDestroyed() {
- return mDestroyed;
- }
-
- public boolean isFinishing() {
- return mIsFinishing;
- }
-
- protected MenuInflater getSupportMenuInflater() {
- return mActivity.getMenuInflater();
- }
-}
diff --git a/src/com/android/gallery3d/app/AlbumDataLoader.java b/src/com/android/gallery3d/app/AlbumDataLoader.java
deleted file mode 100644
index 28a822830..000000000
--- a/src/com/android/gallery3d/app/AlbumDataLoader.java
+++ /dev/null
@@ -1,397 +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.app;
-
-import android.os.Handler;
-import android.os.Message;
-import android.os.Process;
-
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.ContentListener;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.ui.SynchronizedHandler;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-
-public class AlbumDataLoader {
- @SuppressWarnings("unused")
- private static final String TAG = "AlbumDataAdapter";
- private static final int DATA_CACHE_SIZE = 1000;
-
- private static final int MSG_LOAD_START = 1;
- private static final int MSG_LOAD_FINISH = 2;
- private static final int MSG_RUN_OBJECT = 3;
-
- private static final int MIN_LOAD_COUNT = 32;
- private static final int MAX_LOAD_COUNT = 64;
-
- private final MediaItem[] mData;
- private final long[] mItemVersion;
- private final long[] mSetVersion;
-
- public static interface DataListener {
- public void onContentChanged(int index);
- public void onSizeChanged(int size);
- }
-
- private int mActiveStart = 0;
- private int mActiveEnd = 0;
-
- private int mContentStart = 0;
- private int mContentEnd = 0;
-
- private final MediaSet mSource;
- private long mSourceVersion = MediaObject.INVALID_DATA_VERSION;
-
- private final Handler mMainHandler;
- private int mSize = 0;
-
- private DataListener mDataListener;
- private MySourceListener mSourceListener = new MySourceListener();
- private LoadingListener mLoadingListener;
-
- private ReloadTask mReloadTask;
- // the data version on which last loading failed
- private long mFailedVersion = MediaObject.INVALID_DATA_VERSION;
-
- public AlbumDataLoader(AbstractGalleryActivity context, MediaSet mediaSet) {
- mSource = mediaSet;
-
- mData = new MediaItem[DATA_CACHE_SIZE];
- mItemVersion = new long[DATA_CACHE_SIZE];
- mSetVersion = new long[DATA_CACHE_SIZE];
- Arrays.fill(mItemVersion, MediaObject.INVALID_DATA_VERSION);
- Arrays.fill(mSetVersion, MediaObject.INVALID_DATA_VERSION);
-
- mMainHandler = new SynchronizedHandler(context.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_RUN_OBJECT:
- ((Runnable) message.obj).run();
- return;
- case MSG_LOAD_START:
- if (mLoadingListener != null) mLoadingListener.onLoadingStarted();
- return;
- case MSG_LOAD_FINISH:
- if (mLoadingListener != null) {
- boolean loadingFailed =
- (mFailedVersion != MediaObject.INVALID_DATA_VERSION);
- mLoadingListener.onLoadingFinished(loadingFailed);
- }
- return;
- }
- }
- };
- }
-
- public void resume() {
- mSource.addContentListener(mSourceListener);
- mReloadTask = new ReloadTask();
- mReloadTask.start();
- }
-
- public void pause() {
- mReloadTask.terminate();
- mReloadTask = null;
- mSource.removeContentListener(mSourceListener);
- }
-
- public MediaItem get(int index) {
- if (!isActive(index)) {
- return mSource.getMediaItem(index, 1).get(0);
- }
- return mData[index % mData.length];
- }
-
- public int getActiveStart() {
- return mActiveStart;
- }
-
- public boolean isActive(int index) {
- return index >= mActiveStart && index < mActiveEnd;
- }
-
- public int size() {
- return mSize;
- }
-
- // Returns the index of the MediaItem with the given path or
- // -1 if the path is not cached
- public int findItem(Path id) {
- for (int i = mContentStart; i < mContentEnd; i++) {
- MediaItem item = mData[i % DATA_CACHE_SIZE];
- if (item != null && id == item.getPath()) {
- return i;
- }
- }
- return -1;
- }
-
- private void clearSlot(int slotIndex) {
- mData[slotIndex] = null;
- mItemVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
- mSetVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
- }
-
- private void setContentWindow(int contentStart, int contentEnd) {
- if (contentStart == mContentStart && contentEnd == mContentEnd) return;
- int end = mContentEnd;
- int start = mContentStart;
-
- // We need change the content window before calling reloadData(...)
- synchronized (this) {
- mContentStart = contentStart;
- mContentEnd = contentEnd;
- }
- long[] itemVersion = mItemVersion;
- long[] setVersion = mSetVersion;
- if (contentStart >= end || start >= contentEnd) {
- for (int i = start, n = end; i < n; ++i) {
- clearSlot(i % DATA_CACHE_SIZE);
- }
- } else {
- for (int i = start; i < contentStart; ++i) {
- clearSlot(i % DATA_CACHE_SIZE);
- }
- for (int i = contentEnd, n = end; i < n; ++i) {
- clearSlot(i % DATA_CACHE_SIZE);
- }
- }
- if (mReloadTask != null) mReloadTask.notifyDirty();
- }
-
- public void setActiveWindow(int start, int end) {
- if (start == mActiveStart && end == mActiveEnd) return;
-
- Utils.assertTrue(start <= end
- && end - start <= mData.length && end <= mSize);
-
- int length = mData.length;
- mActiveStart = start;
- mActiveEnd = end;
-
- // If no data is visible, keep the cache content
- if (start == end) return;
-
- int contentStart = Utils.clamp((start + end) / 2 - length / 2,
- 0, Math.max(0, mSize - length));
- int contentEnd = Math.min(contentStart + length, mSize);
- if (mContentStart > start || mContentEnd < end
- || Math.abs(contentStart - mContentStart) > MIN_LOAD_COUNT) {
- setContentWindow(contentStart, contentEnd);
- }
- }
-
- private class MySourceListener implements ContentListener {
- @Override
- public void onContentDirty() {
- if (mReloadTask != null) mReloadTask.notifyDirty();
- }
- }
-
- public void setDataListener(DataListener listener) {
- mDataListener = listener;
- }
-
- public void setLoadingListener(LoadingListener listener) {
- mLoadingListener = listener;
- }
-
- private <T> T executeAndWait(Callable<T> callable) {
- FutureTask<T> task = new FutureTask<T>(callable);
- mMainHandler.sendMessage(
- mMainHandler.obtainMessage(MSG_RUN_OBJECT, task));
- try {
- return task.get();
- } catch (InterruptedException e) {
- return null;
- } catch (ExecutionException e) {
- throw new RuntimeException(e);
- }
- }
-
- private static class UpdateInfo {
- public long version;
- public int reloadStart;
- public int reloadCount;
-
- public int size;
- public ArrayList<MediaItem> items;
- }
-
- private class GetUpdateInfo implements Callable<UpdateInfo> {
- private final long mVersion;
-
- public GetUpdateInfo(long version) {
- mVersion = version;
- }
-
- @Override
- public UpdateInfo call() throws Exception {
- if (mFailedVersion == mVersion) {
- // previous loading failed, return null to pause loading
- return null;
- }
- UpdateInfo info = new UpdateInfo();
- long version = mVersion;
- info.version = mSourceVersion;
- info.size = mSize;
- long setVersion[] = mSetVersion;
- for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
- int index = i % DATA_CACHE_SIZE;
- if (setVersion[index] != version) {
- info.reloadStart = i;
- info.reloadCount = Math.min(MAX_LOAD_COUNT, n - i);
- return info;
- }
- }
- return mSourceVersion == mVersion ? null : info;
- }
- }
-
- private class UpdateContent implements Callable<Void> {
-
- private UpdateInfo mUpdateInfo;
-
- public UpdateContent(UpdateInfo info) {
- mUpdateInfo = info;
- }
-
- @Override
- public Void call() throws Exception {
- UpdateInfo info = mUpdateInfo;
- mSourceVersion = info.version;
- if (mSize != info.size) {
- mSize = info.size;
- if (mDataListener != null) mDataListener.onSizeChanged(mSize);
- if (mContentEnd > mSize) mContentEnd = mSize;
- if (mActiveEnd > mSize) mActiveEnd = mSize;
- }
-
- ArrayList<MediaItem> items = info.items;
-
- mFailedVersion = MediaObject.INVALID_DATA_VERSION;
- if ((items == null) || items.isEmpty()) {
- if (info.reloadCount > 0) {
- mFailedVersion = info.version;
- Log.d(TAG, "loading failed: " + mFailedVersion);
- }
- return null;
- }
- int start = Math.max(info.reloadStart, mContentStart);
- int end = Math.min(info.reloadStart + items.size(), mContentEnd);
-
- for (int i = start; i < end; ++i) {
- int index = i % DATA_CACHE_SIZE;
- mSetVersion[index] = info.version;
- MediaItem updateItem = items.get(i - info.reloadStart);
- long itemVersion = updateItem.getDataVersion();
- if (mItemVersion[index] != itemVersion) {
- mItemVersion[index] = itemVersion;
- mData[index] = updateItem;
- if (mDataListener != null && i >= mActiveStart && i < mActiveEnd) {
- mDataListener.onContentChanged(i);
- }
- }
- }
- return null;
- }
- }
-
- /*
- * The thread model of ReloadTask
- * *
- * [Reload Task] [Main Thread]
- * | |
- * getUpdateInfo() --> | (synchronous call)
- * (wait) <---- getUpdateInfo()
- * | |
- * Load Data |
- * | |
- * updateContent() --> | (synchronous call)
- * (wait) updateContent()
- * | |
- * | |
- */
- private class ReloadTask extends Thread {
-
- private volatile boolean mActive = true;
- private volatile boolean mDirty = true;
- private boolean mIsLoading = false;
-
- private void updateLoading(boolean loading) {
- if (mIsLoading == loading) return;
- mIsLoading = loading;
- mMainHandler.sendEmptyMessage(loading ? MSG_LOAD_START : MSG_LOAD_FINISH);
- }
-
- @Override
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
- boolean updateComplete = false;
- while (mActive) {
- synchronized (this) {
- if (mActive && !mDirty && updateComplete) {
- updateLoading(false);
- if (mFailedVersion != MediaObject.INVALID_DATA_VERSION) {
- Log.d(TAG, "reload pause");
- }
- Utils.waitWithoutInterrupt(this);
- if (mActive && (mFailedVersion != MediaObject.INVALID_DATA_VERSION)) {
- Log.d(TAG, "reload resume");
- }
- continue;
- }
- mDirty = false;
- }
- updateLoading(true);
- long version = mSource.reload();
- UpdateInfo info = executeAndWait(new GetUpdateInfo(version));
- updateComplete = info == null;
- if (updateComplete) continue;
- if (info.version != version) {
- info.size = mSource.getMediaItemCount();
- info.version = version;
- }
- if (info.reloadCount > 0) {
- info.items = mSource.getMediaItem(info.reloadStart, info.reloadCount);
- }
- executeAndWait(new UpdateContent(info));
- }
- updateLoading(false);
- }
-
- public synchronized void notifyDirty() {
- mDirty = true;
- notifyAll();
- }
-
- public synchronized void terminate() {
- mActive = false;
- notifyAll();
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/AlbumPage.java b/src/com/android/gallery3d/app/AlbumPage.java
deleted file mode 100644
index 658abbbd4..000000000
--- a/src/com/android/gallery3d/app/AlbumPage.java
+++ /dev/null
@@ -1,786 +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.app;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.MediaStore;
-import android.view.HapticFeedbackConstants;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.widget.Toast;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.MediaDetails;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.filtershow.crop.CropActivity;
-import com.android.gallery3d.filtershow.crop.CropExtras;
-import com.android.gallery3d.glrenderer.FadeTexture;
-import com.android.gallery3d.glrenderer.GLCanvas;
-import com.android.gallery3d.ui.ActionModeHandler;
-import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
-import com.android.gallery3d.ui.AlbumSlotRenderer;
-import com.android.gallery3d.ui.DetailsHelper;
-import com.android.gallery3d.ui.DetailsHelper.CloseListener;
-import com.android.gallery3d.ui.GLRoot;
-import com.android.gallery3d.ui.GLView;
-import com.android.gallery3d.ui.PhotoFallbackEffect;
-import com.android.gallery3d.ui.RelativePosition;
-import com.android.gallery3d.ui.SelectionManager;
-import com.android.gallery3d.ui.SlotView;
-import com.android.gallery3d.ui.SynchronizedHandler;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.GalleryUtils;
-import com.android.gallery3d.util.MediaSetUtils;
-
-
-public class AlbumPage extends ActivityState implements GalleryActionBar.ClusterRunner,
- SelectionManager.SelectionListener, MediaSet.SyncListener, GalleryActionBar.OnAlbumModeSelectedListener {
- @SuppressWarnings("unused")
- private static final String TAG = "AlbumPage";
-
- public static final String KEY_MEDIA_PATH = "media-path";
- public static final String KEY_PARENT_MEDIA_PATH = "parent-media-path";
- public static final String KEY_SET_CENTER = "set-center";
- public static final String KEY_AUTO_SELECT_ALL = "auto-select-all";
- public static final String KEY_SHOW_CLUSTER_MENU = "cluster-menu";
- public static final String KEY_EMPTY_ALBUM = "empty-album";
- public static final String KEY_RESUME_ANIMATION = "resume_animation";
-
- private static final int REQUEST_SLIDESHOW = 1;
- public static final int REQUEST_PHOTO = 2;
- private static final int REQUEST_DO_ANIMATION = 3;
-
- private static final int BIT_LOADING_RELOAD = 1;
- private static final int BIT_LOADING_SYNC = 2;
-
- private static final float USER_DISTANCE_METER = 0.3f;
-
- private boolean mIsActive = false;
- private AlbumSlotRenderer mAlbumView;
- private Path mMediaSetPath;
- private String mParentMediaSetString;
- private SlotView mSlotView;
-
- private AlbumDataLoader mAlbumDataAdapter;
-
- protected SelectionManager mSelectionManager;
-
- private boolean mGetContent;
- private boolean mShowClusterMenu;
-
- private ActionModeHandler mActionModeHandler;
- private int mFocusIndex = 0;
- private DetailsHelper mDetailsHelper;
- private MyDetailsSource mDetailsSource;
- private MediaSet mMediaSet;
- private boolean mShowDetails;
- private float mUserDistance; // in pixel
- private Future<Integer> mSyncTask = null;
- private boolean mLaunchedFromPhotoPage;
- private boolean mInCameraApp;
- private boolean mInCameraAndWantQuitOnPause;
-
- private int mLoadingBits = 0;
- private boolean mInitialSynced = false;
- private int mSyncResult;
- private boolean mLoadingFailed;
- private RelativePosition mOpenCenter = new RelativePosition();
-
- private Handler mHandler;
- private static final int MSG_PICK_PHOTO = 0;
-
- private PhotoFallbackEffect mResumeEffect;
- private PhotoFallbackEffect.PositionProvider mPositionProvider =
- new PhotoFallbackEffect.PositionProvider() {
- @Override
- public Rect getPosition(int index) {
- Rect rect = mSlotView.getSlotRect(index);
- Rect bounds = mSlotView.bounds();
- rect.offset(bounds.left - mSlotView.getScrollX(),
- bounds.top - mSlotView.getScrollY());
- return rect;
- }
-
- @Override
- public int getItemIndex(Path path) {
- int start = mSlotView.getVisibleStart();
- int end = mSlotView.getVisibleEnd();
- for (int i = start; i < end; ++i) {
- MediaItem item = mAlbumDataAdapter.get(i);
- if (item != null && item.getPath() == path) return i;
- }
- return -1;
- }
- };
-
- @Override
- protected int getBackgroundColorId() {
- return R.color.album_background;
- }
-
- private final GLView mRootPane = new GLView() {
- private final float mMatrix[] = new float[16];
-
- @Override
- protected void onLayout(
- boolean changed, int left, int top, int right, int bottom) {
-
- int slotViewTop = mActivity.getGalleryActionBar().getHeight();
- int slotViewBottom = bottom - top;
- int slotViewRight = right - left;
-
- if (mShowDetails) {
- mDetailsHelper.layout(left, slotViewTop, right, bottom);
- } else {
- mAlbumView.setHighlightItemPath(null);
- }
-
- // Set the mSlotView as a reference point to the open animation
- mOpenCenter.setReferencePosition(0, slotViewTop);
- mSlotView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
- GalleryUtils.setViewPointMatrix(mMatrix,
- (right - left) / 2, (bottom - top) / 2, -mUserDistance);
- }
-
- @Override
- protected void render(GLCanvas canvas) {
- canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
- canvas.multiplyMatrix(mMatrix, 0);
- super.render(canvas);
-
- if (mResumeEffect != null) {
- boolean more = mResumeEffect.draw(canvas);
- if (!more) {
- mResumeEffect = null;
- mAlbumView.setSlotFilter(null);
- }
- // We want to render one more time even when no more effect
- // required. So that the animated thumbnails could be draw
- // with declarations in super.render().
- invalidate();
- }
- canvas.restore();
- }
- };
-
- // This are the transitions we want:
- //
- // +--------+ +------------+ +-------+ +----------+
- // | Camera |---------->| Fullscreen |--->| Album |--->| AlbumSet |
- // | View | thumbnail | Photo | up | Page | up | Page |
- // +--------+ +------------+ +-------+ +----------+
- // ^ | | ^ |
- // | | | | | close
- // +----------back--------+ +----back----+ +--back-> app
- //
- @Override
- protected void onBackPressed() {
- if (mShowDetails) {
- hideDetails();
- } else if (mSelectionManager.inSelectionMode()) {
- mSelectionManager.leaveSelectionMode();
- } else {
- if(mLaunchedFromPhotoPage) {
- mActivity.getTransitionStore().putIfNotPresent(
- PhotoPage.KEY_ALBUMPAGE_TRANSITION,
- PhotoPage.MSG_ALBUMPAGE_RESUMED);
- }
- // TODO: fix this regression
- // mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
- if (mInCameraApp) {
- super.onBackPressed();
- } else {
- onUpPressed();
- }
- }
- }
-
- private void onUpPressed() {
- if (mInCameraApp) {
- GalleryUtils.startGalleryActivity(mActivity);
- } else if (mActivity.getStateManager().getStateCount() > 1) {
- super.onBackPressed();
- } else if (mParentMediaSetString != null) {
- Bundle data = new Bundle(getData());
- data.putString(AlbumSetPage.KEY_MEDIA_PATH, mParentMediaSetString);
- mActivity.getStateManager().switchState(
- this, AlbumSetPage.class, data);
- }
- }
-
- private void onDown(int index) {
- mAlbumView.setPressedIndex(index);
- }
-
- private void onUp(boolean followedByLongPress) {
- if (followedByLongPress) {
- // Avoid showing press-up animations for long-press.
- mAlbumView.setPressedIndex(-1);
- } else {
- mAlbumView.setPressedUp();
- }
- }
-
- private void onSingleTapUp(int slotIndex) {
- if (!mIsActive) return;
-
- if (mSelectionManager.inSelectionMode()) {
- MediaItem item = mAlbumDataAdapter.get(slotIndex);
- if (item == null) return; // Item not ready yet, ignore the click
- mSelectionManager.toggle(item.getPath());
- mSlotView.invalidate();
- } else {
- // Render transition in pressed state
- mAlbumView.setPressedIndex(slotIndex);
- mAlbumView.setPressedUp();
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_PHOTO, slotIndex, 0),
- FadeTexture.DURATION);
- }
- }
-
- private void pickPhoto(int slotIndex) {
- pickPhoto(slotIndex, false);
- }
-
- private void pickPhoto(int slotIndex, boolean startInFilmstrip) {
- if (!mIsActive) return;
-
- if (!startInFilmstrip) {
- // Launch photos in lights out mode
- mActivity.getGLRoot().setLightsOutMode(true);
- }
-
- MediaItem item = mAlbumDataAdapter.get(slotIndex);
- if (item == null) return; // Item not ready yet, ignore the click
- if (mGetContent) {
- onGetContent(item);
- } else if (mLaunchedFromPhotoPage) {
- TransitionStore transitions = mActivity.getTransitionStore();
- transitions.put(
- PhotoPage.KEY_ALBUMPAGE_TRANSITION,
- PhotoPage.MSG_ALBUMPAGE_PICKED);
- transitions.put(PhotoPage.KEY_INDEX_HINT, slotIndex);
- onBackPressed();
- } else {
- // Get into the PhotoPage.
- // mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
- Bundle data = new Bundle();
- data.putInt(PhotoPage.KEY_INDEX_HINT, slotIndex);
- data.putParcelable(PhotoPage.KEY_OPEN_ANIMATION_RECT,
- mSlotView.getSlotRect(slotIndex, mRootPane));
- data.putString(PhotoPage.KEY_MEDIA_SET_PATH,
- mMediaSetPath.toString());
- data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH,
- item.getPath().toString());
- data.putInt(PhotoPage.KEY_ALBUMPAGE_TRANSITION,
- PhotoPage.MSG_ALBUMPAGE_STARTED);
- data.putBoolean(PhotoPage.KEY_START_IN_FILMSTRIP,
- startInFilmstrip);
- data.putBoolean(PhotoPage.KEY_IN_CAMERA_ROLL, mMediaSet.isCameraRoll());
- if (startInFilmstrip) {
- mActivity.getStateManager().switchState(this, FilmstripPage.class, data);
- } else {
- mActivity.getStateManager().startStateForResult(
- SinglePhotoPage.class, REQUEST_PHOTO, data);
- }
- }
- }
-
- private void onGetContent(final MediaItem item) {
- DataManager dm = mActivity.getDataManager();
- Activity activity = mActivity;
- if (mData.getString(Gallery.EXTRA_CROP) != null) {
- Uri uri = dm.getContentUri(item.getPath());
- Intent intent = new Intent(CropActivity.CROP_ACTION, uri)
- .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
- .putExtras(getData());
- if (mData.getParcelable(MediaStore.EXTRA_OUTPUT) == null) {
- intent.putExtra(CropExtras.KEY_RETURN_DATA, true);
- }
- activity.startActivity(intent);
- activity.finish();
- } else {
- Intent intent = new Intent(null, item.getContentUri())
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- activity.setResult(Activity.RESULT_OK, intent);
- activity.finish();
- }
- }
-
- public void onLongTap(int slotIndex) {
- if (mGetContent) return;
- MediaItem item = mAlbumDataAdapter.get(slotIndex);
- if (item == null) return;
- mSelectionManager.setAutoLeaveSelectionMode(true);
- mSelectionManager.toggle(item.getPath());
- mSlotView.invalidate();
- }
-
- @Override
- public void doCluster(int clusterType) {
- String basePath = mMediaSet.getPath().toString();
- String newPath = FilterUtils.newClusterPath(basePath, clusterType);
- Bundle data = new Bundle(getData());
- data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
- if (mShowClusterMenu) {
- Context context = mActivity.getAndroidContext();
- data.putString(AlbumSetPage.KEY_SET_TITLE, mMediaSet.getName());
- data.putString(AlbumSetPage.KEY_SET_SUBTITLE,
- GalleryActionBar.getClusterByTypeString(context, clusterType));
- }
-
- // mAlbumView.savePositions(PositionRepository.getInstance(mActivity));
- mActivity.getStateManager().startStateForResult(
- AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
- }
-
- @Override
- protected void onCreate(Bundle data, Bundle restoreState) {
- super.onCreate(data, restoreState);
- mUserDistance = GalleryUtils.meterToPixel(USER_DISTANCE_METER);
- initializeViews();
- initializeData(data);
- mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
- mShowClusterMenu = data.getBoolean(KEY_SHOW_CLUSTER_MENU, false);
- mDetailsSource = new MyDetailsSource();
- Context context = mActivity.getAndroidContext();
-
- if (data.getBoolean(KEY_AUTO_SELECT_ALL)) {
- mSelectionManager.selectAll();
- }
-
- mLaunchedFromPhotoPage =
- mActivity.getStateManager().hasStateClass(FilmstripPage.class);
- mInCameraApp = data.getBoolean(PhotoPage.KEY_APP_BRIDGE, false);
-
- mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_PICK_PHOTO: {
- pickPhoto(message.arg1);
- break;
- }
- default:
- throw new AssertionError(message.what);
- }
- }
- };
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- mIsActive = true;
-
- mResumeEffect = mActivity.getTransitionStore().get(KEY_RESUME_ANIMATION);
- if (mResumeEffect != null) {
- mAlbumView.setSlotFilter(mResumeEffect);
- mResumeEffect.setPositionProvider(mPositionProvider);
- mResumeEffect.start();
- }
-
- setContentPane(mRootPane);
-
- boolean enableHomeButton = (mActivity.getStateManager().getStateCount() > 1) |
- mParentMediaSetString != null;
- GalleryActionBar actionBar = mActivity.getGalleryActionBar();
- actionBar.setDisplayOptions(enableHomeButton, false);
- if (!mGetContent) {
- actionBar.enableAlbumModeMenu(GalleryActionBar.ALBUM_GRID_MODE_SELECTED, this);
- }
-
- // Set the reload bit here to prevent it exit this page in clearLoadingBit().
- setLoadingBit(BIT_LOADING_RELOAD);
- mLoadingFailed = false;
- mAlbumDataAdapter.resume();
-
- mAlbumView.resume();
- mAlbumView.setPressedIndex(-1);
- mActionModeHandler.resume();
- if (!mInitialSynced) {
- setLoadingBit(BIT_LOADING_SYNC);
- mSyncTask = mMediaSet.requestSync(this);
- }
- mInCameraAndWantQuitOnPause = mInCameraApp;
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mIsActive = false;
-
- if (mSelectionManager.inSelectionMode()) {
- mSelectionManager.leaveSelectionMode();
- }
- mAlbumView.setSlotFilter(null);
- mActionModeHandler.pause();
- mAlbumDataAdapter.pause();
- mAlbumView.pause();
- DetailsHelper.pause();
- if (!mGetContent) {
- mActivity.getGalleryActionBar().disableAlbumModeMenu(true);
- }
-
- if (mSyncTask != null) {
- mSyncTask.cancel();
- mSyncTask = null;
- clearLoadingBit(BIT_LOADING_SYNC);
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (mAlbumDataAdapter != null) {
- mAlbumDataAdapter.setLoadingListener(null);
- }
- mActionModeHandler.destroy();
- }
-
- private void initializeViews() {
- mSelectionManager = new SelectionManager(mActivity, false);
- mSelectionManager.setSelectionListener(this);
- Config.AlbumPage config = Config.AlbumPage.get(mActivity);
- mSlotView = new SlotView(mActivity, config.slotViewSpec);
- mAlbumView = new AlbumSlotRenderer(mActivity, mSlotView,
- mSelectionManager, config.placeholderColor);
- mSlotView.setSlotRenderer(mAlbumView);
- mRootPane.addComponent(mSlotView);
- mSlotView.setListener(new SlotView.SimpleListener() {
- @Override
- public void onDown(int index) {
- AlbumPage.this.onDown(index);
- }
-
- @Override
- public void onUp(boolean followedByLongPress) {
- AlbumPage.this.onUp(followedByLongPress);
- }
-
- @Override
- public void onSingleTapUp(int slotIndex) {
- AlbumPage.this.onSingleTapUp(slotIndex);
- }
-
- @Override
- public void onLongTap(int slotIndex) {
- AlbumPage.this.onLongTap(slotIndex);
- }
- });
- mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
- mActionModeHandler.setActionModeListener(new ActionModeListener() {
- @Override
- public boolean onActionItemClicked(MenuItem item) {
- return onItemSelected(item);
- }
- });
- }
-
- private void initializeData(Bundle data) {
- mMediaSetPath = Path.fromString(data.getString(KEY_MEDIA_PATH));
- mParentMediaSetString = data.getString(KEY_PARENT_MEDIA_PATH);
- mMediaSet = mActivity.getDataManager().getMediaSet(mMediaSetPath);
- if (mMediaSet == null) {
- Utils.fail("MediaSet is null. Path = %s", mMediaSetPath);
- }
- mSelectionManager.setSourceMediaSet(mMediaSet);
- mAlbumDataAdapter = new AlbumDataLoader(mActivity, mMediaSet);
- mAlbumDataAdapter.setLoadingListener(new MyLoadingListener());
- mAlbumView.setModel(mAlbumDataAdapter);
- }
-
- private void showDetails() {
- mShowDetails = true;
- if (mDetailsHelper == null) {
- mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource);
- mDetailsHelper.setCloseListener(new CloseListener() {
- @Override
- public void onClose() {
- hideDetails();
- }
- });
- }
- mDetailsHelper.show();
- }
-
- private void hideDetails() {
- mShowDetails = false;
- mDetailsHelper.hide();
- mAlbumView.setHighlightItemPath(null);
- mSlotView.invalidate();
- }
-
- @Override
- protected boolean onCreateActionBar(Menu menu) {
- GalleryActionBar actionBar = mActivity.getGalleryActionBar();
- MenuInflater inflator = getSupportMenuInflater();
- if (mGetContent) {
- inflator.inflate(R.menu.pickup, menu);
- int typeBits = mData.getInt(Gallery.KEY_TYPE_BITS,
- DataManager.INCLUDE_IMAGE);
- actionBar.setTitle(GalleryUtils.getSelectionModePrompt(typeBits));
- } else {
- inflator.inflate(R.menu.album, menu);
- actionBar.setTitle(mMediaSet.getName());
-
- FilterUtils.setupMenuItems(actionBar, mMediaSetPath, true);
-
- menu.findItem(R.id.action_group_by).setVisible(mShowClusterMenu);
- menu.findItem(R.id.action_camera).setVisible(
- MediaSetUtils.isCameraSource(mMediaSetPath)
- && GalleryUtils.isCameraAvailable(mActivity));
-
- }
- actionBar.setSubtitle(null);
- return true;
- }
-
- private void prepareAnimationBackToFilmstrip(int slotIndex) {
- if (mAlbumDataAdapter == null || !mAlbumDataAdapter.isActive(slotIndex)) return;
- MediaItem item = mAlbumDataAdapter.get(slotIndex);
- if (item == null) return;
- TransitionStore transitions = mActivity.getTransitionStore();
- transitions.put(PhotoPage.KEY_INDEX_HINT, slotIndex);
- transitions.put(PhotoPage.KEY_OPEN_ANIMATION_RECT,
- mSlotView.getSlotRect(slotIndex, mRootPane));
- }
-
- private void switchToFilmstrip() {
- if (mAlbumDataAdapter.size() < 1) return;
- int targetPhoto = mSlotView.getVisibleStart();
- prepareAnimationBackToFilmstrip(targetPhoto);
- if(mLaunchedFromPhotoPage) {
- onBackPressed();
- } else {
- pickPhoto(targetPhoto, true);
- }
- }
-
- @Override
- protected boolean onItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home: {
- onUpPressed();
- return true;
- }
- case R.id.action_cancel:
- mActivity.getStateManager().finishState(this);
- return true;
- case R.id.action_select:
- mSelectionManager.setAutoLeaveSelectionMode(false);
- mSelectionManager.enterSelectionMode();
- return true;
- case R.id.action_group_by: {
- mActivity.getGalleryActionBar().showClusterDialog(this);
- return true;
- }
- case R.id.action_slideshow: {
- mInCameraAndWantQuitOnPause = false;
- Bundle data = new Bundle();
- data.putString(SlideshowPage.KEY_SET_PATH,
- mMediaSetPath.toString());
- data.putBoolean(SlideshowPage.KEY_REPEAT, true);
- mActivity.getStateManager().startStateForResult(
- SlideshowPage.class, REQUEST_SLIDESHOW, data);
- return true;
- }
- case R.id.action_details: {
- if (mShowDetails) {
- hideDetails();
- } else {
- showDetails();
- }
- return true;
- }
- case R.id.action_camera: {
- GalleryUtils.startCameraActivity(mActivity);
- return true;
- }
- default:
- return false;
- }
- }
-
- @Override
- protected void onStateResult(int request, int result, Intent data) {
- switch (request) {
- case REQUEST_SLIDESHOW: {
- // data could be null, if there is no images in the album
- if (data == null) return;
- mFocusIndex = data.getIntExtra(SlideshowPage.KEY_PHOTO_INDEX, 0);
- mSlotView.setCenterIndex(mFocusIndex);
- break;
- }
- case REQUEST_PHOTO: {
- if (data == null) return;
- mFocusIndex = data.getIntExtra(PhotoPage.KEY_RETURN_INDEX_HINT, 0);
- mSlotView.makeSlotVisible(mFocusIndex);
- break;
- }
- case REQUEST_DO_ANIMATION: {
- mSlotView.startRisingAnimation();
- break;
- }
- }
- }
-
- @Override
- public void onSelectionModeChange(int mode) {
- switch (mode) {
- case SelectionManager.ENTER_SELECTION_MODE: {
- mActionModeHandler.startActionMode();
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- break;
- }
- case SelectionManager.LEAVE_SELECTION_MODE: {
- mActionModeHandler.finishActionMode();
- mRootPane.invalidate();
- break;
- }
- case SelectionManager.SELECT_ALL_MODE: {
- mActionModeHandler.updateSupportedOperation();
- mRootPane.invalidate();
- break;
- }
- }
- }
-
- @Override
- public void onSelectionChange(Path path, boolean selected) {
- int count = mSelectionManager.getSelectedCount();
- String format = mActivity.getResources().getQuantityString(
- R.plurals.number_of_items_selected, count);
- mActionModeHandler.setTitle(String.format(format, count));
- mActionModeHandler.updateSupportedOperation(path, selected);
- }
-
- @Override
- public void onSyncDone(final MediaSet mediaSet, final int resultCode) {
- Log.d(TAG, "onSyncDone: " + Utils.maskDebugInfo(mediaSet.getName()) + " result="
- + resultCode);
- ((Activity) mActivity).runOnUiThread(new Runnable() {
- @Override
- public void run() {
- GLRoot root = mActivity.getGLRoot();
- root.lockRenderThread();
- mSyncResult = resultCode;
- try {
- if (resultCode == MediaSet.SYNC_RESULT_SUCCESS) {
- mInitialSynced = true;
- }
- clearLoadingBit(BIT_LOADING_SYNC);
- showSyncErrorIfNecessary(mLoadingFailed);
- } finally {
- root.unlockRenderThread();
- }
- }
- });
- }
-
- // Show sync error toast when all the following conditions are met:
- // (1) both loading and sync are done,
- // (2) sync result is error,
- // (3) the page is still active, and
- // (4) no photo is shown or loading fails.
- private void showSyncErrorIfNecessary(boolean loadingFailed) {
- if ((mLoadingBits == 0) && (mSyncResult == MediaSet.SYNC_RESULT_ERROR) && mIsActive
- && (loadingFailed || (mAlbumDataAdapter.size() == 0))) {
- Toast.makeText(mActivity, R.string.sync_album_error,
- Toast.LENGTH_LONG).show();
- }
- }
-
- private void setLoadingBit(int loadTaskBit) {
- mLoadingBits |= loadTaskBit;
- }
-
- private void clearLoadingBit(int loadTaskBit) {
- mLoadingBits &= ~loadTaskBit;
- if (mLoadingBits == 0 && mIsActive) {
- if (mAlbumDataAdapter.size() == 0) {
- Intent result = new Intent();
- result.putExtra(KEY_EMPTY_ALBUM, true);
- setStateResult(Activity.RESULT_OK, result);
- mActivity.getStateManager().finishState(this);
- }
- }
- }
-
- private class MyLoadingListener implements LoadingListener {
- @Override
- public void onLoadingStarted() {
- setLoadingBit(BIT_LOADING_RELOAD);
- mLoadingFailed = false;
- }
-
- @Override
- public void onLoadingFinished(boolean loadingFailed) {
- clearLoadingBit(BIT_LOADING_RELOAD);
- mLoadingFailed = loadingFailed;
- showSyncErrorIfNecessary(loadingFailed);
- }
- }
-
- private class MyDetailsSource implements DetailsHelper.DetailsSource {
- private int mIndex;
-
- @Override
- public int size() {
- return mAlbumDataAdapter.size();
- }
-
- @Override
- public int setIndex() {
- Path id = mSelectionManager.getSelected(false).get(0);
- mIndex = mAlbumDataAdapter.findItem(id);
- return mIndex;
- }
-
- @Override
- public MediaDetails getDetails() {
- // this relies on setIndex() being called beforehand
- MediaObject item = mAlbumDataAdapter.get(mIndex);
- if (item != null) {
- mAlbumView.setHighlightItemPath(item.getPath());
- return item.getDetails();
- } else {
- return null;
- }
- }
- }
-
- @Override
- public void onAlbumModeSelected(int mode) {
- if (mode == GalleryActionBar.ALBUM_FILMSTRIP_MODE_SELECTED) {
- switchToFilmstrip();
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/AlbumPicker.java b/src/com/android/gallery3d/app/AlbumPicker.java
deleted file mode 100644
index 65eb77291..000000000
--- a/src/com/android/gallery3d/app/AlbumPicker.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 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.app;
-
-import android.content.Intent;
-import android.os.Bundle;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.data.DataManager;
-
-public class AlbumPicker extends PickerActivity {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setTitle(R.string.select_album);
- Intent intent = getIntent();
- Bundle extras = intent.getExtras();
- Bundle data = extras == null ? new Bundle() : new Bundle(extras);
-
- data.putBoolean(Gallery.KEY_GET_ALBUM, true);
- data.putString(AlbumSetPage.KEY_MEDIA_PATH,
- getDataManager().getTopSetPath(DataManager.INCLUDE_IMAGE));
- getStateManager().startState(AlbumSetPage.class, data);
- }
-}
diff --git a/src/com/android/gallery3d/app/AlbumSetDataLoader.java b/src/com/android/gallery3d/app/AlbumSetDataLoader.java
deleted file mode 100644
index cf380f812..000000000
--- a/src/com/android/gallery3d/app/AlbumSetDataLoader.java
+++ /dev/null
@@ -1,393 +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.app;
-
-import android.os.Handler;
-import android.os.Message;
-import android.os.Process;
-
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.ContentListener;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.ui.SynchronizedHandler;
-
-import java.util.Arrays;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-
-public class AlbumSetDataLoader {
- @SuppressWarnings("unused")
- private static final String TAG = "AlbumSetDataAdapter";
-
- private static final int INDEX_NONE = -1;
-
- private static final int MIN_LOAD_COUNT = 4;
-
- private static final int MSG_LOAD_START = 1;
- private static final int MSG_LOAD_FINISH = 2;
- private static final int MSG_RUN_OBJECT = 3;
-
- public static interface DataListener {
- public void onContentChanged(int index);
- public void onSizeChanged(int size);
- }
-
- private final MediaSet[] mData;
- private final MediaItem[] mCoverItem;
- private final int[] mTotalCount;
- private final long[] mItemVersion;
- private final long[] mSetVersion;
-
- private int mActiveStart = 0;
- private int mActiveEnd = 0;
-
- private int mContentStart = 0;
- private int mContentEnd = 0;
-
- private final MediaSet mSource;
- private long mSourceVersion = MediaObject.INVALID_DATA_VERSION;
- private int mSize;
-
- private DataListener mDataListener;
- private LoadingListener mLoadingListener;
- private ReloadTask mReloadTask;
-
- private final Handler mMainHandler;
-
- private final MySourceListener mSourceListener = new MySourceListener();
-
- public AlbumSetDataLoader(AbstractGalleryActivity activity, MediaSet albumSet, int cacheSize) {
- mSource = Utils.checkNotNull(albumSet);
- mCoverItem = new MediaItem[cacheSize];
- mData = new MediaSet[cacheSize];
- mTotalCount = new int[cacheSize];
- mItemVersion = new long[cacheSize];
- mSetVersion = new long[cacheSize];
- Arrays.fill(mItemVersion, MediaObject.INVALID_DATA_VERSION);
- Arrays.fill(mSetVersion, MediaObject.INVALID_DATA_VERSION);
-
- mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_RUN_OBJECT:
- ((Runnable) message.obj).run();
- return;
- case MSG_LOAD_START:
- if (mLoadingListener != null) mLoadingListener.onLoadingStarted();
- return;
- case MSG_LOAD_FINISH:
- if (mLoadingListener != null) mLoadingListener.onLoadingFinished(false);
- return;
- }
- }
- };
- }
-
- public void pause() {
- mReloadTask.terminate();
- mReloadTask = null;
- mSource.removeContentListener(mSourceListener);
- }
-
- public void resume() {
- mSource.addContentListener(mSourceListener);
- mReloadTask = new ReloadTask();
- mReloadTask.start();
- }
-
- private void assertIsActive(int index) {
- if (index < mActiveStart && index >= mActiveEnd) {
- throw new IllegalArgumentException(String.format(
- "%s not in (%s, %s)", index, mActiveStart, mActiveEnd));
- }
- }
-
- public MediaSet getMediaSet(int index) {
- assertIsActive(index);
- return mData[index % mData.length];
- }
-
- public MediaItem getCoverItem(int index) {
- assertIsActive(index);
- return mCoverItem[index % mCoverItem.length];
- }
-
- public int getTotalCount(int index) {
- assertIsActive(index);
- return mTotalCount[index % mTotalCount.length];
- }
-
- public int getActiveStart() {
- return mActiveStart;
- }
-
- public boolean isActive(int index) {
- return index >= mActiveStart && index < mActiveEnd;
- }
-
- public int size() {
- return mSize;
- }
-
- // Returns the index of the MediaSet with the given path or
- // -1 if the path is not cached
- public int findSet(Path id) {
- int length = mData.length;
- for (int i = mContentStart; i < mContentEnd; i++) {
- MediaSet set = mData[i % length];
- if (set != null && id == set.getPath()) {
- return i;
- }
- }
- return -1;
- }
-
- private void clearSlot(int slotIndex) {
- mData[slotIndex] = null;
- mCoverItem[slotIndex] = null;
- mTotalCount[slotIndex] = 0;
- mItemVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
- mSetVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
- }
-
- private void setContentWindow(int contentStart, int contentEnd) {
- if (contentStart == mContentStart && contentEnd == mContentEnd) return;
- int length = mCoverItem.length;
-
- int start = this.mContentStart;
- int end = this.mContentEnd;
-
- mContentStart = contentStart;
- mContentEnd = contentEnd;
-
- if (contentStart >= end || start >= contentEnd) {
- for (int i = start, n = end; i < n; ++i) {
- clearSlot(i % length);
- }
- } else {
- for (int i = start; i < contentStart; ++i) {
- clearSlot(i % length);
- }
- for (int i = contentEnd, n = end; i < n; ++i) {
- clearSlot(i % length);
- }
- }
- mReloadTask.notifyDirty();
- }
-
- public void setActiveWindow(int start, int end) {
- if (start == mActiveStart && end == mActiveEnd) return;
-
- Utils.assertTrue(start <= end
- && end - start <= mCoverItem.length && end <= mSize);
-
- mActiveStart = start;
- mActiveEnd = end;
-
- int length = mCoverItem.length;
- // If no data is visible, keep the cache content
- if (start == end) return;
-
- int contentStart = Utils.clamp((start + end) / 2 - length / 2,
- 0, Math.max(0, mSize - length));
- int contentEnd = Math.min(contentStart + length, mSize);
- if (mContentStart > start || mContentEnd < end
- || Math.abs(contentStart - mContentStart) > MIN_LOAD_COUNT) {
- setContentWindow(contentStart, contentEnd);
- }
- }
-
- private class MySourceListener implements ContentListener {
- @Override
- public void onContentDirty() {
- mReloadTask.notifyDirty();
- }
- }
-
- public void setModelListener(DataListener listener) {
- mDataListener = listener;
- }
-
- public void setLoadingListener(LoadingListener listener) {
- mLoadingListener = listener;
- }
-
- private static class UpdateInfo {
- public long version;
- public int index;
-
- public int size;
- public MediaSet item;
- public MediaItem cover;
- public int totalCount;
- }
-
- private class GetUpdateInfo implements Callable<UpdateInfo> {
-
- private final long mVersion;
-
- public GetUpdateInfo(long version) {
- mVersion = version;
- }
-
- private int getInvalidIndex(long version) {
- long setVersion[] = mSetVersion;
- int length = setVersion.length;
- for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
- int index = i % length;
- if (setVersion[i % length] != version) return i;
- }
- return INDEX_NONE;
- }
-
- @Override
- public UpdateInfo call() throws Exception {
- int index = getInvalidIndex(mVersion);
- if (index == INDEX_NONE && mSourceVersion == mVersion) return null;
- UpdateInfo info = new UpdateInfo();
- info.version = mSourceVersion;
- info.index = index;
- info.size = mSize;
- return info;
- }
- }
-
- private class UpdateContent implements Callable<Void> {
- private final UpdateInfo mUpdateInfo;
-
- public UpdateContent(UpdateInfo info) {
- mUpdateInfo = info;
- }
-
- @Override
- public Void call() {
- // Avoid notifying listeners of status change after pause
- // Otherwise gallery will be in inconsistent state after resume.
- if (mReloadTask == null) return null;
- UpdateInfo info = mUpdateInfo;
- mSourceVersion = info.version;
- if (mSize != info.size) {
- mSize = info.size;
- if (mDataListener != null) mDataListener.onSizeChanged(mSize);
- if (mContentEnd > mSize) mContentEnd = mSize;
- if (mActiveEnd > mSize) mActiveEnd = mSize;
- }
- // Note: info.index could be INDEX_NONE, i.e., -1
- if (info.index >= mContentStart && info.index < mContentEnd) {
- int pos = info.index % mCoverItem.length;
- mSetVersion[pos] = info.version;
- long itemVersion = info.item.getDataVersion();
- if (mItemVersion[pos] == itemVersion) return null;
- mItemVersion[pos] = itemVersion;
- mData[pos] = info.item;
- mCoverItem[pos] = info.cover;
- mTotalCount[pos] = info.totalCount;
- if (mDataListener != null
- && info.index >= mActiveStart && info.index < mActiveEnd) {
- mDataListener.onContentChanged(info.index);
- }
- }
- return null;
- }
- }
-
- private <T> T executeAndWait(Callable<T> callable) {
- FutureTask<T> task = new FutureTask<T>(callable);
- mMainHandler.sendMessage(
- mMainHandler.obtainMessage(MSG_RUN_OBJECT, task));
- try {
- return task.get();
- } catch (InterruptedException e) {
- return null;
- } catch (ExecutionException e) {
- throw new RuntimeException(e);
- }
- }
-
- // TODO: load active range first
- private class ReloadTask extends Thread {
- private volatile boolean mActive = true;
- private volatile boolean mDirty = true;
- private volatile boolean mIsLoading = false;
-
- private void updateLoading(boolean loading) {
- if (mIsLoading == loading) return;
- mIsLoading = loading;
- mMainHandler.sendEmptyMessage(loading ? MSG_LOAD_START : MSG_LOAD_FINISH);
- }
-
- @Override
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
- boolean updateComplete = false;
- while (mActive) {
- synchronized (this) {
- if (mActive && !mDirty && updateComplete) {
- if (!mSource.isLoading()) updateLoading(false);
- Utils.waitWithoutInterrupt(this);
- continue;
- }
- }
- mDirty = false;
- updateLoading(true);
-
- long version = mSource.reload();
- UpdateInfo info = executeAndWait(new GetUpdateInfo(version));
- updateComplete = info == null;
- if (updateComplete) continue;
- if (info.version != version) {
- info.version = version;
- info.size = mSource.getSubMediaSetCount();
-
- // If the size becomes smaller after reload(), we may
- // receive from GetUpdateInfo an index which is too
- // big. Because the main thread is not aware of the size
- // change until we call UpdateContent.
- if (info.index >= info.size) {
- info.index = INDEX_NONE;
- }
- }
- if (info.index != INDEX_NONE) {
- info.item = mSource.getSubMediaSet(info.index);
- if (info.item == null) continue;
- info.cover = info.item.getCoverMediaItem();
- info.totalCount = info.item.getTotalMediaItemCount();
- }
- executeAndWait(new UpdateContent(info));
- }
- updateLoading(false);
- }
-
- public synchronized void notifyDirty() {
- mDirty = true;
- notifyAll();
- }
-
- public synchronized void terminate() {
- mActive = false;
- notifyAll();
- }
- }
-}
-
-
diff --git a/src/com/android/gallery3d/app/AlbumSetPage.java b/src/com/android/gallery3d/app/AlbumSetPage.java
deleted file mode 100644
index dd9d8ec41..000000000
--- a/src/com/android/gallery3d/app/AlbumSetPage.java
+++ /dev/null
@@ -1,764 +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.app;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.view.HapticFeedbackConstants;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.RelativeLayout;
-import android.widget.Toast;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.MediaDetails;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.glrenderer.FadeTexture;
-import com.android.gallery3d.glrenderer.GLCanvas;
-import com.android.gallery3d.picasasource.PicasaSource;
-import com.android.gallery3d.settings.GallerySettings;
-import com.android.gallery3d.ui.ActionModeHandler;
-import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
-import com.android.gallery3d.ui.AlbumSetSlotRenderer;
-import com.android.gallery3d.ui.DetailsHelper;
-import com.android.gallery3d.ui.DetailsHelper.CloseListener;
-import com.android.gallery3d.ui.GLRoot;
-import com.android.gallery3d.ui.GLView;
-import com.android.gallery3d.ui.SelectionManager;
-import com.android.gallery3d.ui.SlotView;
-import com.android.gallery3d.ui.SynchronizedHandler;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.GalleryUtils;
-import com.android.gallery3d.util.HelpUtils;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-public class AlbumSetPage extends ActivityState implements
- SelectionManager.SelectionListener, GalleryActionBar.ClusterRunner,
- EyePosition.EyePositionListener, MediaSet.SyncListener {
- @SuppressWarnings("unused")
- private static final String TAG = "AlbumSetPage";
-
- private static final int MSG_PICK_ALBUM = 1;
-
- public static final String KEY_MEDIA_PATH = "media-path";
- public static final String KEY_SET_TITLE = "set-title";
- public static final String KEY_SET_SUBTITLE = "set-subtitle";
- public static final String KEY_SELECTED_CLUSTER_TYPE = "selected-cluster";
-
- private static final int DATA_CACHE_SIZE = 256;
- private static final int REQUEST_DO_ANIMATION = 1;
-
- private static final int BIT_LOADING_RELOAD = 1;
- private static final int BIT_LOADING_SYNC = 2;
-
- private boolean mIsActive = false;
- private SlotView mSlotView;
- private AlbumSetSlotRenderer mAlbumSetView;
- private Config.AlbumSetPage mConfig;
-
- private MediaSet mMediaSet;
- private String mTitle;
- private String mSubtitle;
- private boolean mShowClusterMenu;
- private GalleryActionBar mActionBar;
- private int mSelectedAction;
-
- protected SelectionManager mSelectionManager;
- private AlbumSetDataLoader mAlbumSetDataAdapter;
-
- private boolean mGetContent;
- private boolean mGetAlbum;
- private ActionModeHandler mActionModeHandler;
- private DetailsHelper mDetailsHelper;
- private MyDetailsSource mDetailsSource;
- private boolean mShowDetails;
- private EyePosition mEyePosition;
- private Handler mHandler;
-
- // The eyes' position of the user, the origin is at the center of the
- // device and the unit is in pixels.
- private float mX;
- private float mY;
- private float mZ;
-
- private Future<Integer> mSyncTask = null;
-
- private int mLoadingBits = 0;
- private boolean mInitialSynced = false;
-
- private Button mCameraButton;
- private boolean mShowedEmptyToastForSelf = false;
-
- @Override
- protected int getBackgroundColorId() {
- return R.color.albumset_background;
- }
-
- private final GLView mRootPane = new GLView() {
- private final float mMatrix[] = new float[16];
-
- @Override
- protected void onLayout(
- boolean changed, int left, int top, int right, int bottom) {
- mEyePosition.resetPosition();
-
- int slotViewTop = mActionBar.getHeight() + mConfig.paddingTop;
- int slotViewBottom = bottom - top - mConfig.paddingBottom;
- int slotViewRight = right - left;
-
- if (mShowDetails) {
- mDetailsHelper.layout(left, slotViewTop, right, bottom);
- } else {
- mAlbumSetView.setHighlightItemPath(null);
- }
-
- mSlotView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
- }
-
- @Override
- protected void render(GLCanvas canvas) {
- canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
- GalleryUtils.setViewPointMatrix(mMatrix,
- getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
- canvas.multiplyMatrix(mMatrix, 0);
- super.render(canvas);
- canvas.restore();
- }
- };
-
- @Override
- public void onEyePositionChanged(float x, float y, float z) {
- mRootPane.lockRendering();
- mX = x;
- mY = y;
- mZ = z;
- mRootPane.unlockRendering();
- mRootPane.invalidate();
- }
-
- @Override
- public void onBackPressed() {
- if (mShowDetails) {
- hideDetails();
- } else if (mSelectionManager.inSelectionMode()) {
- mSelectionManager.leaveSelectionMode();
- } else {
- super.onBackPressed();
- }
- }
-
- private void getSlotCenter(int slotIndex, int center[]) {
- Rect offset = new Rect();
- mRootPane.getBoundsOf(mSlotView, offset);
- Rect r = mSlotView.getSlotRect(slotIndex);
- int scrollX = mSlotView.getScrollX();
- int scrollY = mSlotView.getScrollY();
- center[0] = offset.left + (r.left + r.right) / 2 - scrollX;
- center[1] = offset.top + (r.top + r.bottom) / 2 - scrollY;
- }
-
- public void onSingleTapUp(int slotIndex) {
- if (!mIsActive) return;
-
- if (mSelectionManager.inSelectionMode()) {
- MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
- if (targetSet == null) return; // Content is dirty, we shall reload soon
- mSelectionManager.toggle(targetSet.getPath());
- mSlotView.invalidate();
- } else {
- // Show pressed-up animation for the single-tap.
- mAlbumSetView.setPressedIndex(slotIndex);
- mAlbumSetView.setPressedUp();
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_PICK_ALBUM, slotIndex, 0),
- FadeTexture.DURATION);
- }
- }
-
- private static boolean albumShouldOpenInFilmstrip(MediaSet album) {
- int itemCount = album.getMediaItemCount();
- ArrayList<MediaItem> list = (itemCount == 1) ? album.getMediaItem(0, 1) : null;
- // open in film strip only if there's one item in the album and the item exists
- return (list != null && !list.isEmpty());
- }
-
- WeakReference<Toast> mEmptyAlbumToast = null;
-
- private void showEmptyAlbumToast(int toastLength) {
- Toast toast;
- if (mEmptyAlbumToast != null) {
- toast = mEmptyAlbumToast.get();
- if (toast != null) {
- toast.show();
- return;
- }
- }
- toast = Toast.makeText(mActivity, R.string.empty_album, toastLength);
- mEmptyAlbumToast = new WeakReference<Toast>(toast);
- toast.show();
- }
-
- private void hideEmptyAlbumToast() {
- if (mEmptyAlbumToast != null) {
- Toast toast = mEmptyAlbumToast.get();
- if (toast != null) toast.cancel();
- }
- }
-
- private void pickAlbum(int slotIndex) {
- if (!mIsActive) return;
-
- MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
- if (targetSet == null) return; // Content is dirty, we shall reload soon
- if (targetSet.getTotalMediaItemCount() == 0) {
- showEmptyAlbumToast(Toast.LENGTH_SHORT);
- return;
- }
- hideEmptyAlbumToast();
-
- String mediaPath = targetSet.getPath().toString();
-
- Bundle data = new Bundle(getData());
- int[] center = new int[2];
- getSlotCenter(slotIndex, center);
- data.putIntArray(AlbumPage.KEY_SET_CENTER, center);
- if (mGetAlbum && targetSet.isLeafAlbum()) {
- Activity activity = mActivity;
- Intent result = new Intent()
- .putExtra(AlbumPicker.KEY_ALBUM_PATH, targetSet.getPath().toString());
- activity.setResult(Activity.RESULT_OK, result);
- activity.finish();
- } else if (targetSet.getSubMediaSetCount() > 0) {
- data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
- mActivity.getStateManager().startStateForResult(
- AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
- } else {
- if (!mGetContent && albumShouldOpenInFilmstrip(targetSet)) {
- data.putParcelable(PhotoPage.KEY_OPEN_ANIMATION_RECT,
- mSlotView.getSlotRect(slotIndex, mRootPane));
- data.putInt(PhotoPage.KEY_INDEX_HINT, 0);
- data.putString(PhotoPage.KEY_MEDIA_SET_PATH,
- mediaPath);
- data.putBoolean(PhotoPage.KEY_START_IN_FILMSTRIP, true);
- data.putBoolean(PhotoPage.KEY_IN_CAMERA_ROLL, targetSet.isCameraRoll());
- mActivity.getStateManager().startStateForResult(
- FilmstripPage.class, AlbumPage.REQUEST_PHOTO, data);
- return;
- }
- data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);
-
- // We only show cluster menu in the first AlbumPage in stack
- boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
- data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum);
- mActivity.getStateManager().startStateForResult(
- AlbumPage.class, REQUEST_DO_ANIMATION, data);
- }
- }
-
- private void onDown(int index) {
- mAlbumSetView.setPressedIndex(index);
- }
-
- private void onUp(boolean followedByLongPress) {
- if (followedByLongPress) {
- // Avoid showing press-up animations for long-press.
- mAlbumSetView.setPressedIndex(-1);
- } else {
- mAlbumSetView.setPressedUp();
- }
- }
-
- public void onLongTap(int slotIndex) {
- if (mGetContent || mGetAlbum) return;
- MediaSet set = mAlbumSetDataAdapter.getMediaSet(slotIndex);
- if (set == null) return;
- mSelectionManager.setAutoLeaveSelectionMode(true);
- mSelectionManager.toggle(set.getPath());
- mSlotView.invalidate();
- }
-
- @Override
- public void doCluster(int clusterType) {
- String basePath = mMediaSet.getPath().toString();
- String newPath = FilterUtils.switchClusterPath(basePath, clusterType);
- Bundle data = new Bundle(getData());
- data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
- data.putInt(KEY_SELECTED_CLUSTER_TYPE, clusterType);
- mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
- }
-
- @Override
- public void onCreate(Bundle data, Bundle restoreState) {
- super.onCreate(data, restoreState);
- initializeViews();
- initializeData(data);
- Context context = mActivity.getAndroidContext();
- mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
- mGetAlbum = data.getBoolean(Gallery.KEY_GET_ALBUM, false);
- mTitle = data.getString(AlbumSetPage.KEY_SET_TITLE);
- mSubtitle = data.getString(AlbumSetPage.KEY_SET_SUBTITLE);
- mEyePosition = new EyePosition(context, this);
- mDetailsSource = new MyDetailsSource();
- mActionBar = mActivity.getGalleryActionBar();
- mSelectedAction = data.getInt(AlbumSetPage.KEY_SELECTED_CLUSTER_TYPE,
- FilterUtils.CLUSTER_BY_ALBUM);
-
- mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_PICK_ALBUM: {
- pickAlbum(message.arg1);
- break;
- }
- default: throw new AssertionError(message.what);
- }
- }
- };
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- cleanupCameraButton();
- mActionModeHandler.destroy();
- }
-
- private boolean setupCameraButton() {
- if (!GalleryUtils.isCameraAvailable(mActivity)) return false;
- RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity)
- .findViewById(R.id.gallery_root);
- if (galleryRoot == null) return false;
-
- mCameraButton = new Button(mActivity);
- mCameraButton.setText(R.string.camera_label);
- mCameraButton.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.frame_overlay_gallery_camera, 0, 0);
- mCameraButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- GalleryUtils.startCameraActivity(mActivity);
- }
- });
- RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
- RelativeLayout.LayoutParams.WRAP_CONTENT,
- RelativeLayout.LayoutParams.WRAP_CONTENT);
- lp.addRule(RelativeLayout.CENTER_IN_PARENT);
- galleryRoot.addView(mCameraButton, lp);
- return true;
- }
-
- private void cleanupCameraButton() {
- if (mCameraButton == null) return;
- RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity)
- .findViewById(R.id.gallery_root);
- if (galleryRoot == null) return;
- galleryRoot.removeView(mCameraButton);
- mCameraButton = null;
- }
-
- private void showCameraButton() {
- if (mCameraButton == null && !setupCameraButton()) return;
- mCameraButton.setVisibility(View.VISIBLE);
- }
-
- private void hideCameraButton() {
- if (mCameraButton == null) return;
- mCameraButton.setVisibility(View.GONE);
- }
-
- private void clearLoadingBit(int loadingBit) {
- mLoadingBits &= ~loadingBit;
- if (mLoadingBits == 0 && mIsActive) {
- if (mAlbumSetDataAdapter.size() == 0) {
- // If this is not the top of the gallery folder hierarchy,
- // tell the parent AlbumSetPage instance to handle displaying
- // the empty album toast, otherwise show it within this
- // instance
- if (mActivity.getStateManager().getStateCount() > 1) {
- Intent result = new Intent();
- result.putExtra(AlbumPage.KEY_EMPTY_ALBUM, true);
- setStateResult(Activity.RESULT_OK, result);
- mActivity.getStateManager().finishState(this);
- } else {
- mShowedEmptyToastForSelf = true;
- showEmptyAlbumToast(Toast.LENGTH_LONG);
- mSlotView.invalidate();
- showCameraButton();
- }
- return;
- }
- }
- // Hide the empty album toast if we are in the root instance of
- // AlbumSetPage and the album is no longer empty (for instance,
- // after a sync is completed and web albums have been synced)
- if (mShowedEmptyToastForSelf) {
- mShowedEmptyToastForSelf = false;
- hideEmptyAlbumToast();
- hideCameraButton();
- }
- }
-
- private void setLoadingBit(int loadingBit) {
- mLoadingBits |= loadingBit;
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mIsActive = false;
- mAlbumSetDataAdapter.pause();
- mAlbumSetView.pause();
- mActionModeHandler.pause();
- mEyePosition.pause();
- DetailsHelper.pause();
- // Call disableClusterMenu to avoid receiving callback after paused.
- // Don't hide menu here otherwise the list menu will disappear earlier than
- // the action bar, which is janky and unwanted behavior.
- mActionBar.disableClusterMenu(false);
- if (mSyncTask != null) {
- mSyncTask.cancel();
- mSyncTask = null;
- clearLoadingBit(BIT_LOADING_SYNC);
- }
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mIsActive = true;
- setContentPane(mRootPane);
-
- // Set the reload bit here to prevent it exit this page in clearLoadingBit().
- setLoadingBit(BIT_LOADING_RELOAD);
- mAlbumSetDataAdapter.resume();
-
- mAlbumSetView.resume();
- mEyePosition.resume();
- mActionModeHandler.resume();
- if (mShowClusterMenu) {
- mActionBar.enableClusterMenu(mSelectedAction, this);
- }
- if (!mInitialSynced) {
- setLoadingBit(BIT_LOADING_SYNC);
- mSyncTask = mMediaSet.requestSync(AlbumSetPage.this);
- }
- }
-
- private void initializeData(Bundle data) {
- String mediaPath = data.getString(AlbumSetPage.KEY_MEDIA_PATH);
- mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
- mSelectionManager.setSourceMediaSet(mMediaSet);
- mAlbumSetDataAdapter = new AlbumSetDataLoader(
- mActivity, mMediaSet, DATA_CACHE_SIZE);
- mAlbumSetDataAdapter.setLoadingListener(new MyLoadingListener());
- mAlbumSetView.setModel(mAlbumSetDataAdapter);
- }
-
- private void initializeViews() {
- mSelectionManager = new SelectionManager(mActivity, true);
- mSelectionManager.setSelectionListener(this);
-
- mConfig = Config.AlbumSetPage.get(mActivity);
- mSlotView = new SlotView(mActivity, mConfig.slotViewSpec);
- mAlbumSetView = new AlbumSetSlotRenderer(
- mActivity, mSelectionManager, mSlotView, mConfig.labelSpec,
- mConfig.placeholderColor);
- mSlotView.setSlotRenderer(mAlbumSetView);
- mSlotView.setListener(new SlotView.SimpleListener() {
- @Override
- public void onDown(int index) {
- AlbumSetPage.this.onDown(index);
- }
-
- @Override
- public void onUp(boolean followedByLongPress) {
- AlbumSetPage.this.onUp(followedByLongPress);
- }
-
- @Override
- public void onSingleTapUp(int slotIndex) {
- AlbumSetPage.this.onSingleTapUp(slotIndex);
- }
-
- @Override
- public void onLongTap(int slotIndex) {
- AlbumSetPage.this.onLongTap(slotIndex);
- }
- });
-
- mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
- mActionModeHandler.setActionModeListener(new ActionModeListener() {
- @Override
- public boolean onActionItemClicked(MenuItem item) {
- return onItemSelected(item);
- }
- });
- mRootPane.addComponent(mSlotView);
- }
-
- @Override
- protected boolean onCreateActionBar(Menu menu) {
- Activity activity = mActivity;
- final boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
- MenuInflater inflater = getSupportMenuInflater();
-
- if (mGetContent) {
- inflater.inflate(R.menu.pickup, menu);
- int typeBits = mData.getInt(
- Gallery.KEY_TYPE_BITS, DataManager.INCLUDE_IMAGE);
- mActionBar.setTitle(GalleryUtils.getSelectionModePrompt(typeBits));
- } else if (mGetAlbum) {
- inflater.inflate(R.menu.pickup, menu);
- mActionBar.setTitle(R.string.select_album);
- } else {
- inflater.inflate(R.menu.albumset, menu);
- boolean wasShowingClusterMenu = mShowClusterMenu;
- mShowClusterMenu = !inAlbum;
- boolean selectAlbums = !inAlbum &&
- mActionBar.getClusterTypeAction() == FilterUtils.CLUSTER_BY_ALBUM;
- MenuItem selectItem = menu.findItem(R.id.action_select);
- selectItem.setTitle(activity.getString(
- selectAlbums ? R.string.select_album : R.string.select_group));
-
- MenuItem cameraItem = menu.findItem(R.id.action_camera);
- cameraItem.setVisible(GalleryUtils.isCameraAvailable(activity));
-
- FilterUtils.setupMenuItems(mActionBar, mMediaSet.getPath(), false);
-
- Intent helpIntent = HelpUtils.getHelpIntent(activity);
-
- MenuItem helpItem = menu.findItem(R.id.action_general_help);
- helpItem.setVisible(helpIntent != null);
- if (helpIntent != null) helpItem.setIntent(helpIntent);
-
- mActionBar.setTitle(mTitle);
- mActionBar.setSubtitle(mSubtitle);
- if (mShowClusterMenu != wasShowingClusterMenu) {
- if (mShowClusterMenu) {
- mActionBar.enableClusterMenu(mSelectedAction, this);
- } else {
- mActionBar.disableClusterMenu(true);
- }
- }
- }
- return true;
- }
-
- @Override
- protected boolean onItemSelected(MenuItem item) {
- Activity activity = mActivity;
- switch (item.getItemId()) {
- case R.id.action_cancel:
- activity.setResult(Activity.RESULT_CANCELED);
- activity.finish();
- return true;
- case R.id.action_select:
- mSelectionManager.setAutoLeaveSelectionMode(false);
- mSelectionManager.enterSelectionMode();
- return true;
- case R.id.action_details:
- if (mAlbumSetDataAdapter.size() != 0) {
- if (mShowDetails) {
- hideDetails();
- } else {
- showDetails();
- }
- } else {
- Toast.makeText(activity,
- activity.getText(R.string.no_albums_alert),
- Toast.LENGTH_SHORT).show();
- }
- return true;
- case R.id.action_camera: {
- GalleryUtils.startCameraActivity(activity);
- return true;
- }
- case R.id.action_manage_offline: {
- Bundle data = new Bundle();
- String mediaPath = mActivity.getDataManager().getTopSetPath(
- DataManager.INCLUDE_ALL);
- data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
- mActivity.getStateManager().startState(ManageCachePage.class, data);
- return true;
- }
- case R.id.action_sync_picasa_albums: {
- PicasaSource.requestSync(activity);
- return true;
- }
- case R.id.action_settings: {
- activity.startActivity(new Intent(activity, GallerySettings.class));
- return true;
- }
- default:
- return false;
- }
- }
-
- @Override
- protected void onStateResult(int requestCode, int resultCode, Intent data) {
- if (data != null && data.getBooleanExtra(AlbumPage.KEY_EMPTY_ALBUM, false)) {
- showEmptyAlbumToast(Toast.LENGTH_SHORT);
- }
- switch (requestCode) {
- case REQUEST_DO_ANIMATION: {
- mSlotView.startRisingAnimation();
- }
- }
- }
-
- private String getSelectedString() {
- int count = mSelectionManager.getSelectedCount();
- int action = mActionBar.getClusterTypeAction();
- int string = action == FilterUtils.CLUSTER_BY_ALBUM
- ? R.plurals.number_of_albums_selected
- : R.plurals.number_of_groups_selected;
- String format = mActivity.getResources().getQuantityString(string, count);
- return String.format(format, count);
- }
-
- @Override
- public void onSelectionModeChange(int mode) {
- switch (mode) {
- case SelectionManager.ENTER_SELECTION_MODE: {
- mActionBar.disableClusterMenu(true);
- mActionModeHandler.startActionMode();
- performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- break;
- }
- case SelectionManager.LEAVE_SELECTION_MODE: {
- mActionModeHandler.finishActionMode();
- if (mShowClusterMenu) {
- mActionBar.enableClusterMenu(mSelectedAction, this);
- }
- mRootPane.invalidate();
- break;
- }
- case SelectionManager.SELECT_ALL_MODE: {
- mActionModeHandler.updateSupportedOperation();
- mRootPane.invalidate();
- break;
- }
- }
- }
-
- @Override
- public void onSelectionChange(Path path, boolean selected) {
- mActionModeHandler.setTitle(getSelectedString());
- mActionModeHandler.updateSupportedOperation(path, selected);
- }
-
- private void hideDetails() {
- mShowDetails = false;
- mDetailsHelper.hide();
- mAlbumSetView.setHighlightItemPath(null);
- mSlotView.invalidate();
- }
-
- private void showDetails() {
- mShowDetails = true;
- if (mDetailsHelper == null) {
- mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource);
- mDetailsHelper.setCloseListener(new CloseListener() {
- @Override
- public void onClose() {
- hideDetails();
- }
- });
- }
- mDetailsHelper.show();
- }
-
- @Override
- public void onSyncDone(final MediaSet mediaSet, final int resultCode) {
- if (resultCode == MediaSet.SYNC_RESULT_ERROR) {
- Log.d(TAG, "onSyncDone: " + Utils.maskDebugInfo(mediaSet.getName()) + " result="
- + resultCode);
- }
- ((Activity) mActivity).runOnUiThread(new Runnable() {
- @Override
- public void run() {
- GLRoot root = mActivity.getGLRoot();
- root.lockRenderThread();
- try {
- if (resultCode == MediaSet.SYNC_RESULT_SUCCESS) {
- mInitialSynced = true;
- }
- clearLoadingBit(BIT_LOADING_SYNC);
- if (resultCode == MediaSet.SYNC_RESULT_ERROR && mIsActive) {
- Log.w(TAG, "failed to load album set");
- }
- } finally {
- root.unlockRenderThread();
- }
- }
- });
- }
-
- private class MyLoadingListener implements LoadingListener {
- @Override
- public void onLoadingStarted() {
- setLoadingBit(BIT_LOADING_RELOAD);
- }
-
- @Override
- public void onLoadingFinished(boolean loadingFailed) {
- clearLoadingBit(BIT_LOADING_RELOAD);
- }
- }
-
- private class MyDetailsSource implements DetailsHelper.DetailsSource {
- private int mIndex;
-
- @Override
- public int size() {
- return mAlbumSetDataAdapter.size();
- }
-
- @Override
- public int setIndex() {
- Path id = mSelectionManager.getSelected(false).get(0);
- mIndex = mAlbumSetDataAdapter.findSet(id);
- return mIndex;
- }
-
- @Override
- public MediaDetails getDetails() {
- MediaObject item = mAlbumSetDataAdapter.getMediaSet(mIndex);
- if (item != null) {
- mAlbumSetView.setHighlightItemPath(item.getPath());
- return item.getDetails();
- } else {
- return null;
- }
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/AppBridge.java b/src/com/android/gallery3d/app/AppBridge.java
deleted file mode 100644
index ee55fa6db..000000000
--- a/src/com/android/gallery3d/app/AppBridge.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.graphics.Rect;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.gallery3d.ui.ScreenNail;
-
-// This is the bridge to connect a PhotoPage to the external environment.
-public abstract class AppBridge implements Parcelable {
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- }
-
- //////////////////////////////////////////////////////////////////////////
- // These are requests sent from PhotoPage to the app
- //////////////////////////////////////////////////////////////////////////
-
- public abstract boolean isPanorama();
- public abstract boolean isStaticCamera();
- public abstract ScreenNail attachScreenNail();
- public abstract void detachScreenNail();
-
- // Return true if the tap is consumed.
- public abstract boolean onSingleTapUp(int x, int y);
-
- // This is used to notify that the screen nail will be drawn in full screen
- // or not in next draw() call.
- public abstract void onFullScreenChanged(boolean full);
-
- //////////////////////////////////////////////////////////////////////////
- // These are requests send from app to PhotoPage
- //////////////////////////////////////////////////////////////////////////
-
- public interface Server {
- // Set the camera frame relative to GLRootView.
- public void setCameraRelativeFrame(Rect frame);
- // Switch to the previous or next picture using the capture animation.
- // The offset is -1 to switch to the previous picture, 1 to switch to
- // the next picture.
- public boolean switchWithCaptureAnimation(int offset);
- // Enable or disable the swiping gestures (the default is enabled).
- public void setSwipingEnabled(boolean enabled);
- // Notify that the ScreenNail is changed.
- public void notifyScreenNailChanged();
- // Add a new media item to the secure album.
- public void addSecureAlbumItem(boolean isVideo, int id);
- }
-
- // If server is null, the services are not available.
- public abstract void setServer(Server server);
-}
diff --git a/src/com/android/gallery3d/app/BatchService.java b/src/com/android/gallery3d/app/BatchService.java
deleted file mode 100644
index 564001d5b..000000000
--- a/src/com/android/gallery3d/app/BatchService.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.IBinder;
-
-import com.android.gallery3d.util.ThreadPool;
-
-public class BatchService extends Service {
-
- public class LocalBinder extends Binder {
- BatchService getService() {
- return BatchService.this;
- }
- }
-
- private final IBinder mBinder = new LocalBinder();
- private ThreadPool mThreadPool = new ThreadPool(1, 1);
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- // The threadpool returned by getThreadPool must have only 1 thread
- // running at a time, as MenuExecutor (atrociously) depends on this
- // guarantee for synchronization.
- public ThreadPool getThreadPool() {
- return mThreadPool;
- }
-}
diff --git a/src/com/android/gallery3d/app/CommonControllerOverlay.java b/src/com/android/gallery3d/app/CommonControllerOverlay.java
deleted file mode 100644
index 9adb4e7a8..000000000
--- a/src/com/android/gallery3d/app/CommonControllerOverlay.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.android.gallery3d.R;
-
-/**
- * The common playback controller for the Movie Player or Video Trimming.
- */
-public abstract class CommonControllerOverlay extends FrameLayout implements
- ControllerOverlay,
- OnClickListener,
- TimeBar.Listener {
-
- protected enum State {
- PLAYING,
- PAUSED,
- ENDED,
- ERROR,
- LOADING
- }
-
- private static final float ERROR_MESSAGE_RELATIVE_PADDING = 1.0f / 6;
-
- protected Listener mListener;
-
- protected final View mBackground;
- protected TimeBar mTimeBar;
-
- protected View mMainView;
- protected final LinearLayout mLoadingView;
- protected final TextView mErrorView;
- protected final ImageView mPlayPauseReplayView;
-
- protected State mState;
-
- protected boolean mCanReplay = true;
-
- public void setSeekable(boolean canSeek) {
- mTimeBar.setSeekable(canSeek);
- }
-
- public CommonControllerOverlay(Context context) {
- super(context);
-
- mState = State.LOADING;
- // TODO: Move the following layout code into xml file.
- LayoutParams wrapContent =
- new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
- LayoutParams matchParent =
- new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
-
- mBackground = new View(context);
- mBackground.setBackgroundColor(context.getResources().getColor(R.color.darker_transparent));
- addView(mBackground, matchParent);
-
- // Depending on the usage, the timeBar can show a single scrubber, or
- // multiple ones for trimming.
- createTimeBar(context);
- addView(mTimeBar, wrapContent);
- mTimeBar.setContentDescription(
- context.getResources().getString(R.string.accessibility_time_bar));
- mLoadingView = new LinearLayout(context);
- mLoadingView.setOrientation(LinearLayout.VERTICAL);
- mLoadingView.setGravity(Gravity.CENTER_HORIZONTAL);
- ProgressBar spinner = new ProgressBar(context);
- spinner.setIndeterminate(true);
- mLoadingView.addView(spinner, wrapContent);
- TextView loadingText = createOverlayTextView(context);
- loadingText.setText(R.string.loading_video);
- mLoadingView.addView(loadingText, wrapContent);
- addView(mLoadingView, wrapContent);
-
- mPlayPauseReplayView = new ImageView(context);
- mPlayPauseReplayView.setImageResource(R.drawable.ic_vidcontrol_play);
- mPlayPauseReplayView.setContentDescription(
- context.getResources().getString(R.string.accessibility_play_video));
- mPlayPauseReplayView.setBackgroundResource(R.drawable.bg_vidcontrol);
- mPlayPauseReplayView.setScaleType(ScaleType.CENTER);
- mPlayPauseReplayView.setFocusable(true);
- mPlayPauseReplayView.setClickable(true);
- mPlayPauseReplayView.setOnClickListener(this);
- addView(mPlayPauseReplayView, wrapContent);
-
- mErrorView = createOverlayTextView(context);
- addView(mErrorView, matchParent);
-
- RelativeLayout.LayoutParams params =
- new RelativeLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
- setLayoutParams(params);
- hide();
- }
-
- abstract protected void createTimeBar(Context context);
-
- private TextView createOverlayTextView(Context context) {
- TextView view = new TextView(context);
- view.setGravity(Gravity.CENTER);
- view.setTextColor(0xFFFFFFFF);
- view.setPadding(0, 15, 0, 15);
- return view;
- }
-
- @Override
- public void setListener(Listener listener) {
- this.mListener = listener;
- }
-
- @Override
- public void setCanReplay(boolean canReplay) {
- this.mCanReplay = canReplay;
- }
-
- @Override
- public View getView() {
- return this;
- }
-
- @Override
- public void showPlaying() {
- mState = State.PLAYING;
- showMainView(mPlayPauseReplayView);
- }
-
- @Override
- public void showPaused() {
- mState = State.PAUSED;
- showMainView(mPlayPauseReplayView);
- }
-
- @Override
- public void showEnded() {
- mState = State.ENDED;
- if (mCanReplay) showMainView(mPlayPauseReplayView);
- }
-
- @Override
- public void showLoading() {
- mState = State.LOADING;
- showMainView(mLoadingView);
- }
-
- @Override
- public void showErrorMessage(String message) {
- mState = State.ERROR;
- int padding = (int) (getMeasuredWidth() * ERROR_MESSAGE_RELATIVE_PADDING);
- mErrorView.setPadding(
- padding, mErrorView.getPaddingTop(), padding, mErrorView.getPaddingBottom());
- mErrorView.setText(message);
- showMainView(mErrorView);
- }
-
- @Override
- public void setTimes(int currentTime, int totalTime,
- int trimStartTime, int trimEndTime) {
- mTimeBar.setTime(currentTime, totalTime, trimStartTime, trimEndTime);
- }
-
- public void hide() {
- mPlayPauseReplayView.setVisibility(View.INVISIBLE);
- mLoadingView.setVisibility(View.INVISIBLE);
- mBackground.setVisibility(View.INVISIBLE);
- mTimeBar.setVisibility(View.INVISIBLE);
- setVisibility(View.INVISIBLE);
- setFocusable(true);
- requestFocus();
- }
-
- private void showMainView(View view) {
- mMainView = view;
- mErrorView.setVisibility(mMainView == mErrorView ? View.VISIBLE : View.INVISIBLE);
- mLoadingView.setVisibility(mMainView == mLoadingView ? View.VISIBLE : View.INVISIBLE);
- mPlayPauseReplayView.setVisibility(
- mMainView == mPlayPauseReplayView ? View.VISIBLE : View.INVISIBLE);
- show();
- }
-
- @Override
- public void show() {
- updateViews();
- setVisibility(View.VISIBLE);
- setFocusable(false);
- }
-
- @Override
- public void onClick(View view) {
- if (mListener != null) {
- if (view == mPlayPauseReplayView) {
- if (mState == State.ENDED) {
- if (mCanReplay) {
- mListener.onReplay();
- }
- } else if (mState == State.PAUSED || mState == State.PLAYING) {
- mListener.onPlayPause();
- }
- }
- }
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (super.onTouchEvent(event)) {
- return true;
- }
- return false;
- }
-
- // The paddings of 4 sides which covered by system components. E.g.
- // +-----------------+\
- // | Action Bar | insets.top
- // +-----------------+/
- // | |
- // | Content Area | insets.right = insets.left = 0
- // | |
- // +-----------------+\
- // | Navigation Bar | insets.bottom
- // +-----------------+/
- // Please see View.fitSystemWindows() for more details.
- private final Rect mWindowInsets = new Rect();
-
- @Override
- protected boolean fitSystemWindows(Rect insets) {
- // We don't set the paddings of this View, otherwise,
- // the content will get cropped outside window
- mWindowInsets.set(insets);
- return true;
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- Rect insets = mWindowInsets;
- int pl = insets.left; // the left paddings
- int pr = insets.right;
- int pt = insets.top;
- int pb = insets.bottom;
-
- int h = bottom - top;
- int w = right - left;
- boolean error = mErrorView.getVisibility() == View.VISIBLE;
-
- int y = h - pb;
- // Put both TimeBar and Background just above the bottom system
- // component.
- // But extend the background to the width of the screen, since we don't
- // care if it will be covered by a system component and it looks better.
- mBackground.layout(0, y - mTimeBar.getBarHeight(), w, y);
- mTimeBar.layout(pl, y - mTimeBar.getPreferredHeight(), w - pr, y);
-
- // Put the play/pause/next/ previous button in the center of the screen
- layoutCenteredView(mPlayPauseReplayView, 0, 0, w, h);
-
- if (mMainView != null) {
- layoutCenteredView(mMainView, 0, 0, w, h);
- }
- }
-
- private void layoutCenteredView(View view, int l, int t, int r, int b) {
- int cw = view.getMeasuredWidth();
- int ch = view.getMeasuredHeight();
- int cl = (r - l - cw) / 2;
- int ct = (b - t - ch) / 2;
- view.layout(cl, ct, cl + cw, ct + ch);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- measureChildren(widthMeasureSpec, heightMeasureSpec);
- }
-
- protected void updateViews() {
- mBackground.setVisibility(View.VISIBLE);
- mTimeBar.setVisibility(View.VISIBLE);
- Resources resources = getContext().getResources();
- int imageResource = R.drawable.ic_vidcontrol_reload;
- String contentDescription = resources.getString(R.string.accessibility_reload_video);
- if (mState == State.PAUSED) {
- imageResource = R.drawable.ic_vidcontrol_play;
- contentDescription = resources.getString(R.string.accessibility_play_video);
- } else if (mState == State.PLAYING) {
- imageResource = R.drawable.ic_vidcontrol_pause;
- contentDescription = resources.getString(R.string.accessibility_pause_video);
- }
-
- mPlayPauseReplayView.setImageResource(imageResource);
- mPlayPauseReplayView.setContentDescription(contentDescription);
- mPlayPauseReplayView.setVisibility(
- (mState != State.LOADING && mState != State.ERROR &&
- !(mState == State.ENDED && !mCanReplay))
- ? View.VISIBLE : View.GONE);
- requestLayout();
- }
-
- // TimeBar listener
-
- @Override
- public void onScrubbingStart() {
- mListener.onSeekStart();
- }
-
- @Override
- public void onScrubbingMove(int time) {
- mListener.onSeekMove(time);
- }
-
- @Override
- public void onScrubbingEnd(int time, int trimStartTime, int trimEndTime) {
- mListener.onSeekEnd(time, trimStartTime, trimEndTime);
- }
-}
diff --git a/src/com/android/gallery3d/app/Config.java b/src/com/android/gallery3d/app/Config.java
deleted file mode 100644
index 7183acc33..000000000
--- a/src/com/android/gallery3d/app/Config.java
+++ /dev/null
@@ -1,127 +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.app;
-
-import android.content.Context;
-import android.content.res.Resources;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.ui.AlbumSetSlotRenderer;
-import com.android.gallery3d.ui.SlotView;
-
-final class Config {
- public static class AlbumSetPage {
- private static AlbumSetPage sInstance;
-
- public SlotView.Spec slotViewSpec;
- public AlbumSetSlotRenderer.LabelSpec labelSpec;
- public int paddingTop;
- public int paddingBottom;
- public int placeholderColor;
-
- public static synchronized AlbumSetPage get(Context context) {
- if (sInstance == null) {
- sInstance = new AlbumSetPage(context);
- }
- return sInstance;
- }
-
- private AlbumSetPage(Context context) {
- Resources r = context.getResources();
-
- placeholderColor = r.getColor(R.color.albumset_placeholder);
-
- slotViewSpec = new SlotView.Spec();
- slotViewSpec.rowsLand = r.getInteger(R.integer.albumset_rows_land);
- slotViewSpec.rowsPort = r.getInteger(R.integer.albumset_rows_port);
- slotViewSpec.slotGap = r.getDimensionPixelSize(R.dimen.albumset_slot_gap);
- slotViewSpec.slotHeightAdditional = 0;
-
- paddingTop = r.getDimensionPixelSize(R.dimen.albumset_padding_top);
- paddingBottom = r.getDimensionPixelSize(R.dimen.albumset_padding_bottom);
-
- labelSpec = new AlbumSetSlotRenderer.LabelSpec();
- labelSpec.labelBackgroundHeight = r.getDimensionPixelSize(
- R.dimen.albumset_label_background_height);
- labelSpec.titleOffset = r.getDimensionPixelSize(
- R.dimen.albumset_title_offset);
- labelSpec.countOffset = r.getDimensionPixelSize(
- R.dimen.albumset_count_offset);
- labelSpec.titleFontSize = r.getDimensionPixelSize(
- R.dimen.albumset_title_font_size);
- labelSpec.countFontSize = r.getDimensionPixelSize(
- R.dimen.albumset_count_font_size);
- labelSpec.leftMargin = r.getDimensionPixelSize(
- R.dimen.albumset_left_margin);
- labelSpec.titleRightMargin = r.getDimensionPixelSize(
- R.dimen.albumset_title_right_margin);
- labelSpec.iconSize = r.getDimensionPixelSize(
- R.dimen.albumset_icon_size);
- labelSpec.backgroundColor = r.getColor(
- R.color.albumset_label_background);
- labelSpec.titleColor = r.getColor(R.color.albumset_label_title);
- labelSpec.countColor = r.getColor(R.color.albumset_label_count);
- }
- }
-
- public static class AlbumPage {
- private static AlbumPage sInstance;
-
- public SlotView.Spec slotViewSpec;
- public int placeholderColor;
-
- public static synchronized AlbumPage get(Context context) {
- if (sInstance == null) {
- sInstance = new AlbumPage(context);
- }
- return sInstance;
- }
-
- private AlbumPage(Context context) {
- Resources r = context.getResources();
-
- placeholderColor = r.getColor(R.color.album_placeholder);
-
- slotViewSpec = new SlotView.Spec();
- slotViewSpec.rowsLand = r.getInteger(R.integer.album_rows_land);
- slotViewSpec.rowsPort = r.getInteger(R.integer.album_rows_port);
- slotViewSpec.slotGap = r.getDimensionPixelSize(R.dimen.album_slot_gap);
- }
- }
-
- public static class ManageCachePage extends AlbumSetPage {
- private static ManageCachePage sInstance;
-
- public final int cachePinSize;
- public final int cachePinMargin;
-
- public static synchronized ManageCachePage get(Context context) {
- if (sInstance == null) {
- sInstance = new ManageCachePage(context);
- }
- return sInstance;
- }
-
- public ManageCachePage(Context context) {
- super(context);
- Resources r = context.getResources();
- cachePinSize = r.getDimensionPixelSize(R.dimen.cache_pin_size);
- cachePinMargin = r.getDimensionPixelSize(R.dimen.cache_pin_margin);
- }
- }
-}
-
diff --git a/src/com/android/gallery3d/app/ControllerOverlay.java b/src/com/android/gallery3d/app/ControllerOverlay.java
deleted file mode 100644
index 078f59e28..000000000
--- a/src/com/android/gallery3d/app/ControllerOverlay.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2011 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.app;
-
-import android.view.View;
-
-public interface ControllerOverlay {
-
- interface Listener {
- void onPlayPause();
- void onSeekStart();
- void onSeekMove(int time);
- void onSeekEnd(int time, int trimStartTime, int trimEndTime);
- void onShown();
- void onHidden();
- void onReplay();
- }
-
- void setListener(Listener listener);
-
- void setCanReplay(boolean canReplay);
-
- /**
- * @return The overlay view that should be added to the player.
- */
- View getView();
-
- void show();
-
- void showPlaying();
-
- void showPaused();
-
- void showEnded();
-
- void showLoading();
-
- void showErrorMessage(String message);
-
- void setTimes(int currentTime, int totalTime,
- int trimStartTime, int trimEndTime);
-}
diff --git a/src/com/android/gallery3d/app/DialogPicker.java b/src/com/android/gallery3d/app/DialogPicker.java
deleted file mode 100644
index 7ca86e5b4..000000000
--- a/src/com/android/gallery3d/app/DialogPicker.java
+++ /dev/null
@@ -1,41 +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.app;
-
-import android.content.Intent;
-import android.os.Bundle;
-
-import com.android.gallery3d.util.GalleryUtils;
-
-public class DialogPicker extends PickerActivity {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- int typeBits = GalleryUtils.determineTypeBits(this, getIntent());
- setTitle(GalleryUtils.getSelectionModePrompt(typeBits));
- Intent intent = getIntent();
- Bundle extras = intent.getExtras();
- Bundle data = extras == null ? new Bundle() : new Bundle(extras);
-
- data.putBoolean(Gallery.KEY_GET_CONTENT, true);
- data.putString(AlbumSetPage.KEY_MEDIA_PATH,
- getDataManager().getTopSetPath(typeBits));
- getStateManager().startState(AlbumSetPage.class, data);
- }
-}
diff --git a/src/com/android/gallery3d/app/EyePosition.java b/src/com/android/gallery3d/app/EyePosition.java
deleted file mode 100644
index d99d97b0e..000000000
--- a/src/com/android/gallery3d/app/EyePosition.java
+++ /dev/null
@@ -1,226 +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.app;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.os.SystemClock;
-import android.util.FloatMath;
-import android.view.Display;
-import android.view.Surface;
-import android.view.WindowManager;
-
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.util.GalleryUtils;
-
-public class EyePosition {
- @SuppressWarnings("unused")
- private static final String TAG = "EyePosition";
-
- public interface EyePositionListener {
- public void onEyePositionChanged(float x, float y, float z);
- }
-
- private static final float GYROSCOPE_THRESHOLD = 0.15f;
- private static final float GYROSCOPE_LIMIT = 10f;
- private static final int GYROSCOPE_SETTLE_DOWN = 15;
- private static final float GYROSCOPE_RESTORE_FACTOR = 0.995f;
-
- private static final float USER_ANGEL = (float) Math.toRadians(10);
- private static final float USER_ANGEL_COS = FloatMath.cos(USER_ANGEL);
- private static final float USER_ANGEL_SIN = FloatMath.sin(USER_ANGEL);
- private static final float MAX_VIEW_RANGE = (float) 0.5;
- private static final int NOT_STARTED = -1;
-
- private static final float USER_DISTANCE_METER = 0.3f;
-
- private Context mContext;
- private EyePositionListener mListener;
- private Display mDisplay;
- // The eyes' position of the user, the origin is at the center of the
- // device and the unit is in pixels.
- private float mX;
- private float mY;
- private float mZ;
-
- private final float mUserDistance; // in pixel
- private final float mLimit;
- private long mStartTime = NOT_STARTED;
- private Sensor mSensor;
- private PositionListener mPositionListener = new PositionListener();
-
- private int mGyroscopeCountdown = 0;
-
- public EyePosition(Context context, EyePositionListener listener) {
- mContext = context;
- mListener = listener;
- mUserDistance = GalleryUtils.meterToPixel(USER_DISTANCE_METER);
- mLimit = mUserDistance * MAX_VIEW_RANGE;
-
- WindowManager wManager = (WindowManager) mContext
- .getSystemService(Context.WINDOW_SERVICE);
- mDisplay = wManager.getDefaultDisplay();
-
- // The 3D effect where the photo albums fan out in 3D based on angle
- // of device tilt is currently disabled.
-/*
- SensorManager sManager = (SensorManager) mContext
- .getSystemService(Context.SENSOR_SERVICE);
- mSensor = sManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
- if (mSensor == null) {
- Log.w(TAG, "no gyroscope, use accelerometer instead");
- mSensor = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
- }
- if (mSensor == null) {
- Log.w(TAG, "no sensor available");
- }
-*/
- }
-
- public void resetPosition() {
- mStartTime = NOT_STARTED;
- mX = mY = 0;
- mZ = -mUserDistance;
- mListener.onEyePositionChanged(mX, mY, mZ);
- }
-
- /*
- * We assume the user is at the following position
- *
- * /|\ user's eye
- * | /
- * -G(gravity) | /
- * |_/
- * / |/_____\ -Y (-y direction of device)
- * user angel
- */
- private void onAccelerometerChanged(float gx, float gy, float gz) {
-
- float x = gx, y = gy, z = gz;
-
- switch (mDisplay.getRotation()) {
- case Surface.ROTATION_90: x = -gy; y= gx; break;
- case Surface.ROTATION_180: x = -gx; y = -gy; break;
- case Surface.ROTATION_270: x = gy; y = -gx; break;
- }
-
- float temp = x * x + y * y + z * z;
- float t = -y /temp;
-
- float tx = t * x;
- float ty = -1 + t * y;
- float tz = t * z;
-
- float length = FloatMath.sqrt(tx * tx + ty * ty + tz * tz);
- float glength = FloatMath.sqrt(temp);
-
- mX = Utils.clamp((x * USER_ANGEL_COS / glength
- + tx * USER_ANGEL_SIN / length) * mUserDistance,
- -mLimit, mLimit);
- mY = -Utils.clamp((y * USER_ANGEL_COS / glength
- + ty * USER_ANGEL_SIN / length) * mUserDistance,
- -mLimit, mLimit);
- mZ = -FloatMath.sqrt(
- mUserDistance * mUserDistance - mX * mX - mY * mY);
- mListener.onEyePositionChanged(mX, mY, mZ);
- }
-
- private void onGyroscopeChanged(float gx, float gy, float gz) {
- long now = SystemClock.elapsedRealtime();
- float distance = (gx > 0 ? gx : -gx) + (gy > 0 ? gy : - gy);
- if (distance < GYROSCOPE_THRESHOLD
- || distance > GYROSCOPE_LIMIT || mGyroscopeCountdown > 0) {
- --mGyroscopeCountdown;
- mStartTime = now;
- float limit = mUserDistance / 20f;
- if (mX > limit || mX < -limit || mY > limit || mY < -limit) {
- mX *= GYROSCOPE_RESTORE_FACTOR;
- mY *= GYROSCOPE_RESTORE_FACTOR;
- mZ = (float) -Math.sqrt(
- mUserDistance * mUserDistance - mX * mX - mY * mY);
- mListener.onEyePositionChanged(mX, mY, mZ);
- }
- return;
- }
-
- float t = (now - mStartTime) / 1000f * mUserDistance * (-mZ);
- mStartTime = now;
-
- float x = -gy, y = -gx;
- switch (mDisplay.getRotation()) {
- case Surface.ROTATION_90: x = -gx; y= gy; break;
- case Surface.ROTATION_180: x = gy; y = gx; break;
- case Surface.ROTATION_270: x = gx; y = -gy; break;
- }
-
- mX = Utils.clamp((float) (mX + x * t / Math.hypot(mZ, mX)),
- -mLimit, mLimit) * GYROSCOPE_RESTORE_FACTOR;
- mY = Utils.clamp((float) (mY + y * t / Math.hypot(mZ, mY)),
- -mLimit, mLimit) * GYROSCOPE_RESTORE_FACTOR;
-
- mZ = -FloatMath.sqrt(
- mUserDistance * mUserDistance - mX * mX - mY * mY);
- mListener.onEyePositionChanged(mX, mY, mZ);
- }
-
- private class PositionListener implements SensorEventListener {
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
-
- @Override
- public void onSensorChanged(SensorEvent event) {
- switch (event.sensor.getType()) {
- case Sensor.TYPE_GYROSCOPE: {
- onGyroscopeChanged(
- event.values[0], event.values[1], event.values[2]);
- break;
- }
- case Sensor.TYPE_ACCELEROMETER: {
- onAccelerometerChanged(
- event.values[0], event.values[1], event.values[2]);
- }
- }
- }
- }
-
- public void pause() {
- if (mSensor != null) {
- SensorManager sManager = (SensorManager) mContext
- .getSystemService(Context.SENSOR_SERVICE);
- sManager.unregisterListener(mPositionListener);
- }
- }
-
- public void resume() {
- if (mSensor != null) {
- SensorManager sManager = (SensorManager) mContext
- .getSystemService(Context.SENSOR_SERVICE);
- sManager.registerListener(mPositionListener,
- mSensor, SensorManager.SENSOR_DELAY_GAME);
- }
-
- mStartTime = NOT_STARTED;
- mGyroscopeCountdown = GYROSCOPE_SETTLE_DOWN;
- mX = mY = 0;
- mZ = -mUserDistance;
- mListener.onEyePositionChanged(mX, mY, mZ);
- }
-}
diff --git a/src/com/android/gallery3d/app/FilmstripPage.java b/src/com/android/gallery3d/app/FilmstripPage.java
deleted file mode 100644
index a9726cdc9..000000000
--- a/src/com/android/gallery3d/app/FilmstripPage.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-public class FilmstripPage extends PhotoPage {
-
-}
diff --git a/src/com/android/gallery3d/app/FilterUtils.java b/src/com/android/gallery3d/app/FilterUtils.java
deleted file mode 100644
index bc28a9cc1..000000000
--- a/src/com/android/gallery3d/app/FilterUtils.java
+++ /dev/null
@@ -1,257 +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.app;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.Path;
-
-// This class handles filtering and clustering.
-//
-// We allow at most only one filter operation at a time (Currently it
-// doesn't make sense to use more than one). Also each clustering operation
-// can be applied at most once. In addition, there is one more constraint
-// ("fixed set constraint") described below.
-//
-// A clustered album (not including album set) and its base sets are fixed.
-// For example,
-//
-// /cluster/{base_set}/time/7
-//
-// This set and all sets inside base_set (recursively) are fixed because
-// 1. We can not change this set to use another clustering condition (like
-// changing "time" to "location").
-// 2. Neither can we change any set in the base_set.
-// The reason is in both cases the 7th set may not exist in the new clustering.
-// ---------------------
-// newPath operation: create a new path based on a source path and put an extra
-// condition on top of it:
-//
-// T = newFilterPath(S, filterType);
-// T = newClusterPath(S, clusterType);
-//
-// Similar functions can be used to replace the current condition (if there is one).
-//
-// T = switchFilterPath(S, filterType);
-// T = switchClusterPath(S, clusterType);
-//
-// For all fixed set in the path defined above, if some clusterType and
-// filterType are already used, they cannot not be used as parameter for these
-// functions. setupMenuItems() makes sure those types cannot be selected.
-//
-public class FilterUtils {
- @SuppressWarnings("unused")
- private static final String TAG = "FilterUtils";
-
- public static final int CLUSTER_BY_ALBUM = 1;
- public static final int CLUSTER_BY_TIME = 2;
- public static final int CLUSTER_BY_LOCATION = 4;
- public static final int CLUSTER_BY_TAG = 8;
- public static final int CLUSTER_BY_SIZE = 16;
- public static final int CLUSTER_BY_FACE = 32;
-
- public static final int FILTER_IMAGE_ONLY = 1;
- public static final int FILTER_VIDEO_ONLY = 2;
- public static final int FILTER_ALL = 4;
-
- // These are indices of the return values of getAppliedFilters().
- // The _F suffix means "fixed".
- private static final int CLUSTER_TYPE = 0;
- private static final int FILTER_TYPE = 1;
- private static final int CLUSTER_TYPE_F = 2;
- private static final int FILTER_TYPE_F = 3;
- private static final int CLUSTER_CURRENT_TYPE = 4;
- private static final int FILTER_CURRENT_TYPE = 5;
-
- public static void setupMenuItems(GalleryActionBar actionBar, Path path, boolean inAlbum) {
- int[] result = new int[6];
- getAppliedFilters(path, result);
- int ctype = result[CLUSTER_TYPE];
- int ftype = result[FILTER_TYPE];
- int ftypef = result[FILTER_TYPE_F];
- int ccurrent = result[CLUSTER_CURRENT_TYPE];
- int fcurrent = result[FILTER_CURRENT_TYPE];
-
- setMenuItemApplied(actionBar, CLUSTER_BY_TIME,
- (ctype & CLUSTER_BY_TIME) != 0, (ccurrent & CLUSTER_BY_TIME) != 0);
- setMenuItemApplied(actionBar, CLUSTER_BY_LOCATION,
- (ctype & CLUSTER_BY_LOCATION) != 0, (ccurrent & CLUSTER_BY_LOCATION) != 0);
- setMenuItemApplied(actionBar, CLUSTER_BY_TAG,
- (ctype & CLUSTER_BY_TAG) != 0, (ccurrent & CLUSTER_BY_TAG) != 0);
- setMenuItemApplied(actionBar, CLUSTER_BY_FACE,
- (ctype & CLUSTER_BY_FACE) != 0, (ccurrent & CLUSTER_BY_FACE) != 0);
-
- actionBar.setClusterItemVisibility(CLUSTER_BY_ALBUM, !inAlbum || ctype == 0);
-
- setMenuItemApplied(actionBar, R.id.action_cluster_album, ctype == 0,
- ccurrent == 0);
-
- // A filtering is available if it's not applied, and the old filtering
- // (if any) is not fixed.
- setMenuItemAppliedEnabled(actionBar, R.string.show_images_only,
- (ftype & FILTER_IMAGE_ONLY) != 0,
- (ftype & FILTER_IMAGE_ONLY) == 0 && ftypef == 0,
- (fcurrent & FILTER_IMAGE_ONLY) != 0);
- setMenuItemAppliedEnabled(actionBar, R.string.show_videos_only,
- (ftype & FILTER_VIDEO_ONLY) != 0,
- (ftype & FILTER_VIDEO_ONLY) == 0 && ftypef == 0,
- (fcurrent & FILTER_VIDEO_ONLY) != 0);
- setMenuItemAppliedEnabled(actionBar, R.string.show_all,
- ftype == 0, ftype != 0 && ftypef == 0, fcurrent == 0);
- }
-
- // Gets the filters applied in the path.
- private static void getAppliedFilters(Path path, int[] result) {
- getAppliedFilters(path, result, false);
- }
-
- private static void getAppliedFilters(Path path, int[] result, boolean underCluster) {
- String[] segments = path.split();
- // Recurse into sub media sets.
- for (int i = 0; i < segments.length; i++) {
- if (segments[i].startsWith("{")) {
- String[] sets = Path.splitSequence(segments[i]);
- for (int j = 0; j < sets.length; j++) {
- Path sub = Path.fromString(sets[j]);
- getAppliedFilters(sub, result, underCluster);
- }
- }
- }
-
- // update current selection
- if (segments[0].equals("cluster")) {
- // if this is a clustered album, set underCluster to true.
- if (segments.length == 4) {
- underCluster = true;
- }
-
- int ctype = toClusterType(segments[2]);
- result[CLUSTER_TYPE] |= ctype;
- result[CLUSTER_CURRENT_TYPE] = ctype;
- if (underCluster) {
- result[CLUSTER_TYPE_F] |= ctype;
- }
- }
- }
-
- private static int toClusterType(String s) {
- if (s.equals("time")) {
- return CLUSTER_BY_TIME;
- } else if (s.equals("location")) {
- return CLUSTER_BY_LOCATION;
- } else if (s.equals("tag")) {
- return CLUSTER_BY_TAG;
- } else if (s.equals("size")) {
- return CLUSTER_BY_SIZE;
- } else if (s.equals("face")) {
- return CLUSTER_BY_FACE;
- }
- return 0;
- }
-
- private static void setMenuItemApplied(
- GalleryActionBar model, int id, boolean applied, boolean updateTitle) {
- model.setClusterItemEnabled(id, !applied);
- }
-
- private static void setMenuItemAppliedEnabled(GalleryActionBar model, int id, boolean applied, boolean enabled, boolean updateTitle) {
- model.setClusterItemEnabled(id, enabled);
- }
-
- // Add a specified filter to the path.
- public static String newFilterPath(String base, int filterType) {
- int mediaType;
- switch (filterType) {
- case FILTER_IMAGE_ONLY:
- mediaType = MediaObject.MEDIA_TYPE_IMAGE;
- break;
- case FILTER_VIDEO_ONLY:
- mediaType = MediaObject.MEDIA_TYPE_VIDEO;
- break;
- default: /* FILTER_ALL */
- return base;
- }
-
- return "/filter/mediatype/" + mediaType + "/{" + base + "}";
- }
-
- // Add a specified clustering to the path.
- public static String newClusterPath(String base, int clusterType) {
- String kind;
- switch (clusterType) {
- case CLUSTER_BY_TIME:
- kind = "time";
- break;
- case CLUSTER_BY_LOCATION:
- kind = "location";
- break;
- case CLUSTER_BY_TAG:
- kind = "tag";
- break;
- case CLUSTER_BY_SIZE:
- kind = "size";
- break;
- case CLUSTER_BY_FACE:
- kind = "face";
- break;
- default: /* CLUSTER_BY_ALBUM */
- return base;
- }
-
- return "/cluster/{" + base + "}/" + kind;
- }
-
- // Change the topmost clustering to the specified type.
- public static String switchClusterPath(String base, int clusterType) {
- return newClusterPath(removeOneClusterFromPath(base), clusterType);
- }
-
- // Remove the topmost clustering (if any) from the path.
- private static String removeOneClusterFromPath(String base) {
- boolean[] done = new boolean[1];
- return removeOneClusterFromPath(base, done);
- }
-
- private static String removeOneClusterFromPath(String base, boolean[] done) {
- if (done[0]) return base;
-
- String[] segments = Path.split(base);
- if (segments[0].equals("cluster")) {
- done[0] = true;
- return Path.splitSequence(segments[1])[0];
- }
-
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < segments.length; i++) {
- sb.append("/");
- if (segments[i].startsWith("{")) {
- sb.append("{");
- String[] sets = Path.splitSequence(segments[i]);
- for (int j = 0; j < sets.length; j++) {
- if (j > 0) {
- sb.append(",");
- }
- sb.append(removeOneClusterFromPath(sets[j], done));
- }
- sb.append("}");
- } else {
- sb.append(segments[i]);
- }
- }
- return sb.toString();
- }
-}
diff --git a/src/com/android/gallery3d/app/Gallery.java b/src/com/android/gallery3d/app/Gallery.java
deleted file mode 100644
index baef56b44..000000000
--- a/src/com/android/gallery3d/app/Gallery.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (C) 2009 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.app;
-
-import android.app.Dialog;
-import android.content.ContentResolver;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.Toast;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.picasasource.PicasaSource;
-import com.android.gallery3d.util.GalleryUtils;
-
-public final class Gallery extends AbstractGalleryActivity implements OnCancelListener {
- public static final String EXTRA_SLIDESHOW = "slideshow";
- public static final String EXTRA_DREAM = "dream";
- public static final String EXTRA_CROP = "crop";
-
- public static final String ACTION_REVIEW = "com.android.camera.action.REVIEW";
- public static final String KEY_GET_CONTENT = "get-content";
- public static final String KEY_GET_ALBUM = "get-album";
- public static final String KEY_TYPE_BITS = "type-bits";
- public static final String KEY_MEDIA_TYPES = "mediaTypes";
- public static final String KEY_DISMISS_KEYGUARD = "dismiss-keyguard";
-
- private static final String TAG = "Gallery";
- private Dialog mVersionCheckDialog;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_ACTION_BAR);
- requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
-
- if (getIntent().getBooleanExtra(KEY_DISMISS_KEYGUARD, false)) {
- getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
- }
-
- setContentView(R.layout.main);
-
- if (savedInstanceState != null) {
- getStateManager().restoreFromState(savedInstanceState);
- } else {
- initializeByIntent();
- }
- }
-
- private void initializeByIntent() {
- Intent intent = getIntent();
- String action = intent.getAction();
-
- if (Intent.ACTION_GET_CONTENT.equalsIgnoreCase(action)) {
- startGetContent(intent);
- } else if (Intent.ACTION_PICK.equalsIgnoreCase(action)) {
- // We do NOT really support the PICK intent. Handle it as
- // the GET_CONTENT. However, we need to translate the type
- // in the intent here.
- Log.w(TAG, "action PICK is not supported");
- String type = Utils.ensureNotNull(intent.getType());
- if (type.startsWith("vnd.android.cursor.dir/")) {
- if (type.endsWith("/image")) intent.setType("image/*");
- if (type.endsWith("/video")) intent.setType("video/*");
- }
- startGetContent(intent);
- } else if (Intent.ACTION_VIEW.equalsIgnoreCase(action)
- || ACTION_REVIEW.equalsIgnoreCase(action)){
- startViewAction(intent);
- } else {
- startDefaultPage();
- }
- }
-
- public void startDefaultPage() {
- PicasaSource.showSignInReminder(this);
- Bundle data = new Bundle();
- data.putString(AlbumSetPage.KEY_MEDIA_PATH,
- getDataManager().getTopSetPath(DataManager.INCLUDE_ALL));
- getStateManager().startState(AlbumSetPage.class, data);
- mVersionCheckDialog = PicasaSource.getVersionCheckDialog(this);
- if (mVersionCheckDialog != null) {
- mVersionCheckDialog.setOnCancelListener(this);
- }
- }
-
- private void startGetContent(Intent intent) {
- Bundle data = intent.getExtras() != null
- ? new Bundle(intent.getExtras())
- : new Bundle();
- data.putBoolean(KEY_GET_CONTENT, true);
- int typeBits = GalleryUtils.determineTypeBits(this, intent);
- data.putInt(KEY_TYPE_BITS, typeBits);
- data.putString(AlbumSetPage.KEY_MEDIA_PATH,
- getDataManager().getTopSetPath(typeBits));
- getStateManager().startState(AlbumSetPage.class, data);
- }
-
- private String getContentType(Intent intent) {
- String type = intent.getType();
- if (type != null) {
- return GalleryUtils.MIME_TYPE_PANORAMA360.equals(type)
- ? MediaItem.MIME_TYPE_JPEG : type;
- }
-
- Uri uri = intent.getData();
- try {
- return getContentResolver().getType(uri);
- } catch (Throwable t) {
- Log.w(TAG, "get type fail", t);
- return null;
- }
- }
-
- private void startViewAction(Intent intent) {
- Boolean slideshow = intent.getBooleanExtra(EXTRA_SLIDESHOW, false);
- if (slideshow) {
- getActionBar().hide();
- DataManager manager = getDataManager();
- Path path = manager.findPathByUri(intent.getData(), intent.getType());
- if (path == null || manager.getMediaObject(path)
- instanceof MediaItem) {
- path = Path.fromString(
- manager.getTopSetPath(DataManager.INCLUDE_IMAGE));
- }
- Bundle data = new Bundle();
- data.putString(SlideshowPage.KEY_SET_PATH, path.toString());
- data.putBoolean(SlideshowPage.KEY_RANDOM_ORDER, true);
- data.putBoolean(SlideshowPage.KEY_REPEAT, true);
- if (intent.getBooleanExtra(EXTRA_DREAM, false)) {
- data.putBoolean(SlideshowPage.KEY_DREAM, true);
- }
- getStateManager().startState(SlideshowPage.class, data);
- } else {
- Bundle data = new Bundle();
- DataManager dm = getDataManager();
- Uri uri = intent.getData();
- String contentType = getContentType(intent);
- if (contentType == null) {
- Toast.makeText(this,
- R.string.no_such_item, Toast.LENGTH_LONG).show();
- finish();
- return;
- }
- if (uri == null) {
- int typeBits = GalleryUtils.determineTypeBits(this, intent);
- data.putInt(KEY_TYPE_BITS, typeBits);
- data.putString(AlbumSetPage.KEY_MEDIA_PATH,
- getDataManager().getTopSetPath(typeBits));
- getStateManager().startState(AlbumSetPage.class, data);
- } else if (contentType.startsWith(
- ContentResolver.CURSOR_DIR_BASE_TYPE)) {
- int mediaType = intent.getIntExtra(KEY_MEDIA_TYPES, 0);
- if (mediaType != 0) {
- uri = uri.buildUpon().appendQueryParameter(
- KEY_MEDIA_TYPES, String.valueOf(mediaType))
- .build();
- }
- Path setPath = dm.findPathByUri(uri, null);
- MediaSet mediaSet = null;
- if (setPath != null) {
- mediaSet = (MediaSet) dm.getMediaObject(setPath);
- }
- if (mediaSet != null) {
- if (mediaSet.isLeafAlbum()) {
- data.putString(AlbumPage.KEY_MEDIA_PATH, setPath.toString());
- data.putString(AlbumPage.KEY_PARENT_MEDIA_PATH,
- dm.getTopSetPath(DataManager.INCLUDE_ALL));
- getStateManager().startState(AlbumPage.class, data);
- } else {
- data.putString(AlbumSetPage.KEY_MEDIA_PATH, setPath.toString());
- getStateManager().startState(AlbumSetPage.class, data);
- }
- } else {
- startDefaultPage();
- }
- } else {
- Path itemPath = dm.findPathByUri(uri, contentType);
- Path albumPath = dm.getDefaultSetOf(itemPath);
-
- data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, itemPath.toString());
-
- // TODO: Make the parameter "SingleItemOnly" public so other
- // activities can reference it.
- boolean singleItemOnly = (albumPath == null)
- || intent.getBooleanExtra("SingleItemOnly", false);
- if (!singleItemOnly) {
- data.putString(PhotoPage.KEY_MEDIA_SET_PATH, albumPath.toString());
- // when FLAG_ACTIVITY_NEW_TASK is set, (e.g. when intent is fired
- // from notification), back button should behave the same as up button
- // rather than taking users back to the home screen
- if (intent.getBooleanExtra(PhotoPage.KEY_TREAT_BACK_AS_UP, false)
- || ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0)) {
- data.putBoolean(PhotoPage.KEY_TREAT_BACK_AS_UP, true);
- }
- }
-
- getStateManager().startState(SinglePhotoPage.class, data);
- }
- }
- }
-
- @Override
- protected void onResume() {
- Utils.assertTrue(getStateManager().getStateCount() > 0);
- super.onResume();
- if (mVersionCheckDialog != null) {
- mVersionCheckDialog.show();
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- if (mVersionCheckDialog != null) {
- mVersionCheckDialog.dismiss();
- }
- }
-
- @Override
- public void onCancel(DialogInterface dialog) {
- if (dialog == mVersionCheckDialog) {
- mVersionCheckDialog = null;
- }
- }
-
- @Override
- public boolean onGenericMotionEvent(MotionEvent event) {
- final boolean isTouchPad = (event.getSource()
- & InputDevice.SOURCE_CLASS_POSITION) != 0;
- if (isTouchPad) {
- float maxX = event.getDevice().getMotionRange(MotionEvent.AXIS_X).getMax();
- float maxY = event.getDevice().getMotionRange(MotionEvent.AXIS_Y).getMax();
- View decor = getWindow().getDecorView();
- float scaleX = decor.getWidth() / maxX;
- float scaleY = decor.getHeight() / maxY;
- float x = event.getX() * scaleX;
- //x = decor.getWidth() - x; // invert x
- float y = event.getY() * scaleY;
- //y = decor.getHeight() - y; // invert y
- MotionEvent touchEvent = MotionEvent.obtain(event.getDownTime(),
- event.getEventTime(), event.getAction(), x, y, event.getMetaState());
- return dispatchTouchEvent(touchEvent);
- }
- return super.onGenericMotionEvent(event);
- }
-}
diff --git a/src/com/android/gallery3d/app/GalleryActionBar.java b/src/com/android/gallery3d/app/GalleryActionBar.java
deleted file mode 100644
index 588f5842a..000000000
--- a/src/com/android/gallery3d/app/GalleryActionBar.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2011 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.app;
-
-import android.annotation.TargetApi;
-import android.app.ActionBar;
-import android.app.ActionBar.OnMenuVisibilityListener;
-import android.app.ActionBar.OnNavigationListener;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ShareActionProvider;
-import android.widget.TextView;
-import android.widget.TwoLineListItem;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.util.ArrayList;
-
-public class GalleryActionBar implements OnNavigationListener {
- @SuppressWarnings("unused")
- private static final String TAG = "GalleryActionBar";
-
- private ClusterRunner mClusterRunner;
- private CharSequence[] mTitles;
- private ArrayList<Integer> mActions;
- private Context mContext;
- private LayoutInflater mInflater;
- private AbstractGalleryActivity mActivity;
- private ActionBar mActionBar;
- private int mCurrentIndex;
- private ClusterAdapter mAdapter = new ClusterAdapter();
-
- private AlbumModeAdapter mAlbumModeAdapter;
- private OnAlbumModeSelectedListener mAlbumModeListener;
- private int mLastAlbumModeSelected;
- private CharSequence [] mAlbumModes;
- public static final int ALBUM_FILMSTRIP_MODE_SELECTED = 0;
- public static final int ALBUM_GRID_MODE_SELECTED = 1;
-
- public interface ClusterRunner {
- public void doCluster(int id);
- }
-
- public interface OnAlbumModeSelectedListener {
- public void onAlbumModeSelected(int mode);
- }
-
- private static class ActionItem {
- public int action;
- public boolean enabled;
- public boolean visible;
- public int spinnerTitle;
- public int dialogTitle;
- public int clusterBy;
-
- public ActionItem(int action, boolean applied, boolean enabled, int title,
- int clusterBy) {
- this(action, applied, enabled, title, title, clusterBy);
- }
-
- public ActionItem(int action, boolean applied, boolean enabled, int spinnerTitle,
- int dialogTitle, int clusterBy) {
- this.action = action;
- this.enabled = enabled;
- this.spinnerTitle = spinnerTitle;
- this.dialogTitle = dialogTitle;
- this.clusterBy = clusterBy;
- this.visible = true;
- }
- }
-
- private static final ActionItem[] sClusterItems = new ActionItem[] {
- new ActionItem(FilterUtils.CLUSTER_BY_ALBUM, true, false, R.string.albums,
- R.string.group_by_album),
- new ActionItem(FilterUtils.CLUSTER_BY_LOCATION, true, false,
- R.string.locations, R.string.location, R.string.group_by_location),
- new ActionItem(FilterUtils.CLUSTER_BY_TIME, true, false, R.string.times,
- R.string.time, R.string.group_by_time),
- new ActionItem(FilterUtils.CLUSTER_BY_FACE, true, false, R.string.people,
- R.string.group_by_faces),
- new ActionItem(FilterUtils.CLUSTER_BY_TAG, true, false, R.string.tags,
- R.string.group_by_tags)
- };
-
- private class ClusterAdapter extends BaseAdapter {
-
- @Override
- public int getCount() {
- return sClusterItems.length;
- }
-
- @Override
- public Object getItem(int position) {
- return sClusterItems[position];
- }
-
- @Override
- public long getItemId(int position) {
- return sClusterItems[position].action;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = mInflater.inflate(R.layout.action_bar_text,
- parent, false);
- }
- TextView view = (TextView) convertView;
- view.setText(sClusterItems[position].spinnerTitle);
- return convertView;
- }
- }
-
- private class AlbumModeAdapter extends BaseAdapter {
- @Override
- public int getCount() {
- return mAlbumModes.length;
- }
-
- @Override
- public Object getItem(int position) {
- return mAlbumModes[position];
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = mInflater.inflate(R.layout.action_bar_two_line_text,
- parent, false);
- }
- TwoLineListItem view = (TwoLineListItem) convertView;
- view.getText1().setText(mActionBar.getTitle());
- view.getText2().setText((CharSequence) getItem(position));
- return convertView;
- }
-
- @Override
- public View getDropDownView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = mInflater.inflate(R.layout.action_bar_text,
- parent, false);
- }
- TextView view = (TextView) convertView;
- view.setText((CharSequence) getItem(position));
- return convertView;
- }
- }
-
- public static String getClusterByTypeString(Context context, int type) {
- for (ActionItem item : sClusterItems) {
- if (item.action == type) {
- return context.getString(item.clusterBy);
- }
- }
- return null;
- }
-
- public GalleryActionBar(AbstractGalleryActivity activity) {
- mActionBar = activity.getActionBar();
- mContext = activity.getAndroidContext();
- mActivity = activity;
- mInflater = ((Activity) mActivity).getLayoutInflater();
- mCurrentIndex = 0;
- }
-
- private void createDialogData() {
- ArrayList<CharSequence> titles = new ArrayList<CharSequence>();
- mActions = new ArrayList<Integer>();
- for (ActionItem item : sClusterItems) {
- if (item.enabled && item.visible) {
- titles.add(mContext.getString(item.dialogTitle));
- mActions.add(item.action);
- }
- }
- mTitles = new CharSequence[titles.size()];
- titles.toArray(mTitles);
- }
-
- public int getHeight() {
- return mActionBar != null ? mActionBar.getHeight() : 0;
- }
-
- public void setClusterItemEnabled(int id, boolean enabled) {
- for (ActionItem item : sClusterItems) {
- if (item.action == id) {
- item.enabled = enabled;
- return;
- }
- }
- }
-
- public void setClusterItemVisibility(int id, boolean visible) {
- for (ActionItem item : sClusterItems) {
- if (item.action == id) {
- item.visible = visible;
- return;
- }
- }
- }
-
- public int getClusterTypeAction() {
- return sClusterItems[mCurrentIndex].action;
- }
-
- public void enableClusterMenu(int action, ClusterRunner runner) {
- if (mActionBar != null) {
- // Don't set cluster runner until action bar is ready.
- mClusterRunner = null;
- mActionBar.setListNavigationCallbacks(mAdapter, this);
- mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
- setSelectedAction(action);
- mClusterRunner = runner;
- }
- }
-
- // The only use case not to hideMenu in this method is to ensure
- // all elements disappear at the same time when exiting gallery.
- // hideMenu should always be true in all other cases.
- public void disableClusterMenu(boolean hideMenu) {
- if (mActionBar != null) {
- mClusterRunner = null;
- if (hideMenu) {
- mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
- }
- }
- }
-
- public void onConfigurationChanged() {
- if (mActionBar != null && mAlbumModeListener != null) {
- OnAlbumModeSelectedListener listener = mAlbumModeListener;
- enableAlbumModeMenu(mLastAlbumModeSelected, listener);
- }
- }
-
- public void enableAlbumModeMenu(int selected, OnAlbumModeSelectedListener listener) {
- if (mActionBar != null) {
- if (mAlbumModeAdapter == null) {
- // Initialize the album mode options if they haven't been already
- Resources res = mActivity.getResources();
- mAlbumModes = new CharSequence[] {
- res.getString(R.string.switch_photo_filmstrip),
- res.getString(R.string.switch_photo_grid)};
- mAlbumModeAdapter = new AlbumModeAdapter();
- }
- mAlbumModeListener = null;
- mLastAlbumModeSelected = selected;
- mActionBar.setListNavigationCallbacks(mAlbumModeAdapter, this);
- mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
- mActionBar.setSelectedNavigationItem(selected);
- mAlbumModeListener = listener;
- }
- }
-
- public void disableAlbumModeMenu(boolean hideMenu) {
- if (mActionBar != null) {
- mAlbumModeListener = null;
- if (hideMenu) {
- mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
- }
- }
- }
-
- public void showClusterDialog(final ClusterRunner clusterRunner) {
- createDialogData();
- final ArrayList<Integer> actions = mActions;
- new AlertDialog.Builder(mContext).setTitle(R.string.group_by).setItems(
- mTitles, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // Need to lock rendering when operations invoked by system UI (main thread) are
- // modifying slot data used in GL thread for rendering.
- mActivity.getGLRoot().lockRenderThread();
- try {
- clusterRunner.doCluster(actions.get(which).intValue());
- } finally {
- mActivity.getGLRoot().unlockRenderThread();
- }
- }
- }).create().show();
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void setHomeButtonEnabled(boolean enabled) {
- if (mActionBar != null) mActionBar.setHomeButtonEnabled(enabled);
- }
-
- public void setDisplayOptions(boolean displayHomeAsUp, boolean showTitle) {
- if (mActionBar == null) return;
- int options = 0;
- if (displayHomeAsUp) options |= ActionBar.DISPLAY_HOME_AS_UP;
- if (showTitle) options |= ActionBar.DISPLAY_SHOW_TITLE;
-
- mActionBar.setDisplayOptions(options,
- ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_TITLE);
- mActionBar.setHomeButtonEnabled(displayHomeAsUp);
- }
-
- public void setTitle(String title) {
- if (mActionBar != null) mActionBar.setTitle(title);
- }
-
- public void setTitle(int titleId) {
- if (mActionBar != null) {
- mActionBar.setTitle(mContext.getString(titleId));
- }
- }
-
- public void setSubtitle(String title) {
- if (mActionBar != null) mActionBar.setSubtitle(title);
- }
-
- public void show() {
- if (mActionBar != null) mActionBar.show();
- }
-
- public void hide() {
- if (mActionBar != null) mActionBar.hide();
- }
-
- public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
- if (mActionBar != null) mActionBar.addOnMenuVisibilityListener(listener);
- }
-
- public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
- if (mActionBar != null) mActionBar.removeOnMenuVisibilityListener(listener);
- }
-
- public boolean setSelectedAction(int type) {
- if (mActionBar == null) return false;
-
- for (int i = 0, n = sClusterItems.length; i < n; i++) {
- ActionItem item = sClusterItems[i];
- if (item.action == type) {
- mActionBar.setSelectedNavigationItem(i);
- mCurrentIndex = i;
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean onNavigationItemSelected(int itemPosition, long itemId) {
- if (itemPosition != mCurrentIndex && mClusterRunner != null
- || mAlbumModeListener != null) {
- // Need to lock rendering when operations invoked by system UI (main thread) are
- // modifying slot data used in GL thread for rendering.
- mActivity.getGLRoot().lockRenderThread();
- try {
- if (mAlbumModeListener != null) {
- mAlbumModeListener.onAlbumModeSelected(itemPosition);
- } else {
- mClusterRunner.doCluster(sClusterItems[itemPosition].action);
- }
- } finally {
- mActivity.getGLRoot().unlockRenderThread();
- }
- }
- return false;
- }
-
- private Menu mActionBarMenu;
- private ShareActionProvider mSharePanoramaActionProvider;
- private ShareActionProvider mShareActionProvider;
- private Intent mSharePanoramaIntent;
- private Intent mShareIntent;
-
- public void createActionBarMenu(int menuRes, Menu menu) {
- mActivity.getMenuInflater().inflate(menuRes, menu);
- mActionBarMenu = menu;
-
- MenuItem item = menu.findItem(R.id.action_share_panorama);
- if (item != null) {
- mSharePanoramaActionProvider = (ShareActionProvider)
- item.getActionProvider();
- mSharePanoramaActionProvider
- .setShareHistoryFileName("panorama_share_history.xml");
- mSharePanoramaActionProvider.setShareIntent(mSharePanoramaIntent);
- }
-
- item = menu.findItem(R.id.action_share);
- if (item != null) {
- mShareActionProvider = (ShareActionProvider)
- item.getActionProvider();
- mShareActionProvider
- .setShareHistoryFileName("share_history.xml");
- mShareActionProvider.setShareIntent(mShareIntent);
- }
- }
-
- public Menu getMenu() {
- return mActionBarMenu;
- }
-
- public void setShareIntents(Intent sharePanoramaIntent, Intent shareIntent,
- ShareActionProvider.OnShareTargetSelectedListener onShareListener) {
- mSharePanoramaIntent = sharePanoramaIntent;
- if (mSharePanoramaActionProvider != null) {
- mSharePanoramaActionProvider.setShareIntent(sharePanoramaIntent);
- }
- mShareIntent = shareIntent;
- if (mShareActionProvider != null) {
- mShareActionProvider.setShareIntent(shareIntent);
- mShareActionProvider.setOnShareTargetSelectedListener(
- onShareListener);
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/GalleryApp.java b/src/com/android/gallery3d/app/GalleryApp.java
deleted file mode 100644
index b56b8a82c..000000000
--- a/src/com/android/gallery3d/app/GalleryApp.java
+++ /dev/null
@@ -1,41 +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.app;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Looper;
-
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.DownloadCache;
-import com.android.gallery3d.data.ImageCacheService;
-import com.android.gallery3d.util.ThreadPool;
-
-public interface GalleryApp {
- public DataManager getDataManager();
-
- public StitchingProgressManager getStitchingProgressManager();
- public ImageCacheService getImageCacheService();
- public DownloadCache getDownloadCache();
- public ThreadPool getThreadPool();
-
- public Context getAndroidContext();
- public Looper getMainLooper();
- public ContentResolver getContentResolver();
- public Resources getResources();
-}
diff --git a/src/com/android/gallery3d/app/GalleryAppImpl.java b/src/com/android/gallery3d/app/GalleryAppImpl.java
deleted file mode 100644
index 2abdaa0c1..000000000
--- a/src/com/android/gallery3d/app/GalleryAppImpl.java
+++ /dev/null
@@ -1,127 +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.app;
-
-import android.app.Application;
-import android.content.Context;
-import android.os.AsyncTask;
-
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.DownloadCache;
-import com.android.gallery3d.data.ImageCacheService;
-import com.android.gallery3d.gadget.WidgetUtils;
-import com.android.gallery3d.picasasource.PicasaSource;
-import com.android.gallery3d.util.GalleryUtils;
-import com.android.gallery3d.util.LightCycleHelper;
-import com.android.gallery3d.util.ThreadPool;
-import com.android.gallery3d.util.UsageStatistics;
-import com.android.photos.data.MediaCache;
-
-import java.io.File;
-
-public class GalleryAppImpl extends Application implements GalleryApp {
-
- private static final String DOWNLOAD_FOLDER = "download";
- private static final long DOWNLOAD_CAPACITY = 64 * 1024 * 1024; // 64M
-
- private ImageCacheService mImageCacheService;
- private Object mLock = new Object();
- private DataManager mDataManager;
- private ThreadPool mThreadPool;
- private DownloadCache mDownloadCache;
- private StitchingProgressManager mStitchingProgressManager;
-
- @Override
- public void onCreate() {
- super.onCreate();
- com.android.camera.Util.initialize(this);
- initializeAsyncTask();
- GalleryUtils.initialize(this);
- WidgetUtils.initialize(this);
- PicasaSource.initialize(this);
- UsageStatistics.initialize(this);
- MediaCache.initialize(this);
-
- mStitchingProgressManager = LightCycleHelper.createStitchingManagerInstance(this);
- if (mStitchingProgressManager != null) {
- mStitchingProgressManager.addChangeListener(getDataManager());
- }
- }
-
- @Override
- public Context getAndroidContext() {
- return this;
- }
-
- @Override
- public synchronized DataManager getDataManager() {
- if (mDataManager == null) {
- mDataManager = new DataManager(this);
- mDataManager.initializeSourceMap();
- }
- return mDataManager;
- }
-
- @Override
- public StitchingProgressManager getStitchingProgressManager() {
- return mStitchingProgressManager;
- }
-
- @Override
- public ImageCacheService getImageCacheService() {
- // This method may block on file I/O so a dedicated lock is needed here.
- synchronized (mLock) {
- if (mImageCacheService == null) {
- mImageCacheService = new ImageCacheService(getAndroidContext());
- }
- return mImageCacheService;
- }
- }
-
- @Override
- public synchronized ThreadPool getThreadPool() {
- if (mThreadPool == null) {
- mThreadPool = new ThreadPool();
- }
- return mThreadPool;
- }
-
- @Override
- public synchronized DownloadCache getDownloadCache() {
- if (mDownloadCache == null) {
- File cacheDir = new File(getExternalCacheDir(), DOWNLOAD_FOLDER);
-
- if (!cacheDir.isDirectory()) cacheDir.mkdirs();
-
- if (!cacheDir.isDirectory()) {
- throw new RuntimeException(
- "fail to create: " + cacheDir.getAbsolutePath());
- }
- mDownloadCache = new DownloadCache(this, cacheDir, DOWNLOAD_CAPACITY);
- }
- return mDownloadCache;
- }
-
- private void initializeAsyncTask() {
- // AsyncTask class needs to be loaded in UI thread.
- // So we load it here to comply the rule.
- try {
- Class.forName(AsyncTask.class.getName());
- } catch (ClassNotFoundException e) {
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/GalleryContext.java b/src/com/android/gallery3d/app/GalleryContext.java
deleted file mode 100644
index 06f4fe4d1..000000000
--- a/src/com/android/gallery3d/app/GalleryContext.java
+++ /dev/null
@@ -1,34 +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.app;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Looper;
-
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.util.ThreadPool;
-
-public interface GalleryContext {
- public DataManager getDataManager();
-
- public Context getAndroidContext();
-
- public Looper getMainLooper();
- public Resources getResources();
- public ThreadPool getThreadPool();
-}
diff --git a/src/com/android/gallery3d/app/LoadingListener.java b/src/com/android/gallery3d/app/LoadingListener.java
deleted file mode 100644
index e94df9307..000000000
--- a/src/com/android/gallery3d/app/LoadingListener.java
+++ /dev/null
@@ -1,27 +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.app;
-
-public interface LoadingListener {
- public void onLoadingStarted();
- /**
- * Called when loading is complete or no further progress can be made.
- *
- * @param loadingFailed true if data source cannot provide requested data
- */
- public void onLoadingFinished(boolean loadingFailed);
-}
diff --git a/src/com/android/gallery3d/app/Log.java b/src/com/android/gallery3d/app/Log.java
deleted file mode 100644
index 07a8ea588..000000000
--- a/src/com/android/gallery3d/app/Log.java
+++ /dev/null
@@ -1,53 +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.app;
-
-public class Log {
- public static int v(String tag, String msg) {
- return android.util.Log.v(tag, msg);
- }
- public static int v(String tag, String msg, Throwable tr) {
- return android.util.Log.v(tag, msg, tr);
- }
- public static int d(String tag, String msg) {
- return android.util.Log.d(tag, msg);
- }
- public static int d(String tag, String msg, Throwable tr) {
- return android.util.Log.d(tag, msg, tr);
- }
- public static int i(String tag, String msg) {
- return android.util.Log.i(tag, msg);
- }
- public static int i(String tag, String msg, Throwable tr) {
- return android.util.Log.i(tag, msg, tr);
- }
- public static int w(String tag, String msg) {
- return android.util.Log.w(tag, msg);
- }
- public static int w(String tag, String msg, Throwable tr) {
- return android.util.Log.w(tag, msg, tr);
- }
- public static int w(String tag, Throwable tr) {
- return android.util.Log.w(tag, tr);
- }
- public static int e(String tag, String msg) {
- return android.util.Log.e(tag, msg);
- }
- public static int e(String tag, String msg, Throwable tr) {
- return android.util.Log.e(tag, msg, tr);
- }
-}
diff --git a/src/com/android/gallery3d/app/ManageCachePage.java b/src/com/android/gallery3d/app/ManageCachePage.java
deleted file mode 100644
index 4f5c35819..000000000
--- a/src/com/android/gallery3d/app/ManageCachePage.java
+++ /dev/null
@@ -1,419 +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.app;
-
-import android.app.Activity;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.text.format.Formatter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.FrameLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.glrenderer.GLCanvas;
-import com.android.gallery3d.ui.CacheStorageUsageInfo;
-import com.android.gallery3d.ui.GLRoot;
-import com.android.gallery3d.ui.GLView;
-import com.android.gallery3d.ui.ManageCacheDrawer;
-import com.android.gallery3d.ui.MenuExecutor;
-import com.android.gallery3d.ui.SelectionManager;
-import com.android.gallery3d.ui.SlotView;
-import com.android.gallery3d.ui.SynchronizedHandler;
-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 ManageCachePage extends ActivityState implements
- SelectionManager.SelectionListener, MenuExecutor.ProgressListener,
- EyePosition.EyePositionListener, OnClickListener {
- public static final String KEY_MEDIA_PATH = "media-path";
-
- @SuppressWarnings("unused")
- private static final String TAG = "ManageCachePage";
-
- private static final int DATA_CACHE_SIZE = 256;
- private static final int MSG_REFRESH_STORAGE_INFO = 1;
- private static final int MSG_REQUEST_LAYOUT = 2;
- private static final int PROGRESS_BAR_MAX = 10000;
-
- private SlotView mSlotView;
- private MediaSet mMediaSet;
-
- protected SelectionManager mSelectionManager;
- protected ManageCacheDrawer mSelectionDrawer;
- private AlbumSetDataLoader mAlbumSetDataAdapter;
-
- private EyePosition mEyePosition;
-
- // The eyes' position of the user, the origin is at the center of the
- // device and the unit is in pixels.
- private float mX;
- private float mY;
- private float mZ;
-
- private int mAlbumCountToMakeAvailableOffline;
- private View mFooterContent;
- private CacheStorageUsageInfo mCacheStorageInfo;
- private Future<Void> mUpdateStorageInfo;
- private Handler mHandler;
- private boolean mLayoutReady = false;
-
- @Override
- protected int getBackgroundColorId() {
- return R.color.cache_background;
- }
-
- private GLView mRootPane = new GLView() {
- private float mMatrix[] = new float[16];
-
- @Override
- protected void renderBackground(GLCanvas view) {
- view.clearBuffer(getBackgroundColor());
- }
-
- @Override
- protected void onLayout(
- boolean changed, int left, int top, int right, int bottom) {
- // Hack: our layout depends on other components on the screen.
- // We assume the other components will complete before we get a change
- // to run a message in main thread.
- if (!mLayoutReady) {
- mHandler.sendEmptyMessage(MSG_REQUEST_LAYOUT);
- return;
- }
- mLayoutReady = false;
-
- mEyePosition.resetPosition();
- int slotViewTop = mActivity.getGalleryActionBar().getHeight();
- int slotViewBottom = bottom - top;
-
- View footer = mActivity.findViewById(R.id.footer);
- if (footer != null) {
- int location[] = {0, 0};
- footer.getLocationOnScreen(location);
- slotViewBottom = location[1];
- }
-
- mSlotView.layout(0, slotViewTop, right - left, slotViewBottom);
- }
-
- @Override
- protected void render(GLCanvas canvas) {
- canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
- GalleryUtils.setViewPointMatrix(mMatrix,
- getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
- canvas.multiplyMatrix(mMatrix, 0);
- super.render(canvas);
- canvas.restore();
- }
- };
-
- @Override
- public void onEyePositionChanged(float x, float y, float z) {
- mRootPane.lockRendering();
- mX = x;
- mY = y;
- mZ = z;
- mRootPane.unlockRendering();
- mRootPane.invalidate();
- }
-
- private void onDown(int index) {
- mSelectionDrawer.setPressedIndex(index);
- }
-
- private void onUp() {
- mSelectionDrawer.setPressedIndex(-1);
- }
-
- public void onSingleTapUp(int slotIndex) {
- MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
- if (targetSet == null) return; // Content is dirty, we shall reload soon
-
- // ignore selection action if the target set does not support cache
- // operation (like a local album).
- if ((targetSet.getSupportedOperations()
- & MediaSet.SUPPORT_CACHE) == 0) {
- showToastForLocalAlbum();
- return;
- }
-
- Path path = targetSet.getPath();
- boolean isFullyCached =
- (targetSet.getCacheFlag() == MediaObject.CACHE_FLAG_FULL);
- boolean isSelected = mSelectionManager.isItemSelected(path);
-
- if (!isFullyCached) {
- // We only count the media sets that will be made available offline
- // in this session.
- if (isSelected) {
- --mAlbumCountToMakeAvailableOffline;
- } else {
- ++mAlbumCountToMakeAvailableOffline;
- }
- }
-
- long sizeOfTarget = targetSet.getCacheSize();
- mCacheStorageInfo.increaseTargetCacheSize(
- (isFullyCached ^ isSelected) ? -sizeOfTarget : sizeOfTarget);
- refreshCacheStorageInfo();
-
- mSelectionManager.toggle(path);
- mSlotView.invalidate();
- }
-
- @Override
- public void onCreate(Bundle data, Bundle restoreState) {
- super.onCreate(data, restoreState);
- mCacheStorageInfo = new CacheStorageUsageInfo(mActivity);
- initializeViews();
- initializeData(data);
- mEyePosition = new EyePosition(mActivity.getAndroidContext(), this);
- mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_REFRESH_STORAGE_INFO:
- refreshCacheStorageInfo();
- break;
- case MSG_REQUEST_LAYOUT: {
- mLayoutReady = true;
- removeMessages(MSG_REQUEST_LAYOUT);
- mRootPane.requestLayout();
- break;
- }
- }
- }
- };
- }
-
- @Override
- public void onConfigurationChanged(Configuration config) {
- // We use different layout resources for different configs
- initializeFooterViews();
- FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer);
- if (layout.getVisibility() == View.VISIBLE) {
- layout.removeAllViews();
- layout.addView(mFooterContent);
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mAlbumSetDataAdapter.pause();
- mSelectionDrawer.pause();
- mEyePosition.pause();
-
- if (mUpdateStorageInfo != null) {
- mUpdateStorageInfo.cancel();
- mUpdateStorageInfo = null;
- }
- mHandler.removeMessages(MSG_REFRESH_STORAGE_INFO);
-
- FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer);
- layout.removeAllViews();
- layout.setVisibility(View.INVISIBLE);
- }
-
- private Job<Void> mUpdateStorageInfoJob = new Job<Void>() {
- @Override
- public Void run(JobContext jc) {
- mCacheStorageInfo.loadStorageInfo(jc);
- if (!jc.isCancelled()) {
- mHandler.sendEmptyMessage(MSG_REFRESH_STORAGE_INFO);
- }
- return null;
- }
- };
-
- @Override
- public void onResume() {
- super.onResume();
- setContentPane(mRootPane);
- mAlbumSetDataAdapter.resume();
- mSelectionDrawer.resume();
- mEyePosition.resume();
- mUpdateStorageInfo = mActivity.getThreadPool().submit(mUpdateStorageInfoJob);
- FrameLayout layout = (FrameLayout) ((Activity) mActivity).findViewById(R.id.footer);
- layout.addView(mFooterContent);
- layout.setVisibility(View.VISIBLE);
- }
-
- private void initializeData(Bundle data) {
- String mediaPath = data.getString(ManageCachePage.KEY_MEDIA_PATH);
- mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
- mSelectionManager.setSourceMediaSet(mMediaSet);
-
- // We will always be in selection mode in this page.
- mSelectionManager.setAutoLeaveSelectionMode(false);
- mSelectionManager.enterSelectionMode();
-
- mAlbumSetDataAdapter = new AlbumSetDataLoader(
- mActivity, mMediaSet, DATA_CACHE_SIZE);
- mSelectionDrawer.setModel(mAlbumSetDataAdapter);
- }
-
- private void initializeViews() {
- Activity activity = mActivity;
-
- mSelectionManager = new SelectionManager(mActivity, true);
- mSelectionManager.setSelectionListener(this);
-
- Config.ManageCachePage config = Config.ManageCachePage.get(activity);
- mSlotView = new SlotView(mActivity, config.slotViewSpec);
- mSelectionDrawer = new ManageCacheDrawer(mActivity, mSelectionManager, mSlotView,
- config.labelSpec, config.cachePinSize, config.cachePinMargin);
- mSlotView.setSlotRenderer(mSelectionDrawer);
- mSlotView.setListener(new SlotView.SimpleListener() {
- @Override
- public void onDown(int index) {
- ManageCachePage.this.onDown(index);
- }
-
- @Override
- public void onUp(boolean followedByLongPress) {
- ManageCachePage.this.onUp();
- }
-
- @Override
- public void onSingleTapUp(int slotIndex) {
- ManageCachePage.this.onSingleTapUp(slotIndex);
- }
- });
- mRootPane.addComponent(mSlotView);
- initializeFooterViews();
- }
-
- private void initializeFooterViews() {
- Activity activity = mActivity;
-
- LayoutInflater inflater = activity.getLayoutInflater();
- mFooterContent = inflater.inflate(R.layout.manage_offline_bar, null);
-
- mFooterContent.findViewById(R.id.done).setOnClickListener(this);
- refreshCacheStorageInfo();
- }
-
- @Override
- public void onClick(View view) {
- Utils.assertTrue(view.getId() == R.id.done);
- GLRoot root = mActivity.getGLRoot();
- root.lockRenderThread();
- try {
- ArrayList<Path> ids = mSelectionManager.getSelected(false);
- if (ids.size() == 0) {
- onBackPressed();
- return;
- }
- showToast();
-
- MenuExecutor menuExecutor = new MenuExecutor(mActivity, mSelectionManager);
- menuExecutor.startAction(R.id.action_toggle_full_caching,
- R.string.process_caching_requests, this);
- } finally {
- root.unlockRenderThread();
- }
- }
-
- private void showToast() {
- if (mAlbumCountToMakeAvailableOffline > 0) {
- Activity activity = mActivity;
- Toast.makeText(activity, activity.getResources().getQuantityString(
- R.plurals.make_albums_available_offline,
- mAlbumCountToMakeAvailableOffline),
- Toast.LENGTH_SHORT).show();
- }
- }
-
- private void showToastForLocalAlbum() {
- Activity activity = mActivity;
- Toast.makeText(activity, activity.getResources().getString(
- R.string.try_to_set_local_album_available_offline),
- Toast.LENGTH_SHORT).show();
- }
-
- private void refreshCacheStorageInfo() {
- ProgressBar progressBar = (ProgressBar) mFooterContent.findViewById(R.id.progress);
- TextView status = (TextView) mFooterContent.findViewById(R.id.status);
- progressBar.setMax(PROGRESS_BAR_MAX);
- long totalBytes = mCacheStorageInfo.getTotalBytes();
- long usedBytes = mCacheStorageInfo.getUsedBytes();
- long expectedBytes = mCacheStorageInfo.getExpectedUsedBytes();
- long freeBytes = mCacheStorageInfo.getFreeBytes();
-
- Activity activity = mActivity;
- if (totalBytes == 0) {
- progressBar.setProgress(0);
- progressBar.setSecondaryProgress(0);
-
- // TODO: get the string translated
- String label = activity.getString(R.string.free_space_format, "-");
- status.setText(label);
- } else {
- progressBar.setProgress((int) (usedBytes * PROGRESS_BAR_MAX / totalBytes));
- progressBar.setSecondaryProgress(
- (int) (expectedBytes * PROGRESS_BAR_MAX / totalBytes));
- String label = activity.getString(R.string.free_space_format,
- Formatter.formatFileSize(activity, freeBytes));
- status.setText(label);
- }
- }
-
- @Override
- public void onProgressComplete(int result) {
- onBackPressed();
- }
-
- @Override
- public void onProgressUpdate(int index) {
- }
-
- @Override
- public void onSelectionModeChange(int mode) {
- }
-
- @Override
- public void onSelectionChange(Path path, boolean selected) {
- }
-
- @Override
- public void onConfirmDialogDismissed(boolean confirmed) {
- }
-
- @Override
- public void onConfirmDialogShown() {
- }
-
- @Override
- public void onProgressStart() {
- }
-}
diff --git a/src/com/android/gallery3d/app/MovieActivity.java b/src/com/android/gallery3d/app/MovieActivity.java
deleted file mode 100644
index 40edbbe4d..000000000
--- a/src/com/android/gallery3d/app/MovieActivity.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2007 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.app;
-
-import android.annotation.TargetApi;
-import android.app.ActionBar;
-import android.app.Activity;
-import android.content.AsyncQueryHandler;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.provider.MediaStore;
-import android.provider.OpenableColumns;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.ShareActionProvider;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.common.Utils;
-
-/**
- * This activity plays a video from a specified URI.
- *
- * The client of this activity can pass a logo bitmap in the intent (KEY_LOGO_BITMAP)
- * to set the action bar logo so the playback process looks more seamlessly integrated with
- * the original activity.
- */
-public class MovieActivity extends Activity {
- @SuppressWarnings("unused")
- private static final String TAG = "MovieActivity";
- public static final String KEY_LOGO_BITMAP = "logo-bitmap";
- public static final String KEY_TREAT_UP_AS_BACK = "treat-up-as-back";
-
- private MoviePlayer mPlayer;
- private boolean mFinishOnCompletion;
- private Uri mUri;
- private boolean mTreatUpAsBack;
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private void setSystemUiVisibility(View rootView) {
- if (ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE) {
- rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- requestWindowFeature(Window.FEATURE_ACTION_BAR);
- requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
-
- setContentView(R.layout.movie_view);
- View rootView = findViewById(R.id.movie_view_root);
-
- setSystemUiVisibility(rootView);
-
- Intent intent = getIntent();
- initializeActionBar(intent);
- mFinishOnCompletion = intent.getBooleanExtra(
- MediaStore.EXTRA_FINISH_ON_COMPLETION, true);
- mTreatUpAsBack = intent.getBooleanExtra(KEY_TREAT_UP_AS_BACK, false);
- mPlayer = new MoviePlayer(rootView, this, intent.getData(), savedInstanceState,
- !mFinishOnCompletion) {
- @Override
- public void onCompletion() {
- if (mFinishOnCompletion) {
- finish();
- }
- }
- };
- if (intent.hasExtra(MediaStore.EXTRA_SCREEN_ORIENTATION)) {
- int orientation = intent.getIntExtra(
- MediaStore.EXTRA_SCREEN_ORIENTATION,
- ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- if (orientation != getRequestedOrientation()) {
- setRequestedOrientation(orientation);
- }
- }
- Window win = getWindow();
- WindowManager.LayoutParams winParams = win.getAttributes();
- winParams.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
- winParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
- win.setAttributes(winParams);
-
- // We set the background in the theme to have the launching animation.
- // But for the performance (and battery), we remove the background here.
- win.setBackgroundDrawable(null);
- }
-
- private void setActionBarLogoFromIntent(Intent intent) {
- Bitmap logo = intent.getParcelableExtra(KEY_LOGO_BITMAP);
- if (logo != null) {
- getActionBar().setLogo(
- new BitmapDrawable(getResources(), logo));
- }
- }
-
- private void initializeActionBar(Intent intent) {
- mUri = intent.getData();
- final ActionBar actionBar = getActionBar();
- if (actionBar == null) {
- return;
- }
- setActionBarLogoFromIntent(intent);
- actionBar.setDisplayOptions(
- ActionBar.DISPLAY_HOME_AS_UP,
- ActionBar.DISPLAY_HOME_AS_UP);
-
- String title = intent.getStringExtra(Intent.EXTRA_TITLE);
- if (title != null) {
- actionBar.setTitle(title);
- } else {
- // Displays the filename as title, reading the filename from the
- // interface: {@link android.provider.OpenableColumns#DISPLAY_NAME}.
- AsyncQueryHandler queryHandler =
- new AsyncQueryHandler(getContentResolver()) {
- @Override
- protected void onQueryComplete(int token, Object cookie,
- Cursor cursor) {
- try {
- if ((cursor != null) && cursor.moveToFirst()) {
- String displayName = cursor.getString(0);
-
- // Just show empty title if other apps don't set
- // DISPLAY_NAME
- actionBar.setTitle((displayName == null) ? "" :
- displayName);
- }
- } finally {
- Utils.closeSilently(cursor);
- }
- }
- };
- queryHandler.startQuery(0, null, mUri,
- new String[] {OpenableColumns.DISPLAY_NAME}, null, null,
- null);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- getMenuInflater().inflate(R.menu.movie, menu);
-
- // Document says EXTRA_STREAM should be a content: Uri
- // So, we only share the video if it's "content:".
- MenuItem shareItem = menu.findItem(R.id.action_share);
- if (ContentResolver.SCHEME_CONTENT.equals(mUri.getScheme())) {
- shareItem.setVisible(true);
- ((ShareActionProvider) shareItem.getActionProvider())
- .setShareIntent(createShareIntent());
- } else {
- shareItem.setVisible(false);
- }
- return true;
- }
-
- private Intent createShareIntent() {
- Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("video/*");
- intent.putExtra(Intent.EXTRA_STREAM, mUri);
- return intent;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int id = item.getItemId();
- if (id == android.R.id.home) {
- if (mTreatUpAsBack) {
- finish();
- } else {
- startActivity(new Intent(this, Gallery.class));
- finish();
- }
- return true;
- } else if (id == R.id.action_share) {
- startActivity(Intent.createChooser(createShareIntent(),
- getString(R.string.share)));
- return true;
- }
- return false;
- }
-
- @Override
- public void onStart() {
- ((AudioManager) getSystemService(AUDIO_SERVICE))
- .requestAudioFocus(null, AudioManager.STREAM_MUSIC,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
- super.onStart();
- }
-
- @Override
- protected void onStop() {
- ((AudioManager) getSystemService(AUDIO_SERVICE))
- .abandonAudioFocus(null);
- super.onStop();
- }
-
- @Override
- public void onPause() {
- mPlayer.onPause();
- super.onPause();
- }
-
- @Override
- public void onResume() {
- mPlayer.onResume();
- super.onResume();
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mPlayer.onSaveInstanceState(outState);
- }
-
- @Override
- public void onDestroy() {
- mPlayer.onDestroy();
- super.onDestroy();
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- return mPlayer.onKeyDown(keyCode, event)
- || super.onKeyDown(keyCode, event);
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- return mPlayer.onKeyUp(keyCode, event)
- || super.onKeyUp(keyCode, event);
- }
-}
diff --git a/src/com/android/gallery3d/app/MovieControllerOverlay.java b/src/com/android/gallery3d/app/MovieControllerOverlay.java
deleted file mode 100644
index f01e619c6..000000000
--- a/src/com/android/gallery3d/app/MovieControllerOverlay.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2011 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.app;
-
-import android.content.Context;
-import android.os.Handler;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.animation.Animation;
-import android.view.animation.Animation.AnimationListener;
-import android.view.animation.AnimationUtils;
-import com.android.gallery3d.R;
-
-/**
- * The playback controller for the Movie Player.
- */
-public class MovieControllerOverlay extends CommonControllerOverlay implements
- AnimationListener {
-
- private boolean hidden;
-
- private final Handler handler;
- private final Runnable startHidingRunnable;
- private final Animation hideAnimation;
-
- public MovieControllerOverlay(Context context) {
- super(context);
-
- handler = new Handler();
- startHidingRunnable = new Runnable() {
- @Override
- public void run() {
- startHiding();
- }
- };
-
- hideAnimation = AnimationUtils.loadAnimation(context, R.anim.player_out);
- hideAnimation.setAnimationListener(this);
-
- hide();
- }
-
- @Override
- protected void createTimeBar(Context context) {
- mTimeBar = new TimeBar(context, this);
- }
-
- @Override
- public void hide() {
- boolean wasHidden = hidden;
- hidden = true;
- super.hide();
- if (mListener != null && wasHidden != hidden) {
- mListener.onHidden();
- }
- }
-
-
- @Override
- public void show() {
- boolean wasHidden = hidden;
- hidden = false;
- super.show();
- if (mListener != null && wasHidden != hidden) {
- mListener.onShown();
- }
- maybeStartHiding();
- }
-
- private void maybeStartHiding() {
- cancelHiding();
- if (mState == State.PLAYING) {
- handler.postDelayed(startHidingRunnable, 2500);
- }
- }
-
- private void startHiding() {
- startHideAnimation(mBackground);
- startHideAnimation(mTimeBar);
- startHideAnimation(mPlayPauseReplayView);
- }
-
- private void startHideAnimation(View view) {
- if (view.getVisibility() == View.VISIBLE) {
- view.startAnimation(hideAnimation);
- }
- }
-
- private void cancelHiding() {
- handler.removeCallbacks(startHidingRunnable);
- mBackground.setAnimation(null);
- mTimeBar.setAnimation(null);
- mPlayPauseReplayView.setAnimation(null);
- }
-
- @Override
- public void onAnimationStart(Animation animation) {
- // Do nothing.
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
- // Do nothing.
- }
-
- @Override
- public void onAnimationEnd(Animation animation) {
- hide();
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (hidden) {
- show();
- }
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (super.onTouchEvent(event)) {
- return true;
- }
-
- if (hidden) {
- show();
- return true;
- }
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- cancelHiding();
- if (mState == State.PLAYING || mState == State.PAUSED) {
- mListener.onPlayPause();
- }
- break;
- case MotionEvent.ACTION_UP:
- maybeStartHiding();
- break;
- }
- return true;
- }
-
- @Override
- protected void updateViews() {
- if (hidden) {
- return;
- }
- super.updateViews();
- }
-
- // TimeBar listener
-
- @Override
- public void onScrubbingStart() {
- cancelHiding();
- super.onScrubbingStart();
- }
-
- @Override
- public void onScrubbingMove(int time) {
- cancelHiding();
- super.onScrubbingMove(time);
- }
-
- @Override
- public void onScrubbingEnd(int time, int trimStartTime, int trimEndTime) {
- maybeStartHiding();
- super.onScrubbingEnd(time, trimStartTime, trimEndTime);
- }
-}
diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java
deleted file mode 100644
index ce9183483..000000000
--- a/src/com/android/gallery3d/app/MoviePlayer.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2009 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.app;
-
-import android.annotation.TargetApi;
-import android.app.AlertDialog;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.VideoView;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.common.BlobCache;
-import com.android.gallery3d.util.CacheManager;
-import com.android.gallery3d.util.GalleryUtils;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-
-public class MoviePlayer implements
- MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener,
- ControllerOverlay.Listener {
- @SuppressWarnings("unused")
- private static final String TAG = "MoviePlayer";
-
- private static final String KEY_VIDEO_POSITION = "video-position";
- private static final String KEY_RESUMEABLE_TIME = "resumeable-timeout";
-
- // These are constants in KeyEvent, appearing on API level 11.
- private static final int KEYCODE_MEDIA_PLAY = 126;
- private static final int KEYCODE_MEDIA_PAUSE = 127;
-
- // Copied from MediaPlaybackService in the Music Player app.
- private static final String SERVICECMD = "com.android.music.musicservicecommand";
- private static final String CMDNAME = "command";
- private static final String CMDPAUSE = "pause";
-
- private static final long BLACK_TIMEOUT = 500;
-
- // If we resume the acitivty with in RESUMEABLE_TIMEOUT, we will keep playing.
- // Otherwise, we pause the player.
- private static final long RESUMEABLE_TIMEOUT = 3 * 60 * 1000; // 3 mins
-
- private Context mContext;
- private final VideoView mVideoView;
- private final View mRootView;
- private final Bookmarker mBookmarker;
- private final Uri mUri;
- private final Handler mHandler = new Handler();
- private final AudioBecomingNoisyReceiver mAudioBecomingNoisyReceiver;
- private final MovieControllerOverlay mController;
-
- private long mResumeableTime = Long.MAX_VALUE;
- private int mVideoPosition = 0;
- private boolean mHasPaused = false;
- private int mLastSystemUiVis = 0;
-
- // If the time bar is being dragged.
- private boolean mDragging;
-
- // If the time bar is visible.
- private boolean mShowing;
-
- private final Runnable mPlayingChecker = new Runnable() {
- @Override
- public void run() {
- if (mVideoView.isPlaying()) {
- mController.showPlaying();
- } else {
- mHandler.postDelayed(mPlayingChecker, 250);
- }
- }
- };
-
- private final Runnable mProgressChecker = new Runnable() {
- @Override
- public void run() {
- int pos = setProgress();
- mHandler.postDelayed(mProgressChecker, 1000 - (pos % 1000));
- }
- };
-
- public MoviePlayer(View rootView, final MovieActivity movieActivity,
- Uri videoUri, Bundle savedInstance, boolean canReplay) {
- mContext = movieActivity.getApplicationContext();
- mRootView = rootView;
- mVideoView = (VideoView) rootView.findViewById(R.id.surface_view);
- mBookmarker = new Bookmarker(movieActivity);
- mUri = videoUri;
-
- mController = new MovieControllerOverlay(mContext);
- ((ViewGroup)rootView).addView(mController.getView());
- mController.setListener(this);
- mController.setCanReplay(canReplay);
-
- mVideoView.setOnErrorListener(this);
- mVideoView.setOnCompletionListener(this);
- mVideoView.setVideoURI(mUri);
- mVideoView.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- mController.show();
- return true;
- }
- });
- mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
- @Override
- public void onPrepared(MediaPlayer player) {
- if (!mVideoView.canSeekForward() || !mVideoView.canSeekBackward()) {
- mController.setSeekable(false);
- } else {
- mController.setSeekable(true);
- }
- setProgress();
- }
- });
-
- // The SurfaceView is transparent before drawing the first frame.
- // This makes the UI flashing when open a video. (black -> old screen
- // -> video) However, we have no way to know the timing of the first
- // frame. So, we hide the VideoView for a while to make sure the
- // video has been drawn on it.
- mVideoView.postDelayed(new Runnable() {
- @Override
- public void run() {
- mVideoView.setVisibility(View.VISIBLE);
- }
- }, BLACK_TIMEOUT);
-
- setOnSystemUiVisibilityChangeListener();
- // Hide system UI by default
- showSystemUi(false);
-
- mAudioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver();
- mAudioBecomingNoisyReceiver.register();
-
- Intent i = new Intent(SERVICECMD);
- i.putExtra(CMDNAME, CMDPAUSE);
- movieActivity.sendBroadcast(i);
-
- if (savedInstance != null) { // this is a resumed activity
- mVideoPosition = savedInstance.getInt(KEY_VIDEO_POSITION, 0);
- mResumeableTime = savedInstance.getLong(KEY_RESUMEABLE_TIME, Long.MAX_VALUE);
- mVideoView.start();
- mVideoView.suspend();
- mHasPaused = true;
- } else {
- final Integer bookmark = mBookmarker.getBookmark(mUri);
- if (bookmark != null) {
- showResumeDialog(movieActivity, bookmark);
- } else {
- startVideo();
- }
- }
- }
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private void setOnSystemUiVisibilityChangeListener() {
- if (!ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_HIDE_NAVIGATION) return;
-
- // When the user touches the screen or uses some hard key, the framework
- // will change system ui visibility from invisible to visible. We show
- // the media control and enable system UI (e.g. ActionBar) to be visible at this point
- mVideoView.setOnSystemUiVisibilityChangeListener(
- new View.OnSystemUiVisibilityChangeListener() {
- @Override
- public void onSystemUiVisibilityChange(int visibility) {
- int diff = mLastSystemUiVis ^ visibility;
- mLastSystemUiVis = visibility;
- if ((diff & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
- && (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
- mController.show();
- }
- }
- });
- }
-
- @SuppressWarnings("deprecation")
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private void showSystemUi(boolean visible) {
- if (!ApiHelper.HAS_VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE) return;
-
- int flag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
- if (!visible) {
- // We used the deprecated "STATUS_BAR_HIDDEN" for unbundling
- flag |= View.STATUS_BAR_HIDDEN | View.SYSTEM_UI_FLAG_FULLSCREEN
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
- }
- mVideoView.setSystemUiVisibility(flag);
- }
-
- public void onSaveInstanceState(Bundle outState) {
- outState.putInt(KEY_VIDEO_POSITION, mVideoPosition);
- outState.putLong(KEY_RESUMEABLE_TIME, mResumeableTime);
- }
-
- private void showResumeDialog(Context context, final int bookmark) {
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.resume_playing_title);
- builder.setMessage(String.format(
- context.getString(R.string.resume_playing_message),
- GalleryUtils.formatDuration(context, bookmark / 1000)));
- builder.setOnCancelListener(new OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- onCompletion();
- }
- });
- builder.setPositiveButton(
- R.string.resume_playing_resume, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mVideoView.seekTo(bookmark);
- startVideo();
- }
- });
- builder.setNegativeButton(
- R.string.resume_playing_restart, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- startVideo();
- }
- });
- builder.show();
- }
-
- public void onPause() {
- mHasPaused = true;
- mHandler.removeCallbacksAndMessages(null);
- mVideoPosition = mVideoView.getCurrentPosition();
- mBookmarker.setBookmark(mUri, mVideoPosition, mVideoView.getDuration());
- mVideoView.suspend();
- mResumeableTime = System.currentTimeMillis() + RESUMEABLE_TIMEOUT;
- }
-
- public void onResume() {
- if (mHasPaused) {
- mVideoView.seekTo(mVideoPosition);
- mVideoView.resume();
-
- // If we have slept for too long, pause the play
- if (System.currentTimeMillis() > mResumeableTime) {
- pauseVideo();
- }
- }
- mHandler.post(mProgressChecker);
- }
-
- public void onDestroy() {
- mVideoView.stopPlayback();
- mAudioBecomingNoisyReceiver.unregister();
- }
-
- // This updates the time bar display (if necessary). It is called every
- // second by mProgressChecker and also from places where the time bar needs
- // to be updated immediately.
- private int setProgress() {
- if (mDragging || !mShowing) {
- return 0;
- }
- int position = mVideoView.getCurrentPosition();
- int duration = mVideoView.getDuration();
- mController.setTimes(position, duration, 0, 0);
- return position;
- }
-
- private void startVideo() {
- // For streams that we expect to be slow to start up, show a
- // progress spinner until playback starts.
- String scheme = mUri.getScheme();
- if ("http".equalsIgnoreCase(scheme) || "rtsp".equalsIgnoreCase(scheme)) {
- mController.showLoading();
- mHandler.removeCallbacks(mPlayingChecker);
- mHandler.postDelayed(mPlayingChecker, 250);
- } else {
- mController.showPlaying();
- mController.hide();
- }
-
- mVideoView.start();
- setProgress();
- }
-
- private void playVideo() {
- mVideoView.start();
- mController.showPlaying();
- setProgress();
- }
-
- private void pauseVideo() {
- mVideoView.pause();
- mController.showPaused();
- }
-
- // Below are notifications from VideoView
- @Override
- public boolean onError(MediaPlayer player, int arg1, int arg2) {
- mHandler.removeCallbacksAndMessages(null);
- // VideoView will show an error dialog if we return false, so no need
- // to show more message.
- mController.showErrorMessage("");
- return false;
- }
-
- @Override
- public void onCompletion(MediaPlayer mp) {
- mController.showEnded();
- onCompletion();
- }
-
- public void onCompletion() {
- }
-
- // Below are notifications from ControllerOverlay
- @Override
- public void onPlayPause() {
- if (mVideoView.isPlaying()) {
- pauseVideo();
- } else {
- playVideo();
- }
- }
-
- @Override
- public void onSeekStart() {
- mDragging = true;
- }
-
- @Override
- public void onSeekMove(int time) {
- mVideoView.seekTo(time);
- }
-
- @Override
- public void onSeekEnd(int time, int start, int end) {
- mDragging = false;
- mVideoView.seekTo(time);
- setProgress();
- }
-
- @Override
- public void onShown() {
- mShowing = true;
- setProgress();
- showSystemUi(true);
- }
-
- @Override
- public void onHidden() {
- mShowing = false;
- showSystemUi(false);
- }
-
- @Override
- public void onReplay() {
- startVideo();
- }
-
- // Below are key events passed from MovieActivity.
- public boolean onKeyDown(int keyCode, KeyEvent event) {
-
- // Some headsets will fire off 7-10 events on a single click
- if (event.getRepeatCount() > 0) {
- return isMediaKey(keyCode);
- }
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_HEADSETHOOK:
- case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
- if (mVideoView.isPlaying()) {
- pauseVideo();
- } else {
- playVideo();
- }
- return true;
- case KEYCODE_MEDIA_PAUSE:
- if (mVideoView.isPlaying()) {
- pauseVideo();
- }
- return true;
- case KEYCODE_MEDIA_PLAY:
- if (!mVideoView.isPlaying()) {
- playVideo();
- }
- return true;
- case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
- case KeyEvent.KEYCODE_MEDIA_NEXT:
- // TODO: Handle next / previous accordingly, for now we're
- // just consuming the events.
- return true;
- }
- return false;
- }
-
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- return isMediaKey(keyCode);
- }
-
- private static boolean isMediaKey(int keyCode) {
- return keyCode == KeyEvent.KEYCODE_HEADSETHOOK
- || keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS
- || keyCode == KeyEvent.KEYCODE_MEDIA_NEXT
- || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
- || keyCode == KeyEvent.KEYCODE_MEDIA_PLAY
- || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE;
- }
-
- // We want to pause when the headset is unplugged.
- private class AudioBecomingNoisyReceiver extends BroadcastReceiver {
-
- public void register() {
- mContext.registerReceiver(this,
- new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
- }
-
- public void unregister() {
- mContext.unregisterReceiver(this);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (mVideoView.isPlaying()) pauseVideo();
- }
- }
-}
-
-class Bookmarker {
- private static final String TAG = "Bookmarker";
-
- private static final String BOOKMARK_CACHE_FILE = "bookmark";
- private static final int BOOKMARK_CACHE_MAX_ENTRIES = 100;
- private static final int BOOKMARK_CACHE_MAX_BYTES = 10 * 1024;
- private static final int BOOKMARK_CACHE_VERSION = 1;
-
- private static final int HALF_MINUTE = 30 * 1000;
- private static final int TWO_MINUTES = 4 * HALF_MINUTE;
-
- private final Context mContext;
-
- public Bookmarker(Context context) {
- mContext = context;
- }
-
- public void setBookmark(Uri uri, int bookmark, int duration) {
- try {
- BlobCache cache = CacheManager.getCache(mContext,
- BOOKMARK_CACHE_FILE, BOOKMARK_CACHE_MAX_ENTRIES,
- BOOKMARK_CACHE_MAX_BYTES, BOOKMARK_CACHE_VERSION);
-
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(bos);
- dos.writeUTF(uri.toString());
- dos.writeInt(bookmark);
- dos.writeInt(duration);
- dos.flush();
- cache.insert(uri.hashCode(), bos.toByteArray());
- } catch (Throwable t) {
- Log.w(TAG, "setBookmark failed", t);
- }
- }
-
- public Integer getBookmark(Uri uri) {
- try {
- BlobCache cache = CacheManager.getCache(mContext,
- BOOKMARK_CACHE_FILE, BOOKMARK_CACHE_MAX_ENTRIES,
- BOOKMARK_CACHE_MAX_BYTES, BOOKMARK_CACHE_VERSION);
-
- byte[] data = cache.lookup(uri.hashCode());
- if (data == null) return null;
-
- DataInputStream dis = new DataInputStream(
- new ByteArrayInputStream(data));
-
- String uriString = DataInputStream.readUTF(dis);
- int bookmark = dis.readInt();
- int duration = dis.readInt();
-
- if (!uriString.equals(uri.toString())) {
- return null;
- }
-
- if ((bookmark < HALF_MINUTE) || (duration < TWO_MINUTES)
- || (bookmark > (duration - HALF_MINUTE))) {
- return null;
- }
- return Integer.valueOf(bookmark);
- } catch (Throwable t) {
- Log.w(TAG, "getBookmark failed", t);
- }
- return null;
- }
-}
diff --git a/src/com/android/gallery3d/app/MuteVideo.java b/src/com/android/gallery3d/app/MuteVideo.java
deleted file mode 100644
index d3f3aa594..000000000
--- a/src/com/android/gallery3d/app/MuteVideo.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.MediaStore;
-import android.widget.Toast;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.util.SaveVideoFileInfo;
-import com.android.gallery3d.util.SaveVideoFileUtils;
-
-import java.io.IOException;
-
-public class MuteVideo {
-
- private ProgressDialog mMuteProgress;
-
- private String mFilePath = null;
- private Uri mUri = null;
- private SaveVideoFileInfo mDstFileInfo = null;
- private Activity mActivity = null;
- private final Handler mHandler = new Handler();
-
- final String TIME_STAMP_NAME = "'MUTE'_yyyyMMdd_HHmmss";
-
- public MuteVideo(String filePath, Uri uri, Activity activity) {
- mUri = uri;
- mFilePath = filePath;
- mActivity = activity;
- }
-
- public void muteInBackground() {
- mDstFileInfo = SaveVideoFileUtils.getDstMp4FileInfo(TIME_STAMP_NAME,
- mActivity.getContentResolver(), mUri,
- mActivity.getString(R.string.folder_download));
-
- showProgressDialog();
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- VideoUtils.startMute(mFilePath, mDstFileInfo);
- SaveVideoFileUtils.insertContent(
- mDstFileInfo, mActivity.getContentResolver(), mUri);
- } catch (IOException e) {
- Toast.makeText(mActivity, mActivity.getString(R.string.video_mute_err),
- Toast.LENGTH_SHORT).show();
- }
- // After muting is done, trigger the UI changed.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(mActivity.getApplicationContext(),
- mActivity.getString(R.string.save_into,
- mDstFileInfo.mFolderName),
- Toast.LENGTH_SHORT)
- .show();
-
- if (mMuteProgress != null) {
- mMuteProgress.dismiss();
- mMuteProgress = null;
-
- // Show the result only when the activity not
- // stopped.
- Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
- intent.setDataAndType(Uri.fromFile(mDstFileInfo.mFile), "video/*");
- intent.putExtra(MediaStore.EXTRA_FINISH_ON_COMPLETION, false);
- mActivity.startActivity(intent);
- }
- }
- });
- }
- }).start();
- }
-
- private void showProgressDialog() {
- mMuteProgress = new ProgressDialog(mActivity);
- mMuteProgress.setTitle(mActivity.getString(R.string.muting));
- mMuteProgress.setMessage(mActivity.getString(R.string.please_wait));
- mMuteProgress.setCancelable(false);
- mMuteProgress.setCanceledOnTouchOutside(false);
- mMuteProgress.show();
- }
-}
diff --git a/src/com/android/gallery3d/app/NotificationIds.java b/src/com/android/gallery3d/app/NotificationIds.java
deleted file mode 100644
index d697d854b..000000000
--- a/src/com/android/gallery3d/app/NotificationIds.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2013 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.app;
-
-public class NotificationIds {
- public static final int INGEST_NOTIFICATION_SCANNING = 10;
- public static final int INGEST_NOTIFICATION_IMPORTING = 11;
-}
diff --git a/src/com/android/gallery3d/app/OrientationManager.java b/src/com/android/gallery3d/app/OrientationManager.java
deleted file mode 100644
index f2f632c9f..000000000
--- a/src/com/android/gallery3d/app/OrientationManager.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.provider.Settings;
-import android.view.OrientationEventListener;
-import android.view.Surface;
-
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.ui.OrientationSource;
-
-public class OrientationManager implements OrientationSource {
- private static final String TAG = "OrientationManager";
-
- // Orientation hysteresis amount used in rounding, in degrees
- private static final int ORIENTATION_HYSTERESIS = 5;
-
- private Activity mActivity;
- private MyOrientationEventListener mOrientationListener;
- // If the framework orientation is locked.
- private boolean mOrientationLocked = false;
-
- // This is true if "Settings -> Display -> Rotation Lock" is checked. We
- // don't allow the orientation to be unlocked if the value is true.
- private boolean mRotationLockedSetting = false;
-
- public OrientationManager(Activity activity) {
- mActivity = activity;
- mOrientationListener = new MyOrientationEventListener(activity);
- }
-
- public void resume() {
- ContentResolver resolver = mActivity.getContentResolver();
- mRotationLockedSetting = Settings.System.getInt(
- resolver, Settings.System.ACCELEROMETER_ROTATION, 0) != 1;
- mOrientationListener.enable();
- }
-
- public void pause() {
- mOrientationListener.disable();
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // Orientation handling
- //
- // We can choose to lock the framework orientation or not. If we lock the
- // framework orientation, we calculate a a compensation value according to
- // current device orientation and send it to listeners. If we don't lock
- // the framework orientation, we always set the compensation value to 0.
- ////////////////////////////////////////////////////////////////////////////
-
- // Lock the framework orientation to the current device orientation
- public void lockOrientation() {
- if (mOrientationLocked) return;
- mOrientationLocked = true;
- if (ApiHelper.HAS_ORIENTATION_LOCK) {
- mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
- } else {
- mActivity.setRequestedOrientation(calculateCurrentScreenOrientation());
- }
- }
-
- // Unlock the framework orientation, so it can change when the device
- // rotates.
- public void unlockOrientation() {
- if (!mOrientationLocked) return;
- mOrientationLocked = false;
- Log.d(TAG, "unlock orientation");
- mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
- }
-
- private int calculateCurrentScreenOrientation() {
- int displayRotation = getDisplayRotation();
- // Display rotation >= 180 means we need to use the REVERSE landscape/portrait
- boolean standard = displayRotation < 180;
- if (mActivity.getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE) {
- return standard
- ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
- : ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
- } else {
- if (displayRotation == 90 || displayRotation == 270) {
- // If displayRotation = 90 or 270 then we are on a landscape
- // device. On landscape devices, portrait is a 90 degree
- // clockwise rotation from landscape, so we need
- // to flip which portrait we pick as display rotation is counter clockwise
- standard = !standard;
- }
- return standard
- ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
- : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
- }
- }
-
- // This listens to the device orientation, so we can update the compensation.
- private class MyOrientationEventListener extends OrientationEventListener {
- public MyOrientationEventListener(Context context) {
- super(context);
- }
-
- @Override
- public void onOrientationChanged(int orientation) {
- // We keep the last known orientation. So if the user first orient
- // the camera then point the camera to floor or sky, we still have
- // the correct orientation.
- if (orientation == ORIENTATION_UNKNOWN) return;
- orientation = roundOrientation(orientation, 0);
- }
- }
-
- @Override
- public int getDisplayRotation() {
- return getDisplayRotation(mActivity);
- }
-
- @Override
- public int getCompensation() {
- return 0;
- }
-
- private static int roundOrientation(int orientation, int orientationHistory) {
- boolean changeOrientation = false;
- if (orientationHistory == OrientationEventListener.ORIENTATION_UNKNOWN) {
- changeOrientation = true;
- } else {
- int dist = Math.abs(orientation - orientationHistory);
- dist = Math.min(dist, 360 - dist);
- changeOrientation = (dist >= 45 + ORIENTATION_HYSTERESIS);
- }
- if (changeOrientation) {
- return ((orientation + 45) / 90 * 90) % 360;
- }
- return orientationHistory;
- }
-
- private static int getDisplayRotation(Activity activity) {
- int rotation = activity.getWindowManager().getDefaultDisplay()
- .getRotation();
- switch (rotation) {
- case Surface.ROTATION_0: return 0;
- case Surface.ROTATION_90: return 90;
- case Surface.ROTATION_180: return 180;
- case Surface.ROTATION_270: return 270;
- }
- return 0;
- }
-}
diff --git a/src/com/android/gallery3d/app/PackagesMonitor.java b/src/com/android/gallery3d/app/PackagesMonitor.java
deleted file mode 100644
index 9b2412f1b..000000000
--- a/src/com/android/gallery3d/app/PackagesMonitor.java
+++ /dev/null
@@ -1,71 +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.app;
-
-import android.app.IntentService;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
-import com.android.gallery3d.picasasource.PicasaSource;
-import com.android.gallery3d.util.LightCycleHelper;
-
-public class PackagesMonitor extends BroadcastReceiver {
- public static final String KEY_PACKAGES_VERSION = "packages-version";
-
- public synchronized static int getPackagesVersion(Context context) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- return prefs.getInt(KEY_PACKAGES_VERSION, 1);
- }
-
- @Override
- public void onReceive(final Context context, final Intent intent) {
- intent.setClass(context, AsyncService.class);
- context.startService(intent);
- }
-
- public static class AsyncService extends IntentService {
- public AsyncService() {
- super("GalleryPackagesMonitorAsync");
- }
-
- @Override
- protected void onHandleIntent(Intent intent) {
- onReceiveAsync(this, intent);
- }
- }
-
- // Runs in a background thread.
- private static void onReceiveAsync(Context context, Intent intent) {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-
- int version = prefs.getInt(KEY_PACKAGES_VERSION, 1);
- prefs.edit().putInt(KEY_PACKAGES_VERSION, version + 1).commit();
-
- String action = intent.getAction();
- String packageName = intent.getData().getSchemeSpecificPart();
- if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
- PicasaSource.onPackageAdded(context, packageName);
- } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
- PicasaSource.onPackageRemoved(context, packageName);
- } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
- PicasaSource.onPackageChanged(context, packageName);
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/PanoramaMetadataSupport.java b/src/com/android/gallery3d/app/PanoramaMetadataSupport.java
deleted file mode 100644
index ba0c9e71a..000000000
--- a/src/com/android/gallery3d/app/PanoramaMetadataSupport.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaObject.PanoramaSupportCallback;
-import com.android.gallery3d.data.PanoramaMetadataJob;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.FutureListener;
-import com.android.gallery3d.util.LightCycleHelper;
-import com.android.gallery3d.util.LightCycleHelper.PanoramaMetadata;
-
-import java.util.ArrayList;
-
-/**
- * This class breaks out the off-thread panorama support checks so that the
- * complexity can be shared between UriImage and LocalImage, which need to
- * support panoramas.
- */
-public class PanoramaMetadataSupport implements FutureListener<PanoramaMetadata> {
- private Object mLock = new Object();
- private Future<PanoramaMetadata> mGetPanoMetadataTask;
- private PanoramaMetadata mPanoramaMetadata;
- private ArrayList<PanoramaSupportCallback> mCallbacksWaiting;
- private MediaObject mMediaObject;
-
- public PanoramaMetadataSupport(MediaObject mediaObject) {
- mMediaObject = mediaObject;
- }
-
- public void getPanoramaSupport(GalleryApp app, PanoramaSupportCallback callback) {
- synchronized (mLock) {
- if (mPanoramaMetadata != null) {
- callback.panoramaInfoAvailable(mMediaObject, mPanoramaMetadata.mUsePanoramaViewer,
- mPanoramaMetadata.mIsPanorama360);
- } else {
- if (mCallbacksWaiting == null) {
- mCallbacksWaiting = new ArrayList<PanoramaSupportCallback>();
- mGetPanoMetadataTask = app.getThreadPool().submit(
- new PanoramaMetadataJob(app.getAndroidContext(),
- mMediaObject.getContentUri()), this);
-
- }
- mCallbacksWaiting.add(callback);
- }
- }
- }
-
- public void clearCachedValues() {
- synchronized (mLock) {
- if (mPanoramaMetadata != null) {
- mPanoramaMetadata = null;
- } else if (mGetPanoMetadataTask != null) {
- mGetPanoMetadataTask.cancel();
- for (PanoramaSupportCallback cb : mCallbacksWaiting) {
- cb.panoramaInfoAvailable(mMediaObject, false, false);
- }
- mGetPanoMetadataTask = null;
- mCallbacksWaiting = null;
- }
- }
- }
-
- @Override
- public void onFutureDone(Future<PanoramaMetadata> future) {
- synchronized (mLock) {
- mPanoramaMetadata = future.get();
- if (mPanoramaMetadata == null) {
- // Error getting panorama data from file. Treat as not panorama.
- mPanoramaMetadata = LightCycleHelper.NOT_PANORAMA;
- }
- for (PanoramaSupportCallback cb : mCallbacksWaiting) {
- cb.panoramaInfoAvailable(mMediaObject, mPanoramaMetadata.mUsePanoramaViewer,
- mPanoramaMetadata.mIsPanorama360);
- }
- mGetPanoMetadataTask = null;
- mCallbacksWaiting = null;
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/PhotoDataAdapter.java b/src/com/android/gallery3d/app/PhotoDataAdapter.java
deleted file mode 100644
index fd3a7cf73..000000000
--- a/src/com/android/gallery3d/app/PhotoDataAdapter.java
+++ /dev/null
@@ -1,1133 +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.app;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapRegionDecoder;
-import android.os.Handler;
-import android.os.Message;
-
-import com.android.gallery3d.common.BitmapUtils;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.ContentListener;
-import com.android.gallery3d.data.LocalMediaItem;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.glrenderer.TiledTexture;
-import com.android.gallery3d.ui.PhotoView;
-import com.android.gallery3d.ui.ScreenNail;
-import com.android.gallery3d.ui.SynchronizedHandler;
-import com.android.gallery3d.ui.TileImageViewAdapter;
-import com.android.gallery3d.ui.TiledScreenNail;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.FutureListener;
-import com.android.gallery3d.util.MediaSetUtils;
-import com.android.gallery3d.util.ThreadPool;
-import com.android.gallery3d.util.ThreadPool.Job;
-import com.android.gallery3d.util.ThreadPool.JobContext;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-
-public class PhotoDataAdapter implements PhotoPage.Model {
- @SuppressWarnings("unused")
- private static final String TAG = "PhotoDataAdapter";
-
- private static final int MSG_LOAD_START = 1;
- private static final int MSG_LOAD_FINISH = 2;
- private static final int MSG_RUN_OBJECT = 3;
- private static final int MSG_UPDATE_IMAGE_REQUESTS = 4;
-
- private static final int MIN_LOAD_COUNT = 16;
- private static final int DATA_CACHE_SIZE = 256;
- private static final int SCREEN_NAIL_MAX = PhotoView.SCREEN_NAIL_MAX;
- private static final int IMAGE_CACHE_SIZE = 2 * SCREEN_NAIL_MAX + 1;
-
- private static final int BIT_SCREEN_NAIL = 1;
- private static final int BIT_FULL_IMAGE = 2;
-
- // sImageFetchSeq is the fetching sequence for images.
- // We want to fetch the current screennail first (offset = 0), the next
- // screennail (offset = +1), then the previous screennail (offset = -1) etc.
- // After all the screennail are fetched, we fetch the full images (only some
- // of them because of we don't want to use too much memory).
- private static ImageFetch[] sImageFetchSeq;
-
- private static class ImageFetch {
- int indexOffset;
- int imageBit;
- public ImageFetch(int offset, int bit) {
- indexOffset = offset;
- imageBit = bit;
- }
- }
-
- static {
- int k = 0;
- sImageFetchSeq = new ImageFetch[1 + (IMAGE_CACHE_SIZE - 1) * 2 + 3];
- sImageFetchSeq[k++] = new ImageFetch(0, BIT_SCREEN_NAIL);
-
- for (int i = 1; i < IMAGE_CACHE_SIZE; ++i) {
- sImageFetchSeq[k++] = new ImageFetch(i, BIT_SCREEN_NAIL);
- sImageFetchSeq[k++] = new ImageFetch(-i, BIT_SCREEN_NAIL);
- }
-
- sImageFetchSeq[k++] = new ImageFetch(0, BIT_FULL_IMAGE);
- sImageFetchSeq[k++] = new ImageFetch(1, BIT_FULL_IMAGE);
- sImageFetchSeq[k++] = new ImageFetch(-1, BIT_FULL_IMAGE);
- }
-
- private final TileImageViewAdapter mTileProvider = new TileImageViewAdapter();
-
- // PhotoDataAdapter caches MediaItems (data) and ImageEntries (image).
- //
- // The MediaItems are stored in the mData array, which has DATA_CACHE_SIZE
- // entries. The valid index range are [mContentStart, mContentEnd). We keep
- // mContentEnd - mContentStart <= DATA_CACHE_SIZE, so we can use
- // (i % DATA_CACHE_SIZE) as index to the array.
- //
- // The valid MediaItem window size (mContentEnd - mContentStart) may be
- // smaller than DATA_CACHE_SIZE because we only update the window and reload
- // the MediaItems when there are significant changes to the window position
- // (>= MIN_LOAD_COUNT).
- private final MediaItem mData[] = new MediaItem[DATA_CACHE_SIZE];
- private int mContentStart = 0;
- private int mContentEnd = 0;
-
- // The ImageCache is a Path-to-ImageEntry map. It only holds the
- // ImageEntries in the range of [mActiveStart, mActiveEnd). We also keep
- // mActiveEnd - mActiveStart <= IMAGE_CACHE_SIZE. Besides, the
- // [mActiveStart, mActiveEnd) range must be contained within
- // the [mContentStart, mContentEnd) range.
- private HashMap<Path, ImageEntry> mImageCache =
- new HashMap<Path, ImageEntry>();
- private int mActiveStart = 0;
- private int mActiveEnd = 0;
-
- // mCurrentIndex is the "center" image the user is viewing. The change of
- // mCurrentIndex triggers the data loading and image loading.
- private int mCurrentIndex;
-
- // mChanges keeps the version number (of MediaItem) about the images. If any
- // of the version number changes, we notify the view. This is used after a
- // database reload or mCurrentIndex changes.
- private final long mChanges[] = new long[IMAGE_CACHE_SIZE];
- // mPaths keeps the corresponding Path (of MediaItem) for the images. This
- // is used to determine the item movement.
- private final Path mPaths[] = new Path[IMAGE_CACHE_SIZE];
-
- private final Handler mMainHandler;
- private final ThreadPool mThreadPool;
-
- private final PhotoView mPhotoView;
- private final MediaSet mSource;
- private ReloadTask mReloadTask;
-
- private long mSourceVersion = MediaObject.INVALID_DATA_VERSION;
- private int mSize = 0;
- private Path mItemPath;
- private int mCameraIndex;
- private boolean mIsPanorama;
- private boolean mIsStaticCamera;
- private boolean mIsActive;
- private boolean mNeedFullImage;
- private int mFocusHintDirection = FOCUS_HINT_NEXT;
- private Path mFocusHintPath = null;
-
- public interface DataListener extends LoadingListener {
- public void onPhotoChanged(int index, Path item);
- }
-
- private DataListener mDataListener;
-
- private final SourceListener mSourceListener = new SourceListener();
- private final TiledTexture.Uploader mUploader;
-
- // The path of the current viewing item will be stored in mItemPath.
- // If mItemPath is not null, mCurrentIndex is only a hint for where we
- // can find the item. If mItemPath is null, then we use the mCurrentIndex to
- // find the image being viewed. cameraIndex is the index of the camera
- // preview. If cameraIndex < 0, there is no camera preview.
- public PhotoDataAdapter(AbstractGalleryActivity activity, PhotoView view,
- MediaSet mediaSet, Path itemPath, int indexHint, int cameraIndex,
- boolean isPanorama, boolean isStaticCamera) {
- mSource = Utils.checkNotNull(mediaSet);
- mPhotoView = Utils.checkNotNull(view);
- mItemPath = Utils.checkNotNull(itemPath);
- mCurrentIndex = indexHint;
- mCameraIndex = cameraIndex;
- mIsPanorama = isPanorama;
- mIsStaticCamera = isStaticCamera;
- mThreadPool = activity.getThreadPool();
- mNeedFullImage = true;
-
- Arrays.fill(mChanges, MediaObject.INVALID_DATA_VERSION);
-
- mUploader = new TiledTexture.Uploader(activity.getGLRoot());
-
- mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
- @SuppressWarnings("unchecked")
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_RUN_OBJECT:
- ((Runnable) message.obj).run();
- return;
- case MSG_LOAD_START: {
- if (mDataListener != null) {
- mDataListener.onLoadingStarted();
- }
- return;
- }
- case MSG_LOAD_FINISH: {
- if (mDataListener != null) {
- mDataListener.onLoadingFinished(false);
- }
- return;
- }
- case MSG_UPDATE_IMAGE_REQUESTS: {
- updateImageRequests();
- return;
- }
- default: throw new AssertionError();
- }
- }
- };
-
- updateSlidingWindow();
- }
-
- private MediaItem getItemInternal(int index) {
- if (index < 0 || index >= mSize) return null;
- if (index >= mContentStart && index < mContentEnd) {
- return mData[index % DATA_CACHE_SIZE];
- }
- return null;
- }
-
- private long getVersion(int index) {
- MediaItem item = getItemInternal(index);
- if (item == null) return MediaObject.INVALID_DATA_VERSION;
- return item.getDataVersion();
- }
-
- private Path getPath(int index) {
- MediaItem item = getItemInternal(index);
- if (item == null) return null;
- return item.getPath();
- }
-
- private void fireDataChange() {
- // First check if data actually changed.
- boolean changed = false;
- for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; ++i) {
- long newVersion = getVersion(mCurrentIndex + i);
- if (mChanges[i + SCREEN_NAIL_MAX] != newVersion) {
- mChanges[i + SCREEN_NAIL_MAX] = newVersion;
- changed = true;
- }
- }
-
- if (!changed) return;
-
- // Now calculate the fromIndex array. fromIndex represents the item
- // movement. It records the index where the picture come from. The
- // special value Integer.MAX_VALUE means it's a new picture.
- final int N = IMAGE_CACHE_SIZE;
- int fromIndex[] = new int[N];
-
- // Remember the old path array.
- Path oldPaths[] = new Path[N];
- System.arraycopy(mPaths, 0, oldPaths, 0, N);
-
- // Update the mPaths array.
- for (int i = 0; i < N; ++i) {
- mPaths[i] = getPath(mCurrentIndex + i - SCREEN_NAIL_MAX);
- }
-
- // Calculate the fromIndex array.
- for (int i = 0; i < N; i++) {
- Path p = mPaths[i];
- if (p == null) {
- fromIndex[i] = Integer.MAX_VALUE;
- continue;
- }
-
- // Try to find the same path in the old array
- int j;
- for (j = 0; j < N; j++) {
- if (oldPaths[j] == p) {
- break;
- }
- }
- fromIndex[i] = (j < N) ? j - SCREEN_NAIL_MAX : Integer.MAX_VALUE;
- }
-
- mPhotoView.notifyDataChange(fromIndex, -mCurrentIndex,
- mSize - 1 - mCurrentIndex);
- }
-
- public void setDataListener(DataListener listener) {
- mDataListener = listener;
- }
-
- private void updateScreenNail(Path path, Future<ScreenNail> future) {
- ImageEntry entry = mImageCache.get(path);
- ScreenNail screenNail = future.get();
-
- if (entry == null || entry.screenNailTask != future) {
- if (screenNail != null) screenNail.recycle();
- return;
- }
-
- entry.screenNailTask = null;
-
- // Combine the ScreenNails if we already have a BitmapScreenNail
- if (entry.screenNail instanceof TiledScreenNail) {
- TiledScreenNail original = (TiledScreenNail) entry.screenNail;
- screenNail = original.combine(screenNail);
- }
-
- if (screenNail == null) {
- entry.failToLoad = true;
- } else {
- entry.failToLoad = false;
- entry.screenNail = screenNail;
- }
-
- for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; ++i) {
- if (path == getPath(mCurrentIndex + i)) {
- if (i == 0) updateTileProvider(entry);
- mPhotoView.notifyImageChange(i);
- break;
- }
- }
- updateImageRequests();
- updateScreenNailUploadQueue();
- }
-
- private void updateFullImage(Path path, Future<BitmapRegionDecoder> future) {
- ImageEntry entry = mImageCache.get(path);
- if (entry == null || entry.fullImageTask != future) {
- BitmapRegionDecoder fullImage = future.get();
- if (fullImage != null) fullImage.recycle();
- return;
- }
-
- entry.fullImageTask = null;
- entry.fullImage = future.get();
- if (entry.fullImage != null) {
- if (path == getPath(mCurrentIndex)) {
- updateTileProvider(entry);
- mPhotoView.notifyImageChange(0);
- }
- }
- updateImageRequests();
- }
-
- @Override
- public void resume() {
- mIsActive = true;
- TiledTexture.prepareResources();
-
- mSource.addContentListener(mSourceListener);
- updateImageCache();
- updateImageRequests();
-
- mReloadTask = new ReloadTask();
- mReloadTask.start();
-
- fireDataChange();
- }
-
- @Override
- public void pause() {
- mIsActive = false;
-
- mReloadTask.terminate();
- mReloadTask = null;
-
- mSource.removeContentListener(mSourceListener);
-
- for (ImageEntry entry : mImageCache.values()) {
- if (entry.fullImageTask != null) entry.fullImageTask.cancel();
- if (entry.screenNailTask != null) entry.screenNailTask.cancel();
- if (entry.screenNail != null) entry.screenNail.recycle();
- }
- mImageCache.clear();
- mTileProvider.clear();
-
- mUploader.clear();
- TiledTexture.freeResources();
- }
-
- private MediaItem getItem(int index) {
- if (index < 0 || index >= mSize || !mIsActive) return null;
- Utils.assertTrue(index >= mActiveStart && index < mActiveEnd);
-
- if (index >= mContentStart && index < mContentEnd) {
- return mData[index % DATA_CACHE_SIZE];
- }
- return null;
- }
-
- private void updateCurrentIndex(int index) {
- if (mCurrentIndex == index) return;
- mCurrentIndex = index;
- updateSlidingWindow();
-
- MediaItem item = mData[index % DATA_CACHE_SIZE];
- mItemPath = item == null ? null : item.getPath();
-
- updateImageCache();
- updateImageRequests();
- updateTileProvider();
-
- if (mDataListener != null) {
- mDataListener.onPhotoChanged(index, mItemPath);
- }
-
- fireDataChange();
- }
-
- private void uploadScreenNail(int offset) {
- int index = mCurrentIndex + offset;
- if (index < mActiveStart || index >= mActiveEnd) return;
-
- MediaItem item = getItem(index);
- if (item == null) return;
-
- ImageEntry e = mImageCache.get(item.getPath());
- if (e == null) return;
-
- ScreenNail s = e.screenNail;
- if (s instanceof TiledScreenNail) {
- TiledTexture t = ((TiledScreenNail) s).getTexture();
- if (t != null && !t.isReady()) mUploader.addTexture(t);
- }
- }
-
- private void updateScreenNailUploadQueue() {
- mUploader.clear();
- uploadScreenNail(0);
- for (int i = 1; i < IMAGE_CACHE_SIZE; ++i) {
- uploadScreenNail(i);
- uploadScreenNail(-i);
- }
- }
-
- @Override
- public void moveTo(int index) {
- updateCurrentIndex(index);
- }
-
- @Override
- public ScreenNail getScreenNail(int offset) {
- int index = mCurrentIndex + offset;
- if (index < 0 || index >= mSize || !mIsActive) return null;
- Utils.assertTrue(index >= mActiveStart && index < mActiveEnd);
-
- MediaItem item = getItem(index);
- if (item == null) return null;
-
- ImageEntry entry = mImageCache.get(item.getPath());
- if (entry == null) return null;
-
- // Create a default ScreenNail if the real one is not available yet,
- // except for camera that a black screen is better than a gray tile.
- if (entry.screenNail == null && !isCamera(offset)) {
- entry.screenNail = newPlaceholderScreenNail(item);
- if (offset == 0) updateTileProvider(entry);
- }
-
- return entry.screenNail;
- }
-
- @Override
- public void getImageSize(int offset, PhotoView.Size size) {
- MediaItem item = getItem(mCurrentIndex + offset);
- if (item == null) {
- size.width = 0;
- size.height = 0;
- } else {
- size.width = item.getWidth();
- size.height = item.getHeight();
- }
- }
-
- @Override
- public int getImageRotation(int offset) {
- MediaItem item = getItem(mCurrentIndex + offset);
- return (item == null) ? 0 : item.getFullImageRotation();
- }
-
- @Override
- public void setNeedFullImage(boolean enabled) {
- mNeedFullImage = enabled;
- mMainHandler.sendEmptyMessage(MSG_UPDATE_IMAGE_REQUESTS);
- }
-
- @Override
- public boolean isCamera(int offset) {
- return mCurrentIndex + offset == mCameraIndex;
- }
-
- @Override
- public boolean isPanorama(int offset) {
- return isCamera(offset) && mIsPanorama;
- }
-
- @Override
- public boolean isStaticCamera(int offset) {
- return isCamera(offset) && mIsStaticCamera;
- }
-
- @Override
- public boolean isVideo(int offset) {
- MediaItem item = getItem(mCurrentIndex + offset);
- return (item == null)
- ? false
- : item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO;
- }
-
- @Override
- public boolean isDeletable(int offset) {
- MediaItem item = getItem(mCurrentIndex + offset);
- return (item == null)
- ? false
- : (item.getSupportedOperations() & MediaItem.SUPPORT_DELETE) != 0;
- }
-
- @Override
- public int getLoadingState(int offset) {
- ImageEntry entry = mImageCache.get(getPath(mCurrentIndex + offset));
- if (entry == null) return LOADING_INIT;
- if (entry.failToLoad) return LOADING_FAIL;
- if (entry.screenNail != null) return LOADING_COMPLETE;
- return LOADING_INIT;
- }
-
- @Override
- public ScreenNail getScreenNail() {
- return getScreenNail(0);
- }
-
- @Override
- public int getImageHeight() {
- return mTileProvider.getImageHeight();
- }
-
- @Override
- public int getImageWidth() {
- return mTileProvider.getImageWidth();
- }
-
- @Override
- public int getLevelCount() {
- return mTileProvider.getLevelCount();
- }
-
- @Override
- public Bitmap getTile(int level, int x, int y, int tileSize) {
- return mTileProvider.getTile(level, x, y, tileSize);
- }
-
- @Override
- public boolean isEmpty() {
- return mSize == 0;
- }
-
- @Override
- public int getCurrentIndex() {
- return mCurrentIndex;
- }
-
- @Override
- public MediaItem getMediaItem(int offset) {
- int index = mCurrentIndex + offset;
- if (index >= mContentStart && index < mContentEnd) {
- return mData[index % DATA_CACHE_SIZE];
- }
- return null;
- }
-
- @Override
- public void setCurrentPhoto(Path path, int indexHint) {
- if (mItemPath == path) return;
- mItemPath = path;
- mCurrentIndex = indexHint;
- updateSlidingWindow();
- updateImageCache();
- fireDataChange();
-
- // We need to reload content if the path doesn't match.
- MediaItem item = getMediaItem(0);
- if (item != null && item.getPath() != path) {
- if (mReloadTask != null) mReloadTask.notifyDirty();
- }
- }
-
- @Override
- public void setFocusHintDirection(int direction) {
- mFocusHintDirection = direction;
- }
-
- @Override
- public void setFocusHintPath(Path path) {
- mFocusHintPath = path;
- }
-
- private void updateTileProvider() {
- ImageEntry entry = mImageCache.get(getPath(mCurrentIndex));
- if (entry == null) { // in loading
- mTileProvider.clear();
- } else {
- updateTileProvider(entry);
- }
- }
-
- private void updateTileProvider(ImageEntry entry) {
- ScreenNail screenNail = entry.screenNail;
- BitmapRegionDecoder fullImage = entry.fullImage;
- if (screenNail != null) {
- if (fullImage != null) {
- mTileProvider.setScreenNail(screenNail,
- fullImage.getWidth(), fullImage.getHeight());
- mTileProvider.setRegionDecoder(fullImage);
- } else {
- int width = screenNail.getWidth();
- int height = screenNail.getHeight();
- mTileProvider.setScreenNail(screenNail, width, height);
- }
- } else {
- mTileProvider.clear();
- }
- }
-
- private void updateSlidingWindow() {
- // 1. Update the image window
- int start = Utils.clamp(mCurrentIndex - IMAGE_CACHE_SIZE / 2,
- 0, Math.max(0, mSize - IMAGE_CACHE_SIZE));
- int end = Math.min(mSize, start + IMAGE_CACHE_SIZE);
-
- if (mActiveStart == start && mActiveEnd == end) return;
-
- mActiveStart = start;
- mActiveEnd = end;
-
- // 2. Update the data window
- start = Utils.clamp(mCurrentIndex - DATA_CACHE_SIZE / 2,
- 0, Math.max(0, mSize - DATA_CACHE_SIZE));
- end = Math.min(mSize, start + DATA_CACHE_SIZE);
- if (mContentStart > mActiveStart || mContentEnd < mActiveEnd
- || Math.abs(start - mContentStart) > MIN_LOAD_COUNT) {
- for (int i = mContentStart; i < mContentEnd; ++i) {
- if (i < start || i >= end) {
- mData[i % DATA_CACHE_SIZE] = null;
- }
- }
- mContentStart = start;
- mContentEnd = end;
- if (mReloadTask != null) mReloadTask.notifyDirty();
- }
- }
-
- private void updateImageRequests() {
- if (!mIsActive) return;
-
- int currentIndex = mCurrentIndex;
- MediaItem item = mData[currentIndex % DATA_CACHE_SIZE];
- if (item == null || item.getPath() != mItemPath) {
- // current item mismatch - don't request image
- return;
- }
-
- // 1. Find the most wanted request and start it (if not already started).
- Future<?> task = null;
- for (int i = 0; i < sImageFetchSeq.length; i++) {
- int offset = sImageFetchSeq[i].indexOffset;
- int bit = sImageFetchSeq[i].imageBit;
- if (bit == BIT_FULL_IMAGE && !mNeedFullImage) continue;
- task = startTaskIfNeeded(currentIndex + offset, bit);
- if (task != null) break;
- }
-
- // 2. Cancel everything else.
- for (ImageEntry entry : mImageCache.values()) {
- if (entry.screenNailTask != null && entry.screenNailTask != task) {
- entry.screenNailTask.cancel();
- entry.screenNailTask = null;
- entry.requestedScreenNail = MediaObject.INVALID_DATA_VERSION;
- }
- if (entry.fullImageTask != null && entry.fullImageTask != task) {
- entry.fullImageTask.cancel();
- entry.fullImageTask = null;
- entry.requestedFullImage = MediaObject.INVALID_DATA_VERSION;
- }
- }
- }
-
- private class ScreenNailJob implements Job<ScreenNail> {
- private MediaItem mItem;
-
- public ScreenNailJob(MediaItem item) {
- mItem = item;
- }
-
- @Override
- public ScreenNail run(JobContext jc) {
- // We try to get a ScreenNail first, if it fails, we fallback to get
- // a Bitmap and then wrap it in a BitmapScreenNail instead.
- ScreenNail s = mItem.getScreenNail();
- if (s != null) return s;
-
- // If this is a temporary item, don't try to get its bitmap because
- // it won't be available. We will get its bitmap after a data reload.
- if (isTemporaryItem(mItem)) {
- return newPlaceholderScreenNail(mItem);
- }
-
- Bitmap bitmap = mItem.requestImage(MediaItem.TYPE_THUMBNAIL).run(jc);
- if (jc.isCancelled()) return null;
- if (bitmap != null) {
- bitmap = BitmapUtils.rotateBitmap(bitmap,
- mItem.getRotation() - mItem.getFullImageRotation(), true);
- }
- return bitmap == null ? null : new TiledScreenNail(bitmap);
- }
- }
-
- private class FullImageJob implements Job<BitmapRegionDecoder> {
- private MediaItem mItem;
-
- public FullImageJob(MediaItem item) {
- mItem = item;
- }
-
- @Override
- public BitmapRegionDecoder run(JobContext jc) {
- if (isTemporaryItem(mItem)) {
- return null;
- }
- return mItem.requestLargeImage().run(jc);
- }
- }
-
- // Returns true if we think this is a temporary item created by Camera. A
- // temporary item is an image or a video whose data is still being
- // processed, but an incomplete entry is created first in MediaProvider, so
- // we can display them (in grey tile) even if they are not saved to disk
- // yet. When the image or video data is actually saved, we will get
- // notification from MediaProvider, reload data, and show the actual image
- // or video data.
- private boolean isTemporaryItem(MediaItem mediaItem) {
- // Must have camera to create a temporary item.
- if (mCameraIndex < 0) return false;
- // Must be an item in camera roll.
- if (!(mediaItem instanceof LocalMediaItem)) return false;
- LocalMediaItem item = (LocalMediaItem) mediaItem;
- if (item.getBucketId() != MediaSetUtils.CAMERA_BUCKET_ID) return false;
- // Must have no size, but must have width and height information
- if (item.getSize() != 0) return false;
- if (item.getWidth() == 0) return false;
- if (item.getHeight() == 0) return false;
- // Must be created in the last 10 seconds.
- if (item.getDateInMs() - System.currentTimeMillis() > 10000) return false;
- return true;
- }
-
- // Create a default ScreenNail when a ScreenNail is needed, but we don't yet
- // have one available (because the image data is still being saved, or the
- // Bitmap is still being loaded.
- private ScreenNail newPlaceholderScreenNail(MediaItem item) {
- int width = item.getWidth();
- int height = item.getHeight();
- return new TiledScreenNail(width, height);
- }
-
- // Returns the task if we started the task or the task is already started.
- private Future<?> startTaskIfNeeded(int index, int which) {
- if (index < mActiveStart || index >= mActiveEnd) return null;
-
- ImageEntry entry = mImageCache.get(getPath(index));
- if (entry == null) return null;
- MediaItem item = mData[index % DATA_CACHE_SIZE];
- Utils.assertTrue(item != null);
- long version = item.getDataVersion();
-
- if (which == BIT_SCREEN_NAIL && entry.screenNailTask != null
- && entry.requestedScreenNail == version) {
- return entry.screenNailTask;
- } else if (which == BIT_FULL_IMAGE && entry.fullImageTask != null
- && entry.requestedFullImage == version) {
- return entry.fullImageTask;
- }
-
- if (which == BIT_SCREEN_NAIL && entry.requestedScreenNail != version) {
- entry.requestedScreenNail = version;
- entry.screenNailTask = mThreadPool.submit(
- new ScreenNailJob(item),
- new ScreenNailListener(item));
- // request screen nail
- return entry.screenNailTask;
- }
- if (which == BIT_FULL_IMAGE && entry.requestedFullImage != version
- && (item.getSupportedOperations()
- & MediaItem.SUPPORT_FULL_IMAGE) != 0) {
- entry.requestedFullImage = version;
- entry.fullImageTask = mThreadPool.submit(
- new FullImageJob(item),
- new FullImageListener(item));
- // request full image
- return entry.fullImageTask;
- }
- return null;
- }
-
- private void updateImageCache() {
- HashSet<Path> toBeRemoved = new HashSet<Path>(mImageCache.keySet());
- for (int i = mActiveStart; i < mActiveEnd; ++i) {
- MediaItem item = mData[i % DATA_CACHE_SIZE];
- if (item == null) continue;
- Path path = item.getPath();
- ImageEntry entry = mImageCache.get(path);
- toBeRemoved.remove(path);
- if (entry != null) {
- if (Math.abs(i - mCurrentIndex) > 1) {
- if (entry.fullImageTask != null) {
- entry.fullImageTask.cancel();
- entry.fullImageTask = null;
- }
- entry.fullImage = null;
- entry.requestedFullImage = MediaObject.INVALID_DATA_VERSION;
- }
- if (entry.requestedScreenNail != item.getDataVersion()) {
- // This ScreenNail is outdated, we want to update it if it's
- // still a placeholder.
- if (entry.screenNail instanceof TiledScreenNail) {
- TiledScreenNail s = (TiledScreenNail) entry.screenNail;
- s.updatePlaceholderSize(
- item.getWidth(), item.getHeight());
- }
- }
- } else {
- entry = new ImageEntry();
- mImageCache.put(path, entry);
- }
- }
-
- // Clear the data and requests for ImageEntries outside the new window.
- for (Path path : toBeRemoved) {
- ImageEntry entry = mImageCache.remove(path);
- if (entry.fullImageTask != null) entry.fullImageTask.cancel();
- if (entry.screenNailTask != null) entry.screenNailTask.cancel();
- if (entry.screenNail != null) entry.screenNail.recycle();
- }
-
- updateScreenNailUploadQueue();
- }
-
- private class FullImageListener
- implements Runnable, FutureListener<BitmapRegionDecoder> {
- private final Path mPath;
- private Future<BitmapRegionDecoder> mFuture;
-
- public FullImageListener(MediaItem item) {
- mPath = item.getPath();
- }
-
- @Override
- public void onFutureDone(Future<BitmapRegionDecoder> future) {
- mFuture = future;
- mMainHandler.sendMessage(
- mMainHandler.obtainMessage(MSG_RUN_OBJECT, this));
- }
-
- @Override
- public void run() {
- updateFullImage(mPath, mFuture);
- }
- }
-
- private class ScreenNailListener
- implements Runnable, FutureListener<ScreenNail> {
- private final Path mPath;
- private Future<ScreenNail> mFuture;
-
- public ScreenNailListener(MediaItem item) {
- mPath = item.getPath();
- }
-
- @Override
- public void onFutureDone(Future<ScreenNail> future) {
- mFuture = future;
- mMainHandler.sendMessage(
- mMainHandler.obtainMessage(MSG_RUN_OBJECT, this));
- }
-
- @Override
- public void run() {
- updateScreenNail(mPath, mFuture);
- }
- }
-
- private static class ImageEntry {
- public BitmapRegionDecoder fullImage;
- public ScreenNail screenNail;
- public Future<ScreenNail> screenNailTask;
- public Future<BitmapRegionDecoder> fullImageTask;
- public long requestedScreenNail = MediaObject.INVALID_DATA_VERSION;
- public long requestedFullImage = MediaObject.INVALID_DATA_VERSION;
- public boolean failToLoad = false;
- }
-
- private class SourceListener implements ContentListener {
- @Override
- public void onContentDirty() {
- if (mReloadTask != null) mReloadTask.notifyDirty();
- }
- }
-
- private <T> T executeAndWait(Callable<T> callable) {
- FutureTask<T> task = new FutureTask<T>(callable);
- mMainHandler.sendMessage(
- mMainHandler.obtainMessage(MSG_RUN_OBJECT, task));
- try {
- return task.get();
- } catch (InterruptedException e) {
- return null;
- } catch (ExecutionException e) {
- throw new RuntimeException(e);
- }
- }
-
- private static class UpdateInfo {
- public long version;
- public boolean reloadContent;
- public Path target;
- public int indexHint;
- public int contentStart;
- public int contentEnd;
-
- public int size;
- public ArrayList<MediaItem> items;
- }
-
- private class GetUpdateInfo implements Callable<UpdateInfo> {
-
- private boolean needContentReload() {
- for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
- if (mData[i % DATA_CACHE_SIZE] == null) return true;
- }
- MediaItem current = mData[mCurrentIndex % DATA_CACHE_SIZE];
- return current == null || current.getPath() != mItemPath;
- }
-
- @Override
- public UpdateInfo call() throws Exception {
- // TODO: Try to load some data in first update
- UpdateInfo info = new UpdateInfo();
- info.version = mSourceVersion;
- info.reloadContent = needContentReload();
- info.target = mItemPath;
- info.indexHint = mCurrentIndex;
- info.contentStart = mContentStart;
- info.contentEnd = mContentEnd;
- info.size = mSize;
- return info;
- }
- }
-
- private class UpdateContent implements Callable<Void> {
- UpdateInfo mUpdateInfo;
-
- public UpdateContent(UpdateInfo updateInfo) {
- mUpdateInfo = updateInfo;
- }
-
- @Override
- public Void call() throws Exception {
- UpdateInfo info = mUpdateInfo;
- mSourceVersion = info.version;
-
- if (info.size != mSize) {
- mSize = info.size;
- if (mContentEnd > mSize) mContentEnd = mSize;
- if (mActiveEnd > mSize) mActiveEnd = mSize;
- }
-
- mCurrentIndex = info.indexHint;
- updateSlidingWindow();
-
- if (info.items != null) {
- int start = Math.max(info.contentStart, mContentStart);
- int end = Math.min(info.contentStart + info.items.size(), mContentEnd);
- int dataIndex = start % DATA_CACHE_SIZE;
- for (int i = start; i < end; ++i) {
- mData[dataIndex] = info.items.get(i - info.contentStart);
- if (++dataIndex == DATA_CACHE_SIZE) dataIndex = 0;
- }
- }
-
- // update mItemPath
- MediaItem current = mData[mCurrentIndex % DATA_CACHE_SIZE];
- mItemPath = current == null ? null : current.getPath();
-
- updateImageCache();
- updateTileProvider();
- updateImageRequests();
-
- if (mDataListener != null) {
- mDataListener.onPhotoChanged(mCurrentIndex, mItemPath);
- }
-
- fireDataChange();
- return null;
- }
- }
-
- private class ReloadTask extends Thread {
- private volatile boolean mActive = true;
- private volatile boolean mDirty = true;
-
- private boolean mIsLoading = false;
-
- private void updateLoading(boolean loading) {
- if (mIsLoading == loading) return;
- mIsLoading = loading;
- mMainHandler.sendEmptyMessage(loading ? MSG_LOAD_START : MSG_LOAD_FINISH);
- }
-
- @Override
- public void run() {
- while (mActive) {
- synchronized (this) {
- if (!mDirty && mActive) {
- updateLoading(false);
- Utils.waitWithoutInterrupt(this);
- continue;
- }
- }
- mDirty = false;
- UpdateInfo info = executeAndWait(new GetUpdateInfo());
- updateLoading(true);
- long version = mSource.reload();
- if (info.version != version) {
- info.reloadContent = true;
- info.size = mSource.getMediaItemCount();
- }
- if (!info.reloadContent) continue;
- info.items = mSource.getMediaItem(
- info.contentStart, info.contentEnd);
-
- int index = MediaSet.INDEX_NOT_FOUND;
-
- // First try to focus on the given hint path if there is one.
- if (mFocusHintPath != null) {
- index = findIndexOfPathInCache(info, mFocusHintPath);
- mFocusHintPath = null;
- }
-
- // Otherwise try to see if the currently focused item can be found.
- if (index == MediaSet.INDEX_NOT_FOUND) {
- MediaItem item = findCurrentMediaItem(info);
- if (item != null && item.getPath() == info.target) {
- index = info.indexHint;
- } else {
- index = findIndexOfTarget(info);
- }
- }
-
- // The image has been deleted. Focus on the next image (keep
- // mCurrentIndex unchanged) or the previous image (decrease
- // mCurrentIndex by 1). In page mode we want to see the next
- // image, so we focus on the next one. In film mode we want the
- // later images to shift left to fill the empty space, so we
- // focus on the previous image (so it will not move). In any
- // case the index needs to be limited to [0, mSize).
- if (index == MediaSet.INDEX_NOT_FOUND) {
- index = info.indexHint;
- int focusHintDirection = mFocusHintDirection;
- if (index == (mCameraIndex + 1)) {
- focusHintDirection = FOCUS_HINT_NEXT;
- }
- if (focusHintDirection == FOCUS_HINT_PREVIOUS
- && index > 0) {
- index--;
- }
- }
-
- // Don't change index if mSize == 0
- if (mSize > 0) {
- if (index >= mSize) index = mSize - 1;
- }
-
- info.indexHint = index;
-
- executeAndWait(new UpdateContent(info));
- }
- }
-
- public synchronized void notifyDirty() {
- mDirty = true;
- notifyAll();
- }
-
- public synchronized void terminate() {
- mActive = false;
- notifyAll();
- }
-
- private MediaItem findCurrentMediaItem(UpdateInfo info) {
- ArrayList<MediaItem> items = info.items;
- int index = info.indexHint - info.contentStart;
- return index < 0 || index >= items.size() ? null : items.get(index);
- }
-
- private int findIndexOfTarget(UpdateInfo info) {
- if (info.target == null) return info.indexHint;
- ArrayList<MediaItem> items = info.items;
-
- // First, try to find the item in the data just loaded
- if (items != null) {
- int i = findIndexOfPathInCache(info, info.target);
- if (i != MediaSet.INDEX_NOT_FOUND) return i;
- }
-
- // Not found, find it in mSource.
- return mSource.getIndexOfItem(info.target, info.indexHint);
- }
-
- private int findIndexOfPathInCache(UpdateInfo info, Path path) {
- ArrayList<MediaItem> items = info.items;
- for (int i = 0, n = items.size(); i < n; ++i) {
- MediaItem item = items.get(i);
- if (item != null && item.getPath() == path) {
- return i + info.contentStart;
- }
- }
- return MediaSet.INDEX_NOT_FOUND;
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java
deleted file mode 100644
index 7a71e9109..000000000
--- a/src/com/android/gallery3d/app/PhotoPage.java
+++ /dev/null
@@ -1,1571 +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.app;
-
-import android.annotation.TargetApi;
-import android.app.ActionBar.OnMenuVisibilityListener;
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.nfc.NfcAdapter;
-import android.nfc.NfcAdapter.CreateBeamUrisCallback;
-import android.nfc.NfcEvent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.RelativeLayout;
-import android.widget.ShareActionProvider;
-import android.widget.Toast;
-
-import com.android.camera.CameraActivity;
-import com.android.camera.ProxyLauncher;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.data.ComboAlbum;
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.FilterDeleteSet;
-import com.android.gallery3d.data.FilterSource;
-import com.android.gallery3d.data.LocalImage;
-import com.android.gallery3d.data.MediaDetails;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaObject.PanoramaSupportCallback;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.data.SecureAlbum;
-import com.android.gallery3d.data.SecureSource;
-import com.android.gallery3d.data.SnailAlbum;
-import com.android.gallery3d.data.SnailItem;
-import com.android.gallery3d.data.SnailSource;
-import com.android.gallery3d.filtershow.FilterShowActivity;
-import com.android.gallery3d.filtershow.crop.CropActivity;
-import com.android.gallery3d.picasasource.PicasaSource;
-import com.android.gallery3d.ui.DetailsHelper;
-import com.android.gallery3d.ui.DetailsHelper.CloseListener;
-import com.android.gallery3d.ui.DetailsHelper.DetailsSource;
-import com.android.gallery3d.ui.GLView;
-import com.android.gallery3d.ui.MenuExecutor;
-import com.android.gallery3d.ui.PhotoView;
-import com.android.gallery3d.ui.SelectionManager;
-import com.android.gallery3d.ui.SynchronizedHandler;
-import com.android.gallery3d.util.GalleryUtils;
-import com.android.gallery3d.util.UsageStatistics;
-
-public abstract class PhotoPage extends ActivityState implements
- PhotoView.Listener, AppBridge.Server, ShareActionProvider.OnShareTargetSelectedListener,
- PhotoPageBottomControls.Delegate, GalleryActionBar.OnAlbumModeSelectedListener {
- private static final String TAG = "PhotoPage";
-
- private static final int MSG_HIDE_BARS = 1;
- private static final int MSG_ON_FULL_SCREEN_CHANGED = 4;
- private static final int MSG_UPDATE_ACTION_BAR = 5;
- private static final int MSG_UNFREEZE_GLROOT = 6;
- private static final int MSG_WANT_BARS = 7;
- private static final int MSG_REFRESH_BOTTOM_CONTROLS = 8;
- private static final int MSG_ON_CAMERA_CENTER = 9;
- private static final int MSG_ON_PICTURE_CENTER = 10;
- private static final int MSG_REFRESH_IMAGE = 11;
- private static final int MSG_UPDATE_PHOTO_UI = 12;
- private static final int MSG_UPDATE_PROGRESS = 13;
- private static final int MSG_UPDATE_DEFERRED = 14;
- private static final int MSG_UPDATE_SHARE_URI = 15;
- private static final int MSG_UPDATE_PANORAMA_UI = 16;
-
- private static final int HIDE_BARS_TIMEOUT = 3500;
- private static final int UNFREEZE_GLROOT_TIMEOUT = 250;
-
- private static final int REQUEST_SLIDESHOW = 1;
- private static final int REQUEST_CROP = 2;
- private static final int REQUEST_CROP_PICASA = 3;
- private static final int REQUEST_EDIT = 4;
- private static final int REQUEST_PLAY_VIDEO = 5;
- private static final int REQUEST_TRIM = 6;
-
- public static final String KEY_MEDIA_SET_PATH = "media-set-path";
- public static final String KEY_MEDIA_ITEM_PATH = "media-item-path";
- public static final String KEY_INDEX_HINT = "index-hint";
- public static final String KEY_OPEN_ANIMATION_RECT = "open-animation-rect";
- public static final String KEY_APP_BRIDGE = "app-bridge";
- public static final String KEY_TREAT_BACK_AS_UP = "treat-back-as-up";
- public static final String KEY_START_IN_FILMSTRIP = "start-in-filmstrip";
- public static final String KEY_RETURN_INDEX_HINT = "return-index-hint";
- public static final String KEY_SHOW_WHEN_LOCKED = "show_when_locked";
- public static final String KEY_IN_CAMERA_ROLL = "in_camera_roll";
-
- public static final String KEY_ALBUMPAGE_TRANSITION = "albumpage-transition";
- public static final int MSG_ALBUMPAGE_NONE = 0;
- public static final int MSG_ALBUMPAGE_STARTED = 1;
- public static final int MSG_ALBUMPAGE_RESUMED = 2;
- public static final int MSG_ALBUMPAGE_PICKED = 4;
-
- public static final String ACTION_NEXTGEN_EDIT = "action_nextgen_edit";
- public static final String ACTION_SIMPLE_EDIT = "action_simple_edit";
-
- private GalleryApp mApplication;
- private SelectionManager mSelectionManager;
-
- private PhotoView mPhotoView;
- private PhotoPage.Model mModel;
- private DetailsHelper mDetailsHelper;
- private boolean mShowDetails;
-
- // mMediaSet could be null if there is no KEY_MEDIA_SET_PATH supplied.
- // E.g., viewing a photo in gmail attachment
- private FilterDeleteSet mMediaSet;
-
- // The mediaset used by camera launched from secure lock screen.
- private SecureAlbum mSecureAlbum;
-
- private int mCurrentIndex = 0;
- private Handler mHandler;
- private boolean mShowBars = true;
- private volatile boolean mActionBarAllowed = true;
- private GalleryActionBar mActionBar;
- private boolean mIsMenuVisible;
- private boolean mHaveImageEditor;
- private PhotoPageBottomControls mBottomControls;
- private PhotoPageProgressBar mProgressBar;
- private MediaItem mCurrentPhoto = null;
- private MenuExecutor mMenuExecutor;
- private boolean mIsActive;
- private boolean mShowSpinner;
- private String mSetPathString;
- // This is the original mSetPathString before adding the camera preview item.
- private String mOriginalSetPathString;
- private AppBridge mAppBridge;
- private SnailItem mScreenNailItem;
- private SnailAlbum mScreenNailSet;
- private OrientationManager mOrientationManager;
- private boolean mTreatBackAsUp;
- private boolean mStartInFilmstrip;
- private boolean mHasCameraScreennailOrPlaceholder = false;
- private boolean mRecenterCameraOnResume = true;
-
- // These are only valid after the panorama callback
- private boolean mIsPanorama;
- private boolean mIsPanorama360;
-
- private long mCameraSwitchCutoff = 0;
- private boolean mSkipUpdateCurrentPhoto = false;
- private static final long CAMERA_SWITCH_CUTOFF_THRESHOLD_MS = 300;
-
- private static final long DEFERRED_UPDATE_MS = 250;
- private boolean mDeferredUpdateWaiting = false;
- private long mDeferUpdateUntil = Long.MAX_VALUE;
-
- // The item that is deleted (but it can still be undeleted before commiting)
- private Path mDeletePath;
- private boolean mDeleteIsFocus; // whether the deleted item was in focus
-
- private Uri[] mNfcPushUris = new Uri[1];
-
- private final MyMenuVisibilityListener mMenuVisibilityListener =
- new MyMenuVisibilityListener();
- private UpdateProgressListener mProgressListener;
-
- private final PanoramaSupportCallback mUpdatePanoramaMenuItemsCallback = new PanoramaSupportCallback() {
- @Override
- public void panoramaInfoAvailable(MediaObject mediaObject, boolean isPanorama,
- boolean isPanorama360) {
- if (mediaObject == mCurrentPhoto) {
- mHandler.obtainMessage(MSG_UPDATE_PANORAMA_UI, isPanorama360 ? 1 : 0, 0,
- mediaObject).sendToTarget();
- }
- }
- };
-
- private final PanoramaSupportCallback mRefreshBottomControlsCallback = new PanoramaSupportCallback() {
- @Override
- public void panoramaInfoAvailable(MediaObject mediaObject, boolean isPanorama,
- boolean isPanorama360) {
- if (mediaObject == mCurrentPhoto) {
- mHandler.obtainMessage(MSG_REFRESH_BOTTOM_CONTROLS, isPanorama ? 1 : 0, isPanorama360 ? 1 : 0,
- mediaObject).sendToTarget();
- }
- }
- };
-
- private final PanoramaSupportCallback mUpdateShareURICallback = new PanoramaSupportCallback() {
- @Override
- public void panoramaInfoAvailable(MediaObject mediaObject, boolean isPanorama,
- boolean isPanorama360) {
- if (mediaObject == mCurrentPhoto) {
- mHandler.obtainMessage(MSG_UPDATE_SHARE_URI, isPanorama360 ? 1 : 0, 0, mediaObject)
- .sendToTarget();
- }
- }
- };
-
- public static interface Model extends PhotoView.Model {
- public void resume();
- public void pause();
- public boolean isEmpty();
- public void setCurrentPhoto(Path path, int indexHint);
- }
-
- private class MyMenuVisibilityListener implements OnMenuVisibilityListener {
- @Override
- public void onMenuVisibilityChanged(boolean isVisible) {
- mIsMenuVisible = isVisible;
- refreshHidingMessage();
- }
- }
-
- private class UpdateProgressListener implements StitchingChangeListener {
-
- @Override
- public void onStitchingResult(Uri uri) {
- sendUpdate(uri, MSG_REFRESH_IMAGE);
- }
-
- @Override
- public void onStitchingQueued(Uri uri) {
- sendUpdate(uri, MSG_UPDATE_PROGRESS);
- }
-
- @Override
- public void onStitchingProgress(Uri uri, final int progress) {
- sendUpdate(uri, MSG_UPDATE_PROGRESS);
- }
-
- private void sendUpdate(Uri uri, int message) {
- MediaObject currentPhoto = mCurrentPhoto;
- boolean isCurrentPhoto = currentPhoto instanceof LocalImage
- && currentPhoto.getContentUri().equals(uri);
- if (isCurrentPhoto) {
- mHandler.sendEmptyMessage(message);
- }
- }
- };
-
- @Override
- protected int getBackgroundColorId() {
- return R.color.photo_background;
- }
-
- private final GLView mRootPane = new GLView() {
- @Override
- protected void onLayout(
- boolean changed, int left, int top, int right, int bottom) {
- mPhotoView.layout(0, 0, right - left, bottom - top);
- if (mShowDetails) {
- mDetailsHelper.layout(left, mActionBar.getHeight(), right, bottom);
- }
- }
- };
-
- @Override
- public void onCreate(Bundle data, Bundle restoreState) {
- super.onCreate(data, restoreState);
- mActionBar = mActivity.getGalleryActionBar();
- mSelectionManager = new SelectionManager(mActivity, false);
- mMenuExecutor = new MenuExecutor(mActivity, mSelectionManager);
-
- mPhotoView = new PhotoView(mActivity);
- mPhotoView.setListener(this);
- mRootPane.addComponent(mPhotoView);
- mApplication = (GalleryApp) ((Activity) mActivity).getApplication();
- mOrientationManager = mActivity.getOrientationManager();
- mActivity.getGLRoot().setOrientationSource(mOrientationManager);
-
- mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_HIDE_BARS: {
- hideBars();
- break;
- }
- case MSG_REFRESH_BOTTOM_CONTROLS: {
- if (mCurrentPhoto == message.obj && mBottomControls != null) {
- mIsPanorama = message.arg1 == 1;
- mIsPanorama360 = message.arg2 == 1;
- mBottomControls.refresh();
- }
- break;
- }
- case MSG_ON_FULL_SCREEN_CHANGED: {
- if (mAppBridge != null) {
- mAppBridge.onFullScreenChanged(message.arg1 == 1);
- }
- break;
- }
- case MSG_UPDATE_ACTION_BAR: {
- updateBars();
- break;
- }
- case MSG_WANT_BARS: {
- wantBars();
- break;
- }
- case MSG_UNFREEZE_GLROOT: {
- mActivity.getGLRoot().unfreeze();
- break;
- }
- case MSG_UPDATE_DEFERRED: {
- long nextUpdate = mDeferUpdateUntil - SystemClock.uptimeMillis();
- if (nextUpdate <= 0) {
- mDeferredUpdateWaiting = false;
- updateUIForCurrentPhoto();
- } else {
- mHandler.sendEmptyMessageDelayed(MSG_UPDATE_DEFERRED, nextUpdate);
- }
- break;
- }
- case MSG_ON_CAMERA_CENTER: {
- mSkipUpdateCurrentPhoto = false;
- boolean stayedOnCamera = false;
- if (!mPhotoView.getFilmMode()) {
- stayedOnCamera = true;
- } else if (SystemClock.uptimeMillis() < mCameraSwitchCutoff &&
- mMediaSet.getMediaItemCount() > 1) {
- mPhotoView.switchToImage(1);
- } else {
- if (mAppBridge != null) mPhotoView.setFilmMode(false);
- stayedOnCamera = true;
- }
-
- if (stayedOnCamera) {
- if (mAppBridge == null && mMediaSet.getTotalMediaItemCount() > 1) {
- launchCamera();
- /* We got here by swiping from photo 1 to the
- placeholder, so make it be the thing that
- is in focus when the user presses back from
- the camera app */
- mPhotoView.switchToImage(1);
- } else {
- updateBars();
- updateCurrentPhoto(mModel.getMediaItem(0));
- }
- }
- break;
- }
- case MSG_ON_PICTURE_CENTER: {
- if (!mPhotoView.getFilmMode() && mCurrentPhoto != null
- && (mCurrentPhoto.getSupportedOperations() & MediaObject.SUPPORT_ACTION) != 0) {
- mPhotoView.setFilmMode(true);
- }
- break;
- }
- case MSG_REFRESH_IMAGE: {
- final MediaItem photo = mCurrentPhoto;
- mCurrentPhoto = null;
- updateCurrentPhoto(photo);
- break;
- }
- case MSG_UPDATE_PHOTO_UI: {
- updateUIForCurrentPhoto();
- break;
- }
- case MSG_UPDATE_PROGRESS: {
- updateProgressBar();
- break;
- }
- case MSG_UPDATE_SHARE_URI: {
- if (mCurrentPhoto == message.obj) {
- boolean isPanorama360 = message.arg1 != 0;
- Uri contentUri = mCurrentPhoto.getContentUri();
- Intent panoramaIntent = null;
- if (isPanorama360) {
- panoramaIntent = createSharePanoramaIntent(contentUri);
- }
- Intent shareIntent = createShareIntent(mCurrentPhoto);
-
- mActionBar.setShareIntents(panoramaIntent, shareIntent, PhotoPage.this);
- setNfcBeamPushUri(contentUri);
- }
- break;
- }
- case MSG_UPDATE_PANORAMA_UI: {
- if (mCurrentPhoto == message.obj) {
- boolean isPanorama360 = message.arg1 != 0;
- updatePanoramaUI(isPanorama360);
- }
- break;
- }
- default: throw new AssertionError(message.what);
- }
- }
- };
-
- mSetPathString = data.getString(KEY_MEDIA_SET_PATH);
- mOriginalSetPathString = mSetPathString;
- setupNfcBeamPush();
- String itemPathString = data.getString(KEY_MEDIA_ITEM_PATH);
- Path itemPath = itemPathString != null ?
- Path.fromString(data.getString(KEY_MEDIA_ITEM_PATH)) :
- null;
- mTreatBackAsUp = data.getBoolean(KEY_TREAT_BACK_AS_UP, false);
- mStartInFilmstrip = data.getBoolean(KEY_START_IN_FILMSTRIP, false);
- boolean inCameraRoll = data.getBoolean(KEY_IN_CAMERA_ROLL, false);
- mCurrentIndex = data.getInt(KEY_INDEX_HINT, 0);
- if (mSetPathString != null) {
- mShowSpinner = true;
- mAppBridge = (AppBridge) data.getParcelable(KEY_APP_BRIDGE);
- if (mAppBridge != null) {
- mShowBars = false;
- mHasCameraScreennailOrPlaceholder = true;
- mAppBridge.setServer(this);
-
- // Get the ScreenNail from AppBridge and register it.
- int id = SnailSource.newId();
- Path screenNailSetPath = SnailSource.getSetPath(id);
- Path screenNailItemPath = SnailSource.getItemPath(id);
- mScreenNailSet = (SnailAlbum) mActivity.getDataManager()
- .getMediaObject(screenNailSetPath);
- mScreenNailItem = (SnailItem) mActivity.getDataManager()
- .getMediaObject(screenNailItemPath);
- mScreenNailItem.setScreenNail(mAppBridge.attachScreenNail());
-
- if (data.getBoolean(KEY_SHOW_WHEN_LOCKED, false)) {
- // Set the flag to be on top of the lock screen.
- mFlags |= FLAG_SHOW_WHEN_LOCKED;
- }
-
- // Don't display "empty album" action item for capture intents.
- if (!mSetPathString.equals("/local/all/0")) {
- // Check if the path is a secure album.
- if (SecureSource.isSecurePath(mSetPathString)) {
- mSecureAlbum = (SecureAlbum) mActivity.getDataManager()
- .getMediaSet(mSetPathString);
- mShowSpinner = false;
- }
- mSetPathString = "/filter/empty/{"+mSetPathString+"}";
- }
-
- // Combine the original MediaSet with the one for ScreenNail
- // from AppBridge.
- mSetPathString = "/combo/item/{" + screenNailSetPath +
- "," + mSetPathString + "}";
-
- // Start from the screen nail.
- itemPath = screenNailItemPath;
- } else if (inCameraRoll && GalleryUtils.isCameraAvailable(mActivity)) {
- mSetPathString = "/combo/item/{" + FilterSource.FILTER_CAMERA_SHORTCUT +
- "," + mSetPathString + "}";
- mCurrentIndex++;
- mHasCameraScreennailOrPlaceholder = true;
- }
-
- MediaSet originalSet = mActivity.getDataManager()
- .getMediaSet(mSetPathString);
- if (mHasCameraScreennailOrPlaceholder && originalSet instanceof ComboAlbum) {
- // Use the name of the camera album rather than the default
- // ComboAlbum behavior
- ((ComboAlbum) originalSet).useNameOfChild(1);
- }
- mSelectionManager.setSourceMediaSet(originalSet);
- mSetPathString = "/filter/delete/{" + mSetPathString + "}";
- mMediaSet = (FilterDeleteSet) mActivity.getDataManager()
- .getMediaSet(mSetPathString);
- if (mMediaSet == null) {
- Log.w(TAG, "failed to restore " + mSetPathString);
- }
- if (itemPath == null) {
- int mediaItemCount = mMediaSet.getMediaItemCount();
- if (mediaItemCount > 0) {
- if (mCurrentIndex >= mediaItemCount) mCurrentIndex = 0;
- itemPath = mMediaSet.getMediaItem(mCurrentIndex, 1)
- .get(0).getPath();
- } else {
- // Bail out, PhotoPage can't load on an empty album
- return;
- }
- }
- PhotoDataAdapter pda = new PhotoDataAdapter(
- mActivity, mPhotoView, mMediaSet, itemPath, mCurrentIndex,
- mAppBridge == null ? -1 : 0,
- mAppBridge == null ? false : mAppBridge.isPanorama(),
- mAppBridge == null ? false : mAppBridge.isStaticCamera());
- mModel = pda;
- mPhotoView.setModel(mModel);
-
- pda.setDataListener(new PhotoDataAdapter.DataListener() {
-
- @Override
- public void onPhotoChanged(int index, Path item) {
- int oldIndex = mCurrentIndex;
- mCurrentIndex = index;
-
- if (mHasCameraScreennailOrPlaceholder) {
- if (mCurrentIndex > 0) {
- mSkipUpdateCurrentPhoto = false;
- }
-
- if (oldIndex == 0 && mCurrentIndex > 0
- && !mPhotoView.getFilmMode()) {
- mPhotoView.setFilmMode(true);
- if (mAppBridge != null) {
- UsageStatistics.onEvent("CameraToFilmstrip",
- UsageStatistics.TRANSITION_SWIPE, null);
- }
- } else if (oldIndex == 2 && mCurrentIndex == 1) {
- mCameraSwitchCutoff = SystemClock.uptimeMillis() +
- CAMERA_SWITCH_CUTOFF_THRESHOLD_MS;
- mPhotoView.stopScrolling();
- } else if (oldIndex >= 1 && mCurrentIndex == 0) {
- mPhotoView.setWantPictureCenterCallbacks(true);
- mSkipUpdateCurrentPhoto = true;
- }
- }
- if (!mSkipUpdateCurrentPhoto) {
- if (item != null) {
- MediaItem photo = mModel.getMediaItem(0);
- if (photo != null) updateCurrentPhoto(photo);
- }
- updateBars();
- }
- // Reset the timeout for the bars after a swipe
- refreshHidingMessage();
- }
-
- @Override
- public void onLoadingFinished(boolean loadingFailed) {
- if (!mModel.isEmpty()) {
- MediaItem photo = mModel.getMediaItem(0);
- if (photo != null) updateCurrentPhoto(photo);
- } else if (mIsActive) {
- // We only want to finish the PhotoPage if there is no
- // deletion that the user can undo.
- if (mMediaSet.getNumberOfDeletions() == 0) {
- mActivity.getStateManager().finishState(
- PhotoPage.this);
- }
- }
- }
-
- @Override
- public void onLoadingStarted() {
- }
- });
- } else {
- // Get default media set by the URI
- MediaItem mediaItem = (MediaItem)
- mActivity.getDataManager().getMediaObject(itemPath);
- mModel = new SinglePhotoDataAdapter(mActivity, mPhotoView, mediaItem);
- mPhotoView.setModel(mModel);
- updateCurrentPhoto(mediaItem);
- mShowSpinner = false;
- }
-
- mPhotoView.setFilmMode(mStartInFilmstrip && mMediaSet.getMediaItemCount() > 1);
- RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity)
- .findViewById(mAppBridge != null ? R.id.content : R.id.gallery_root);
- if (galleryRoot != null) {
- if (mSecureAlbum == null) {
- mBottomControls = new PhotoPageBottomControls(this, mActivity, galleryRoot);
- }
- StitchingProgressManager progressManager = mApplication.getStitchingProgressManager();
- if (progressManager != null) {
- mProgressBar = new PhotoPageProgressBar(mActivity, galleryRoot);
- mProgressListener = new UpdateProgressListener();
- progressManager.addChangeListener(mProgressListener);
- if (mSecureAlbum != null) {
- progressManager.addChangeListener(mSecureAlbum);
- }
- }
- }
- }
-
- @Override
- public void onPictureCenter(boolean isCamera) {
- isCamera = isCamera || (mHasCameraScreennailOrPlaceholder && mAppBridge == null);
- mPhotoView.setWantPictureCenterCallbacks(false);
- mHandler.removeMessages(MSG_ON_CAMERA_CENTER);
- mHandler.removeMessages(MSG_ON_PICTURE_CENTER);
- mHandler.sendEmptyMessage(isCamera ? MSG_ON_CAMERA_CENTER : MSG_ON_PICTURE_CENTER);
- }
-
- @Override
- public boolean canDisplayBottomControls() {
- return mIsActive && !mPhotoView.canUndo();
- }
-
- @Override
- public boolean canDisplayBottomControl(int control) {
- if (mCurrentPhoto == null) {
- return false;
- }
- switch(control) {
- case R.id.photopage_bottom_control_edit:
- return mHaveImageEditor && mShowBars
- && !mPhotoView.getFilmMode()
- && (mCurrentPhoto.getSupportedOperations() & MediaItem.SUPPORT_EDIT) != 0
- && mCurrentPhoto.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE;
- case R.id.photopage_bottom_control_panorama:
- return mIsPanorama;
- case R.id.photopage_bottom_control_tiny_planet:
- return mHaveImageEditor && mShowBars
- && mIsPanorama360 && !mPhotoView.getFilmMode();
- default:
- return false;
- }
- }
-
- @Override
- public void onBottomControlClicked(int control) {
- switch(control) {
- case R.id.photopage_bottom_control_edit:
- launchPhotoEditor();
- return;
- case R.id.photopage_bottom_control_panorama:
- mActivity.getPanoramaViewHelper()
- .showPanorama(mCurrentPhoto.getContentUri());
- return;
- case R.id.photopage_bottom_control_tiny_planet:
- launchTinyPlanet();
- return;
- default:
- return;
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private void setupNfcBeamPush() {
- if (!ApiHelper.HAS_SET_BEAM_PUSH_URIS) return;
-
- NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mActivity);
- if (adapter != null) {
- adapter.setBeamPushUris(null, mActivity);
- adapter.setBeamPushUrisCallback(new CreateBeamUrisCallback() {
- @Override
- public Uri[] createBeamUris(NfcEvent event) {
- return mNfcPushUris;
- }
- }, mActivity);
- }
- }
-
- private void setNfcBeamPushUri(Uri uri) {
- mNfcPushUris[0] = uri;
- }
-
- private static Intent createShareIntent(MediaObject mediaObject) {
- int type = mediaObject.getMediaType();
- return new Intent(Intent.ACTION_SEND)
- .setType(MenuExecutor.getMimeType(type))
- .putExtra(Intent.EXTRA_STREAM, mediaObject.getContentUri())
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- }
-
- private static Intent createSharePanoramaIntent(Uri contentUri) {
- return new Intent(Intent.ACTION_SEND)
- .setType(GalleryUtils.MIME_TYPE_PANORAMA360)
- .putExtra(Intent.EXTRA_STREAM, contentUri)
- .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- }
-
- private void overrideTransitionToEditor() {
- ((Activity) mActivity).overridePendingTransition(android.R.anim.fade_in,
- android.R.anim.fade_out);
- }
-
- private void launchTinyPlanet() {
- // Deep link into tiny planet
- MediaItem current = mModel.getMediaItem(0);
- Intent intent = new Intent(FilterShowActivity.TINY_PLANET_ACTION);
- intent.setClass(mActivity, FilterShowActivity.class);
- intent.setDataAndType(current.getContentUri(), current.getMimeType())
- .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.putExtra(FilterShowActivity.LAUNCH_FULLSCREEN,
- mActivity.isFullscreen());
- mActivity.startActivityForResult(intent, REQUEST_EDIT);
- overrideTransitionToEditor();
- }
-
- private void launchCamera() {
- Intent intent = new Intent(mActivity, CameraActivity.class)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mRecenterCameraOnResume = false;
- mActivity.startActivity(intent);
- }
-
- private void launchPhotoEditor() {
- MediaItem current = mModel.getMediaItem(0);
- if (current == null || (current.getSupportedOperations()
- & MediaObject.SUPPORT_EDIT) == 0) {
- return;
- }
-
- Intent intent = new Intent(ACTION_NEXTGEN_EDIT);
-
- intent.setDataAndType(current.getContentUri(), current.getMimeType())
- .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- if (mActivity.getPackageManager()
- .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() == 0) {
- intent.setAction(Intent.ACTION_EDIT);
- }
- intent.putExtra(FilterShowActivity.LAUNCH_FULLSCREEN,
- mActivity.isFullscreen());
- ((Activity) mActivity).startActivityForResult(Intent.createChooser(intent, null),
- REQUEST_EDIT);
- overrideTransitionToEditor();
- }
-
- private void launchSimpleEditor() {
- MediaItem current = mModel.getMediaItem(0);
- if (current == null || (current.getSupportedOperations()
- & MediaObject.SUPPORT_EDIT) == 0) {
- return;
- }
-
- Intent intent = new Intent(ACTION_SIMPLE_EDIT);
-
- intent.setDataAndType(current.getContentUri(), current.getMimeType())
- .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- if (mActivity.getPackageManager()
- .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() == 0) {
- intent.setAction(Intent.ACTION_EDIT);
- }
- intent.putExtra(FilterShowActivity.LAUNCH_FULLSCREEN,
- mActivity.isFullscreen());
- ((Activity) mActivity).startActivityForResult(Intent.createChooser(intent, null),
- REQUEST_EDIT);
- overrideTransitionToEditor();
- }
-
- private void requestDeferredUpdate() {
- mDeferUpdateUntil = SystemClock.uptimeMillis() + DEFERRED_UPDATE_MS;
- if (!mDeferredUpdateWaiting) {
- mDeferredUpdateWaiting = true;
- mHandler.sendEmptyMessageDelayed(MSG_UPDATE_DEFERRED, DEFERRED_UPDATE_MS);
- }
- }
-
- private void updateUIForCurrentPhoto() {
- if (mCurrentPhoto == null) return;
-
- // If by swiping or deletion the user ends up on an action item
- // and zoomed in, zoom out so that the context of the action is
- // more clear
- if ((mCurrentPhoto.getSupportedOperations() & MediaObject.SUPPORT_ACTION) != 0
- && !mPhotoView.getFilmMode()) {
- mPhotoView.setWantPictureCenterCallbacks(true);
- }
-
- updateMenuOperations();
- refreshBottomControlsWhenReady();
- if (mShowDetails) {
- mDetailsHelper.reloadDetails();
- }
- if ((mSecureAlbum == null)
- && (mCurrentPhoto.getSupportedOperations() & MediaItem.SUPPORT_SHARE) != 0) {
- mCurrentPhoto.getPanoramaSupport(mUpdateShareURICallback);
- }
- updateProgressBar();
- }
-
- private void updateCurrentPhoto(MediaItem photo) {
- if (mCurrentPhoto == photo) return;
- mCurrentPhoto = photo;
- if (mPhotoView.getFilmMode()) {
- requestDeferredUpdate();
- } else {
- updateUIForCurrentPhoto();
- }
- }
-
- private void updateProgressBar() {
- if (mProgressBar != null) {
- mProgressBar.hideProgress();
- StitchingProgressManager progressManager = mApplication.getStitchingProgressManager();
- if (progressManager != null && mCurrentPhoto instanceof LocalImage) {
- Integer progress = progressManager.getProgress(mCurrentPhoto.getContentUri());
- if (progress != null) {
- mProgressBar.setProgress(progress);
- }
- }
- }
- }
-
- private void updateMenuOperations() {
- Menu menu = mActionBar.getMenu();
-
- // it could be null if onCreateActionBar has not been called yet
- if (menu == null) return;
-
- MenuItem item = menu.findItem(R.id.action_slideshow);
- if (item != null) {
- item.setVisible((mSecureAlbum == null) && canDoSlideShow());
- }
- if (mCurrentPhoto == null) return;
-
- int supportedOperations = mCurrentPhoto.getSupportedOperations();
- if (mSecureAlbum != null) {
- supportedOperations &= MediaObject.SUPPORT_DELETE;
- } else {
- mCurrentPhoto.getPanoramaSupport(mUpdatePanoramaMenuItemsCallback);
- if (!mHaveImageEditor) {
- supportedOperations &= ~MediaObject.SUPPORT_EDIT;
- }
- }
- MenuExecutor.updateMenuOperation(menu, supportedOperations);
- }
-
- private boolean canDoSlideShow() {
- if (mMediaSet == null || mCurrentPhoto == null) {
- return false;
- }
- if (mCurrentPhoto.getMediaType() != MediaObject.MEDIA_TYPE_IMAGE) {
- return false;
- }
- return true;
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Action Bar show/hide management
- //////////////////////////////////////////////////////////////////////////
-
- private void showBars() {
- if (mShowBars) return;
- mShowBars = true;
- mOrientationManager.unlockOrientation();
- mActionBar.show();
- mActivity.getGLRoot().setLightsOutMode(false);
- refreshHidingMessage();
- refreshBottomControlsWhenReady();
- }
-
- private void hideBars() {
- if (!mShowBars) return;
- mShowBars = false;
- mActionBar.hide();
- mActivity.getGLRoot().setLightsOutMode(true);
- mHandler.removeMessages(MSG_HIDE_BARS);
- refreshBottomControlsWhenReady();
- }
-
- private void refreshHidingMessage() {
- mHandler.removeMessages(MSG_HIDE_BARS);
- if (!mIsMenuVisible && !mPhotoView.getFilmMode()) {
- mHandler.sendEmptyMessageDelayed(MSG_HIDE_BARS, HIDE_BARS_TIMEOUT);
- }
- }
-
- private boolean canShowBars() {
- // No bars if we are showing camera preview.
- if (mAppBridge != null && mCurrentIndex == 0
- && !mPhotoView.getFilmMode()) return false;
-
- // No bars if it's not allowed.
- if (!mActionBarAllowed) return false;
-
- Configuration config = mActivity.getResources().getConfiguration();
- if (config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH) {
- return false;
- }
-
- return true;
- }
-
- private void wantBars() {
- if (canShowBars()) showBars();
- }
-
- private void toggleBars() {
- if (mShowBars) {
- hideBars();
- } else {
- if (canShowBars()) showBars();
- }
- }
-
- private void updateBars() {
- if (!canShowBars()) {
- hideBars();
- }
- }
-
- @Override
- protected void onBackPressed() {
- if (mShowDetails) {
- hideDetails();
- } else if (mAppBridge == null || !switchWithCaptureAnimation(-1)) {
- // We are leaving this page. Set the result now.
- setResult();
- if (mStartInFilmstrip && !mPhotoView.getFilmMode()) {
- mPhotoView.setFilmMode(true);
- } else if (mTreatBackAsUp) {
- onUpPressed();
- } else {
- super.onBackPressed();
- }
- }
- }
-
- private void onUpPressed() {
- if ((mStartInFilmstrip || mAppBridge != null)
- && !mPhotoView.getFilmMode()) {
- mPhotoView.setFilmMode(true);
- return;
- }
-
- if (mActivity.getStateManager().getStateCount() > 1) {
- setResult();
- super.onBackPressed();
- return;
- }
-
- if (mOriginalSetPathString == null) return;
-
- if (mAppBridge == null) {
- // We're in view mode so set up the stacks on our own.
- Bundle data = new Bundle(getData());
- data.putString(AlbumPage.KEY_MEDIA_PATH, mOriginalSetPathString);
- data.putString(AlbumPage.KEY_PARENT_MEDIA_PATH,
- mActivity.getDataManager().getTopSetPath(
- DataManager.INCLUDE_ALL));
- mActivity.getStateManager().switchState(this, AlbumPage.class, data);
- } else {
- GalleryUtils.startGalleryActivity(mActivity);
- }
- }
-
- private void setResult() {
- Intent result = null;
- result = new Intent();
- result.putExtra(KEY_RETURN_INDEX_HINT, mCurrentIndex);
- setStateResult(Activity.RESULT_OK, result);
- }
-
- //////////////////////////////////////////////////////////////////////////
- // AppBridge.Server interface
- //////////////////////////////////////////////////////////////////////////
-
- @Override
- public void setCameraRelativeFrame(Rect frame) {
- mPhotoView.setCameraRelativeFrame(frame);
- }
-
- @Override
- public boolean switchWithCaptureAnimation(int offset) {
- return mPhotoView.switchWithCaptureAnimation(offset);
- }
-
- @Override
- public void setSwipingEnabled(boolean enabled) {
- mPhotoView.setSwipingEnabled(enabled);
- }
-
- @Override
- public void notifyScreenNailChanged() {
- mScreenNailItem.setScreenNail(mAppBridge.attachScreenNail());
- mScreenNailSet.notifyChange();
- }
-
- @Override
- public void addSecureAlbumItem(boolean isVideo, int id) {
- mSecureAlbum.addMediaItem(isVideo, id);
- }
-
- @Override
- protected boolean onCreateActionBar(Menu menu) {
- mActionBar.createActionBarMenu(R.menu.photo, menu);
- mHaveImageEditor = GalleryUtils.isEditorAvailable(mActivity, "image/*");
- updateMenuOperations();
- mActionBar.setTitle(mMediaSet != null ? mMediaSet.getName() : "");
- return true;
- }
-
- private MenuExecutor.ProgressListener mConfirmDialogListener =
- new MenuExecutor.ProgressListener() {
- @Override
- public void onProgressUpdate(int index) {}
-
- @Override
- public void onProgressComplete(int result) {}
-
- @Override
- public void onConfirmDialogShown() {
- mHandler.removeMessages(MSG_HIDE_BARS);
- }
-
- @Override
- public void onConfirmDialogDismissed(boolean confirmed) {
- refreshHidingMessage();
- }
-
- @Override
- public void onProgressStart() {}
- };
-
- private void switchToGrid() {
- if (mActivity.getStateManager().hasStateClass(AlbumPage.class)) {
- onUpPressed();
- } else {
- if (mOriginalSetPathString == null) return;
- if (mProgressBar != null) {
- updateCurrentPhoto(null);
- mProgressBar.hideProgress();
- }
- Bundle data = new Bundle(getData());
- data.putString(AlbumPage.KEY_MEDIA_PATH, mOriginalSetPathString);
- data.putString(AlbumPage.KEY_PARENT_MEDIA_PATH,
- mActivity.getDataManager().getTopSetPath(
- DataManager.INCLUDE_ALL));
-
- // We only show cluster menu in the first AlbumPage in stack
- // TODO: Enable this when running from the camera app
- boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
- data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum
- && mAppBridge == null);
-
- data.putBoolean(PhotoPage.KEY_APP_BRIDGE, mAppBridge != null);
-
- // Account for live preview being first item
- mActivity.getTransitionStore().put(KEY_RETURN_INDEX_HINT,
- mAppBridge != null ? mCurrentIndex - 1 : mCurrentIndex);
-
- if (mHasCameraScreennailOrPlaceholder && mAppBridge != null) {
- mActivity.getStateManager().startState(AlbumPage.class, data);
- } else {
- mActivity.getStateManager().switchState(this, AlbumPage.class, data);
- }
- }
- }
-
- @Override
- protected boolean onItemSelected(MenuItem item) {
- if (mModel == null) return true;
- refreshHidingMessage();
- MediaItem current = mModel.getMediaItem(0);
-
- // This is a shield for monkey when it clicks the action bar
- // menu when transitioning from filmstrip to camera
- if (current instanceof SnailItem) return true;
- // TODO: We should check the current photo against the MediaItem
- // that the menu was initially created for. We need to fix this
- // after PhotoPage being refactored.
- if (current == null) {
- // item is not ready, ignore
- return true;
- }
- int currentIndex = mModel.getCurrentIndex();
- Path path = current.getPath();
-
- DataManager manager = mActivity.getDataManager();
- int action = item.getItemId();
- String confirmMsg = null;
- switch (action) {
- case android.R.id.home: {
- onUpPressed();
- return true;
- }
- case R.id.action_slideshow: {
- Bundle data = new Bundle();
- data.putString(SlideshowPage.KEY_SET_PATH, mMediaSet.getPath().toString());
- data.putString(SlideshowPage.KEY_ITEM_PATH, path.toString());
- data.putInt(SlideshowPage.KEY_PHOTO_INDEX, currentIndex);
- data.putBoolean(SlideshowPage.KEY_REPEAT, true);
- mActivity.getStateManager().startStateForResult(
- SlideshowPage.class, REQUEST_SLIDESHOW, data);
- return true;
- }
- case R.id.action_crop: {
- Activity activity = mActivity;
- Intent intent = new Intent(CropActivity.CROP_ACTION);
- intent.setClass(activity, CropActivity.class);
- intent.setDataAndType(manager.getContentUri(path), current.getMimeType())
- .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- activity.startActivityForResult(intent, PicasaSource.isPicasaImage(current)
- ? REQUEST_CROP_PICASA
- : REQUEST_CROP);
- return true;
- }
- case R.id.action_trim: {
- Intent intent = new Intent(mActivity, TrimVideo.class);
- intent.setData(manager.getContentUri(path));
- // We need the file path to wrap this into a RandomAccessFile.
- intent.putExtra(KEY_MEDIA_ITEM_PATH, current.getFilePath());
- mActivity.startActivityForResult(intent, REQUEST_TRIM);
- return true;
- }
- case R.id.action_mute: {
- MuteVideo muteVideo = new MuteVideo(current.getFilePath(),
- manager.getContentUri(path), mActivity);
- muteVideo.muteInBackground();
- return true;
- }
- case R.id.action_edit: {
- launchPhotoEditor();
- return true;
- }
- case R.id.action_simple_edit: {
- launchSimpleEditor();
- return true;
- }
- case R.id.action_details: {
- if (mShowDetails) {
- hideDetails();
- } else {
- showDetails();
- }
- return true;
- }
- case R.id.action_delete:
- confirmMsg = mActivity.getResources().getQuantityString(
- R.plurals.delete_selection, 1);
- case R.id.action_setas:
- case R.id.action_rotate_ccw:
- case R.id.action_rotate_cw:
- case R.id.action_show_on_map:
- mSelectionManager.deSelectAll();
- mSelectionManager.toggle(path);
- mMenuExecutor.onMenuClicked(item, confirmMsg, mConfirmDialogListener);
- return true;
- default :
- return false;
- }
- }
-
- private void hideDetails() {
- mShowDetails = false;
- mDetailsHelper.hide();
- }
-
- private void showDetails() {
- mShowDetails = true;
- if (mDetailsHelper == null) {
- mDetailsHelper = new DetailsHelper(mActivity, mRootPane, new MyDetailsSource());
- mDetailsHelper.setCloseListener(new CloseListener() {
- @Override
- public void onClose() {
- hideDetails();
- }
- });
- }
- mDetailsHelper.show();
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // Callbacks from PhotoView
- ////////////////////////////////////////////////////////////////////////////
- @Override
- public void onSingleTapUp(int x, int y) {
- if (mAppBridge != null) {
- if (mAppBridge.onSingleTapUp(x, y)) return;
- }
-
- MediaItem item = mModel.getMediaItem(0);
- if (item == null || item == mScreenNailItem) {
- // item is not ready or it is camera preview, ignore
- return;
- }
-
- int supported = item.getSupportedOperations();
- boolean playVideo = ((supported & MediaItem.SUPPORT_PLAY) != 0);
- boolean unlock = ((supported & MediaItem.SUPPORT_UNLOCK) != 0);
- boolean goBack = ((supported & MediaItem.SUPPORT_BACK) != 0);
- boolean launchCamera = ((supported & MediaItem.SUPPORT_CAMERA_SHORTCUT) != 0);
-
- if (playVideo) {
- // determine if the point is at center (1/6) of the photo view.
- // (The position of the "play" icon is at center (1/6) of the photo)
- int w = mPhotoView.getWidth();
- int h = mPhotoView.getHeight();
- playVideo = (Math.abs(x - w / 2) * 12 <= w)
- && (Math.abs(y - h / 2) * 12 <= h);
- }
-
- if (playVideo) {
- if (mSecureAlbum == null) {
- playVideo(mActivity, item.getPlayUri(), item.getName());
- } else {
- mActivity.getStateManager().finishState(this);
- }
- } else if (goBack) {
- onBackPressed();
- } else if (unlock) {
- Intent intent = new Intent(mActivity, Gallery.class);
- intent.putExtra(Gallery.KEY_DISMISS_KEYGUARD, true);
- mActivity.startActivity(intent);
- } else if (launchCamera) {
- launchCamera();
- } else {
- toggleBars();
- }
- }
-
- @Override
- public void onActionBarAllowed(boolean allowed) {
- mActionBarAllowed = allowed;
- mHandler.sendEmptyMessage(MSG_UPDATE_ACTION_BAR);
- }
-
- @Override
- public void onActionBarWanted() {
- mHandler.sendEmptyMessage(MSG_WANT_BARS);
- }
-
- @Override
- public void onFullScreenChanged(boolean full) {
- Message m = mHandler.obtainMessage(
- MSG_ON_FULL_SCREEN_CHANGED, full ? 1 : 0, 0);
- m.sendToTarget();
- }
-
- // How we do delete/undo:
- //
- // When the user choose to delete a media item, we just tell the
- // FilterDeleteSet to hide that item. If the user choose to undo it, we
- // again tell FilterDeleteSet not to hide it. If the user choose to commit
- // the deletion, we then actually delete the media item.
- @Override
- public void onDeleteImage(Path path, int offset) {
- onCommitDeleteImage(); // commit the previous deletion
- mDeletePath = path;
- mDeleteIsFocus = (offset == 0);
- mMediaSet.addDeletion(path, mCurrentIndex + offset);
- }
-
- @Override
- public void onUndoDeleteImage() {
- if (mDeletePath == null) return;
- // If the deletion was done on the focused item, we want the model to
- // focus on it when it is undeleted.
- if (mDeleteIsFocus) mModel.setFocusHintPath(mDeletePath);
- mMediaSet.removeDeletion(mDeletePath);
- mDeletePath = null;
- }
-
- @Override
- public void onCommitDeleteImage() {
- if (mDeletePath == null) return;
- mMenuExecutor.startSingleItemAction(R.id.action_delete, mDeletePath);
- mDeletePath = null;
- }
-
- public void playVideo(Activity activity, Uri uri, String title) {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW)
- .setDataAndType(uri, "video/*")
- .putExtra(Intent.EXTRA_TITLE, title)
- .putExtra(MovieActivity.KEY_TREAT_UP_AS_BACK, true);
- activity.startActivityForResult(intent, REQUEST_PLAY_VIDEO);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(activity, activity.getString(R.string.video_err),
- Toast.LENGTH_SHORT).show();
- }
- }
-
- private void setCurrentPhotoByIntent(Intent intent) {
- if (intent == null) return;
- Path path = mApplication.getDataManager()
- .findPathByUri(intent.getData(), intent.getType());
- if (path != null) {
- Path albumPath = mApplication.getDataManager().getDefaultSetOf(path);
- if (!albumPath.equalsIgnoreCase(mOriginalSetPathString)) {
- // If the edited image is stored in a different album, we need
- // to start a new activity state to show the new image
- Bundle data = new Bundle(getData());
- data.putString(KEY_MEDIA_SET_PATH, albumPath.toString());
- data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path.toString());
- mActivity.getStateManager().startState(SinglePhotoPage.class, data);
- return;
- }
- mModel.setCurrentPhoto(path, mCurrentIndex);
- }
- }
-
- @Override
- protected void onStateResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == Activity.RESULT_CANCELED) {
- // This is a reset, not a canceled
- return;
- }
- if (resultCode == ProxyLauncher.RESULT_USER_CANCELED) {
- // Unmap reset vs. canceled
- resultCode = Activity.RESULT_CANCELED;
- }
- mRecenterCameraOnResume = false;
- switch (requestCode) {
- case REQUEST_EDIT:
- setCurrentPhotoByIntent(data);
- break;
- case REQUEST_CROP:
- if (resultCode == Activity.RESULT_OK) {
- setCurrentPhotoByIntent(data);
- }
- break;
- case REQUEST_CROP_PICASA: {
- if (resultCode == Activity.RESULT_OK) {
- Context context = mActivity.getAndroidContext();
- String message = context.getString(R.string.crop_saved,
- context.getString(R.string.folder_edited_online_photos));
- Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
- }
- break;
- }
- case REQUEST_SLIDESHOW: {
- if (data == null) break;
- String path = data.getStringExtra(SlideshowPage.KEY_ITEM_PATH);
- int index = data.getIntExtra(SlideshowPage.KEY_PHOTO_INDEX, 0);
- if (path != null) {
- mModel.setCurrentPhoto(Path.fromString(path), index);
- }
- }
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mIsActive = false;
-
- mActivity.getGLRoot().unfreeze();
- mHandler.removeMessages(MSG_UNFREEZE_GLROOT);
-
- DetailsHelper.pause();
- // Hide the detail dialog on exit
- if (mShowDetails) hideDetails();
- if (mModel != null) {
- mModel.pause();
- }
- mPhotoView.pause();
- mHandler.removeMessages(MSG_HIDE_BARS);
- mHandler.removeMessages(MSG_REFRESH_BOTTOM_CONTROLS);
- refreshBottomControlsWhenReady();
- mActionBar.removeOnMenuVisibilityListener(mMenuVisibilityListener);
- if (mShowSpinner) {
- mActionBar.disableAlbumModeMenu(true);
- }
- onCommitDeleteImage();
- mMenuExecutor.pause();
- if (mMediaSet != null) mMediaSet.clearDeletion();
- }
-
- @Override
- public void onCurrentImageUpdated() {
- mActivity.getGLRoot().unfreeze();
- }
-
- @Override
- public void onFilmModeChanged(boolean enabled) {
- refreshBottomControlsWhenReady();
- if (mShowSpinner) {
- if (enabled) {
- mActionBar.enableAlbumModeMenu(
- GalleryActionBar.ALBUM_FILMSTRIP_MODE_SELECTED, this);
- } else {
- mActionBar.disableAlbumModeMenu(true);
- }
- }
- if (enabled) {
- mHandler.removeMessages(MSG_HIDE_BARS);
- UsageStatistics.onContentViewChanged(
- UsageStatistics.COMPONENT_GALLERY, "FilmstripPage");
- } else {
- refreshHidingMessage();
- if (mAppBridge == null || mCurrentIndex > 0) {
- UsageStatistics.onContentViewChanged(
- UsageStatistics.COMPONENT_GALLERY, "SinglePhotoPage");
- } else {
- UsageStatistics.onContentViewChanged(
- UsageStatistics.COMPONENT_CAMERA, "Unknown"); // TODO
- }
- }
- }
-
- private void transitionFromAlbumPageIfNeeded() {
- TransitionStore transitions = mActivity.getTransitionStore();
-
- int albumPageTransition = transitions.get(
- KEY_ALBUMPAGE_TRANSITION, MSG_ALBUMPAGE_NONE);
-
- if (albumPageTransition == MSG_ALBUMPAGE_NONE && mAppBridge != null
- && mRecenterCameraOnResume) {
- // Generally, resuming the PhotoPage when in Camera should
- // reset to the capture mode to allow quick photo taking
- mCurrentIndex = 0;
- mPhotoView.resetToFirstPicture();
- } else {
- int resumeIndex = transitions.get(KEY_INDEX_HINT, -1);
- if (resumeIndex >= 0) {
- if (mHasCameraScreennailOrPlaceholder) {
- // Account for preview/placeholder being the first item
- resumeIndex++;
- }
- if (resumeIndex < mMediaSet.getMediaItemCount()) {
- mCurrentIndex = resumeIndex;
- mModel.moveTo(mCurrentIndex);
- }
- }
- }
-
- if (albumPageTransition == MSG_ALBUMPAGE_RESUMED) {
- mPhotoView.setFilmMode(mStartInFilmstrip || mAppBridge != null);
- } else if (albumPageTransition == MSG_ALBUMPAGE_PICKED) {
- mPhotoView.setFilmMode(false);
- }
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- if (mModel == null) {
- mActivity.getStateManager().finishState(this);
- return;
- }
- transitionFromAlbumPageIfNeeded();
-
- mActivity.getGLRoot().freeze();
- mIsActive = true;
- setContentPane(mRootPane);
-
- mModel.resume();
- mPhotoView.resume();
- mActionBar.setDisplayOptions(
- ((mSecureAlbum == null) && (mSetPathString != null)), false);
- mActionBar.addOnMenuVisibilityListener(mMenuVisibilityListener);
- refreshBottomControlsWhenReady();
- if (mShowSpinner && mPhotoView.getFilmMode()) {
- mActionBar.enableAlbumModeMenu(
- GalleryActionBar.ALBUM_FILMSTRIP_MODE_SELECTED, this);
- }
- if (!mShowBars) {
- mActionBar.hide();
- mActivity.getGLRoot().setLightsOutMode(true);
- }
- boolean haveImageEditor = GalleryUtils.isEditorAvailable(mActivity, "image/*");
- if (haveImageEditor != mHaveImageEditor) {
- mHaveImageEditor = haveImageEditor;
- updateMenuOperations();
- }
-
- mRecenterCameraOnResume = true;
- mHandler.sendEmptyMessageDelayed(MSG_UNFREEZE_GLROOT, UNFREEZE_GLROOT_TIMEOUT);
- }
-
- @Override
- protected void onDestroy() {
- if (mAppBridge != null) {
- mAppBridge.setServer(null);
- mScreenNailItem.setScreenNail(null);
- mAppBridge.detachScreenNail();
- mAppBridge = null;
- mScreenNailSet = null;
- mScreenNailItem = null;
- }
- mActivity.getGLRoot().setOrientationSource(null);
- if (mBottomControls != null) mBottomControls.cleanup();
-
- // Remove all pending messages.
- mHandler.removeCallbacksAndMessages(null);
- super.onDestroy();
- }
-
- private class MyDetailsSource implements DetailsSource {
-
- @Override
- public MediaDetails getDetails() {
- return mModel.getMediaItem(0).getDetails();
- }
-
- @Override
- public int size() {
- return mMediaSet != null ? mMediaSet.getMediaItemCount() : 1;
- }
-
- @Override
- public int setIndex() {
- return mModel.getCurrentIndex();
- }
- }
-
- @Override
- public void onAlbumModeSelected(int mode) {
- if (mode == GalleryActionBar.ALBUM_GRID_MODE_SELECTED) {
- switchToGrid();
- }
- }
-
- @Override
- public void refreshBottomControlsWhenReady() {
- if (mBottomControls == null) {
- return;
- }
- MediaObject currentPhoto = mCurrentPhoto;
- if (currentPhoto == null) {
- mHandler.obtainMessage(MSG_REFRESH_BOTTOM_CONTROLS, 0, 0, currentPhoto).sendToTarget();
- } else {
- currentPhoto.getPanoramaSupport(mRefreshBottomControlsCallback);
- }
- }
-
- private void updatePanoramaUI(boolean isPanorama360) {
- Menu menu = mActionBar.getMenu();
-
- // it could be null if onCreateActionBar has not been called yet
- if (menu == null) {
- return;
- }
-
- MenuExecutor.updateMenuForPanorama(menu, isPanorama360, isPanorama360);
-
- if (isPanorama360) {
- MenuItem item = menu.findItem(R.id.action_share);
- if (item != null) {
- item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- item.setTitle(mActivity.getResources().getString(R.string.share_as_photo));
- }
- } else if ((mCurrentPhoto.getSupportedOperations() & MediaObject.SUPPORT_SHARE) != 0) {
- MenuItem item = menu.findItem(R.id.action_share);
- if (item != null) {
- item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
- item.setTitle(mActivity.getResources().getString(R.string.share));
- }
- }
- }
-
- @Override
- public void onUndoBarVisibilityChanged(boolean visible) {
- refreshBottomControlsWhenReady();
- }
-
- @Override
- public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
- final long timestampMillis = mCurrentPhoto.getDateInMs();
- final String mediaType = getMediaTypeString(mCurrentPhoto);
- UsageStatistics.onEvent(UsageStatistics.COMPONENT_GALLERY,
- UsageStatistics.ACTION_SHARE,
- mediaType,
- timestampMillis > 0
- ? System.currentTimeMillis() - timestampMillis
- : -1);
- return false;
- }
-
- private static String getMediaTypeString(MediaItem item) {
- if (item.getMediaType() == MediaObject.MEDIA_TYPE_VIDEO) {
- return "Video";
- } else if (item.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE) {
- return "Photo";
- } else {
- return "Unknown:" + item.getMediaType();
- }
- }
-
-}
diff --git a/src/com/android/gallery3d/app/PhotoPageBottomControls.java b/src/com/android/gallery3d/app/PhotoPageBottomControls.java
deleted file mode 100644
index 24b8ceb7e..000000000
--- a/src/com/android/gallery3d/app/PhotoPageBottomControls.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.widget.RelativeLayout;
-
-import com.android.gallery3d.R;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class PhotoPageBottomControls implements OnClickListener {
- public interface Delegate {
- public boolean canDisplayBottomControls();
- public boolean canDisplayBottomControl(int control);
- public void onBottomControlClicked(int control);
- public void refreshBottomControlsWhenReady();
- }
-
- private Delegate mDelegate;
- private ViewGroup mParentLayout;
- private ViewGroup mContainer;
-
- private boolean mContainerVisible = false;
- private Map<View, Boolean> mControlsVisible = new HashMap<View, Boolean>();
-
- private Animation mContainerAnimIn = new AlphaAnimation(0f, 1f);
- private Animation mContainerAnimOut = new AlphaAnimation(1f, 0f);
- private static final int CONTAINER_ANIM_DURATION_MS = 200;
-
- private static final int CONTROL_ANIM_DURATION_MS = 150;
- private static Animation getControlAnimForVisibility(boolean visible) {
- Animation anim = visible ? new AlphaAnimation(0f, 1f)
- : new AlphaAnimation(1f, 0f);
- anim.setDuration(CONTROL_ANIM_DURATION_MS);
- return anim;
- }
-
- public PhotoPageBottomControls(Delegate delegate, Context context, RelativeLayout layout) {
- mDelegate = delegate;
- mParentLayout = layout;
-
- LayoutInflater inflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mContainer = (ViewGroup) inflater
- .inflate(R.layout.photopage_bottom_controls, mParentLayout, false);
- mParentLayout.addView(mContainer);
-
- for (int i = mContainer.getChildCount() - 1; i >= 0; i--) {
- View child = mContainer.getChildAt(i);
- child.setOnClickListener(this);
- mControlsVisible.put(child, false);
- }
-
- mContainerAnimIn.setDuration(CONTAINER_ANIM_DURATION_MS);
- mContainerAnimOut.setDuration(CONTAINER_ANIM_DURATION_MS);
-
- mDelegate.refreshBottomControlsWhenReady();
- }
-
- private void hide() {
- mContainer.clearAnimation();
- mContainerAnimOut.reset();
- mContainer.startAnimation(mContainerAnimOut);
- mContainer.setVisibility(View.INVISIBLE);
- }
-
- private void show() {
- mContainer.clearAnimation();
- mContainerAnimIn.reset();
- mContainer.startAnimation(mContainerAnimIn);
- mContainer.setVisibility(View.VISIBLE);
- }
-
- public void refresh() {
- boolean visible = mDelegate.canDisplayBottomControls();
- boolean containerVisibilityChanged = (visible != mContainerVisible);
- if (containerVisibilityChanged) {
- if (visible) {
- show();
- } else {
- hide();
- }
- mContainerVisible = visible;
- }
- if (!mContainerVisible) {
- return;
- }
- for (View control : mControlsVisible.keySet()) {
- Boolean prevVisibility = mControlsVisible.get(control);
- boolean curVisibility = mDelegate.canDisplayBottomControl(control.getId());
- if (prevVisibility.booleanValue() != curVisibility) {
- if (!containerVisibilityChanged) {
- control.clearAnimation();
- control.startAnimation(getControlAnimForVisibility(curVisibility));
- }
- control.setVisibility(curVisibility ? View.VISIBLE : View.INVISIBLE);
- mControlsVisible.put(control, curVisibility);
- }
- }
- // Force a layout change
- mContainer.requestLayout(); // Kick framework to draw the control.
- }
-
- public void cleanup() {
- mParentLayout.removeView(mContainer);
- mControlsVisible.clear();
- }
-
- @Override
- public void onClick(View view) {
- if (mContainerVisible && mControlsVisible.get(view).booleanValue()) {
- mDelegate.onBottomControlClicked(view.getId());
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/PhotoPageProgressBar.java b/src/com/android/gallery3d/app/PhotoPageProgressBar.java
deleted file mode 100644
index 141fea698..000000000
--- a/src/com/android/gallery3d/app/PhotoPageProgressBar.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.RelativeLayout;
-
-import com.android.gallery3d.R;
-
-public class PhotoPageProgressBar {
- private ViewGroup mContainer;
- private View mProgress;
-
- public PhotoPageProgressBar(Context context, RelativeLayout parentLayout) {
- LayoutInflater inflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mContainer = (ViewGroup) inflater.inflate(R.layout.photopage_progress_bar, parentLayout,
- false);
- parentLayout.addView(mContainer);
- mProgress = mContainer.findViewById(R.id.photopage_progress_foreground);
- }
-
- public void setProgress(int progressPercent) {
- mContainer.setVisibility(View.VISIBLE);
- LayoutParams layoutParams = mProgress.getLayoutParams();
- layoutParams.width = mContainer.getWidth() * progressPercent / 100;
- mProgress.setLayoutParams(layoutParams);
- }
-
- public void hideProgress() {
- mContainer.setVisibility(View.INVISIBLE);
- }
-}
diff --git a/src/com/android/gallery3d/app/PickerActivity.java b/src/com/android/gallery3d/app/PickerActivity.java
deleted file mode 100644
index d5bb218ea..000000000
--- a/src/com/android/gallery3d/app/PickerActivity.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 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.app;
-
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.Window;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.ui.GLRootView;
-
-public class PickerActivity extends AbstractGalleryActivity
- implements OnClickListener {
-
- public static final String KEY_ALBUM_PATH = "album-path";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // We show the picker in two ways. One smaller screen we use a full
- // screen window with an action bar. On larger screen we use a dialog.
- boolean isDialog = getResources().getBoolean(R.bool.picker_is_dialog);
-
- if (!isDialog) {
- requestWindowFeature(Window.FEATURE_ACTION_BAR);
- requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
- }
-
- setContentView(R.layout.dialog_picker);
-
- if (isDialog) {
- // In dialog mode, we don't have the action bar to show the
- // "cancel" action, so we show an additional "cancel" button.
- View view = findViewById(R.id.cancel);
- view.setOnClickListener(this);
- view.setVisibility(View.VISIBLE);
-
- // We need this, otherwise the view will be dimmed because it
- // is "behind" the dialog.
- ((GLRootView) findViewById(R.id.gl_root_view)).setZOrderOnTop(true);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.pickup, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.action_cancel) {
- finish();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.cancel) finish();
- }
-}
diff --git a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
deleted file mode 100644
index 00f2fe78f..000000000
--- a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
+++ /dev/null
@@ -1,263 +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.app;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.Message;
-
-import com.android.gallery3d.common.BitmapUtils;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.ui.BitmapScreenNail;
-import com.android.gallery3d.ui.PhotoView;
-import com.android.gallery3d.ui.ScreenNail;
-import com.android.gallery3d.ui.SynchronizedHandler;
-import com.android.gallery3d.ui.TileImageViewAdapter;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.FutureListener;
-import com.android.gallery3d.util.ThreadPool;
-
-public class SinglePhotoDataAdapter extends TileImageViewAdapter
- implements PhotoPage.Model {
-
- private static final String TAG = "SinglePhotoDataAdapter";
- private static final int SIZE_BACKUP = 1024;
- private static final int MSG_UPDATE_IMAGE = 1;
-
- private MediaItem mItem;
- private boolean mHasFullImage;
- private Future<?> mTask;
- private Handler mHandler;
-
- private PhotoView mPhotoView;
- private ThreadPool mThreadPool;
- private int mLoadingState = LOADING_INIT;
- private BitmapScreenNail mBitmapScreenNail;
-
- public SinglePhotoDataAdapter(
- AbstractGalleryActivity activity, PhotoView view, MediaItem item) {
- mItem = Utils.checkNotNull(item);
- mHasFullImage = (item.getSupportedOperations() &
- MediaItem.SUPPORT_FULL_IMAGE) != 0;
- mPhotoView = Utils.checkNotNull(view);
- mHandler = new SynchronizedHandler(activity.getGLRoot()) {
- @Override
- @SuppressWarnings("unchecked")
- public void handleMessage(Message message) {
- Utils.assertTrue(message.what == MSG_UPDATE_IMAGE);
- if (mHasFullImage) {
- onDecodeLargeComplete((ImageBundle) message.obj);
- } else {
- onDecodeThumbComplete((Future<Bitmap>) message.obj);
- }
- }
- };
- mThreadPool = activity.getThreadPool();
- }
-
- private static class ImageBundle {
- public final BitmapRegionDecoder decoder;
- public final Bitmap backupImage;
-
- public ImageBundle(BitmapRegionDecoder decoder, Bitmap backupImage) {
- this.decoder = decoder;
- this.backupImage = backupImage;
- }
- }
-
- private FutureListener<BitmapRegionDecoder> mLargeListener =
- new FutureListener<BitmapRegionDecoder>() {
- @Override
- public void onFutureDone(Future<BitmapRegionDecoder> future) {
- BitmapRegionDecoder decoder = future.get();
- if (decoder == null) return;
- int width = decoder.getWidth();
- int height = decoder.getHeight();
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inSampleSize = BitmapUtils.computeSampleSize(
- (float) SIZE_BACKUP / Math.max(width, height));
- Bitmap bitmap = decoder.decodeRegion(new Rect(0, 0, width, height), options);
- mHandler.sendMessage(mHandler.obtainMessage(
- MSG_UPDATE_IMAGE, new ImageBundle(decoder, bitmap)));
- }
- };
-
- private FutureListener<Bitmap> mThumbListener =
- new FutureListener<Bitmap>() {
- @Override
- public void onFutureDone(Future<Bitmap> future) {
- mHandler.sendMessage(
- mHandler.obtainMessage(MSG_UPDATE_IMAGE, future));
- }
- };
-
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- private void setScreenNail(Bitmap bitmap, int width, int height) {
- mBitmapScreenNail = new BitmapScreenNail(bitmap);
- setScreenNail(mBitmapScreenNail, width, height);
- }
-
- private void onDecodeLargeComplete(ImageBundle bundle) {
- try {
- setScreenNail(bundle.backupImage,
- bundle.decoder.getWidth(), bundle.decoder.getHeight());
- setRegionDecoder(bundle.decoder);
- mPhotoView.notifyImageChange(0);
- } catch (Throwable t) {
- Log.w(TAG, "fail to decode large", t);
- }
- }
-
- private void onDecodeThumbComplete(Future<Bitmap> future) {
- try {
- Bitmap backup = future.get();
- if (backup == null) {
- mLoadingState = LOADING_FAIL;
- return;
- } else {
- mLoadingState = LOADING_COMPLETE;
- }
- setScreenNail(backup, backup.getWidth(), backup.getHeight());
- mPhotoView.notifyImageChange(0);
- } catch (Throwable t) {
- Log.w(TAG, "fail to decode thumb", t);
- }
- }
-
- @Override
- public void resume() {
- if (mTask == null) {
- if (mHasFullImage) {
- mTask = mThreadPool.submit(
- mItem.requestLargeImage(), mLargeListener);
- } else {
- mTask = mThreadPool.submit(
- mItem.requestImage(MediaItem.TYPE_THUMBNAIL),
- mThumbListener);
- }
- }
- }
-
- @Override
- public void pause() {
- Future<?> task = mTask;
- task.cancel();
- task.waitDone();
- if (task.get() == null) {
- mTask = null;
- }
- if (mBitmapScreenNail != null) {
- mBitmapScreenNail.recycle();
- mBitmapScreenNail = null;
- }
- }
-
- @Override
- public void moveTo(int index) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getImageSize(int offset, PhotoView.Size size) {
- if (offset == 0) {
- size.width = mItem.getWidth();
- size.height = mItem.getHeight();
- } else {
- size.width = 0;
- size.height = 0;
- }
- }
-
- @Override
- public int getImageRotation(int offset) {
- return (offset == 0) ? mItem.getFullImageRotation() : 0;
- }
-
- @Override
- public ScreenNail getScreenNail(int offset) {
- return (offset == 0) ? getScreenNail() : null;
- }
-
- @Override
- public void setNeedFullImage(boolean enabled) {
- // currently not necessary.
- }
-
- @Override
- public boolean isCamera(int offset) {
- return false;
- }
-
- @Override
- public boolean isPanorama(int offset) {
- return false;
- }
-
- @Override
- public boolean isStaticCamera(int offset) {
- return false;
- }
-
- @Override
- public boolean isVideo(int offset) {
- return mItem.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO;
- }
-
- @Override
- public boolean isDeletable(int offset) {
- return (mItem.getSupportedOperations() & MediaItem.SUPPORT_DELETE) != 0;
- }
-
- @Override
- public MediaItem getMediaItem(int offset) {
- return offset == 0 ? mItem : null;
- }
-
- @Override
- public int getCurrentIndex() {
- return 0;
- }
-
- @Override
- public void setCurrentPhoto(Path path, int indexHint) {
- // ignore
- }
-
- @Override
- public void setFocusHintDirection(int direction) {
- // ignore
- }
-
- @Override
- public void setFocusHintPath(Path path) {
- // ignore
- }
-
- @Override
- public int getLoadingState(int offset) {
- return mLoadingState;
- }
-}
diff --git a/src/com/android/gallery3d/app/SinglePhotoPage.java b/src/com/android/gallery3d/app/SinglePhotoPage.java
deleted file mode 100644
index beb87d358..000000000
--- a/src/com/android/gallery3d/app/SinglePhotoPage.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-public class SinglePhotoPage extends PhotoPage {
-
-}
diff --git a/src/com/android/gallery3d/app/SlideshowDataAdapter.java b/src/com/android/gallery3d/app/SlideshowDataAdapter.java
deleted file mode 100644
index 7a0fba5fb..000000000
--- a/src/com/android/gallery3d/app/SlideshowDataAdapter.java
+++ /dev/null
@@ -1,204 +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.app;
-
-import android.graphics.Bitmap;
-
-import com.android.gallery3d.app.SlideshowPage.Slide;
-import com.android.gallery3d.data.ContentListener;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.FutureListener;
-import com.android.gallery3d.util.ThreadPool;
-import com.android.gallery3d.util.ThreadPool.Job;
-import com.android.gallery3d.util.ThreadPool.JobContext;
-
-import java.util.LinkedList;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class SlideshowDataAdapter implements SlideshowPage.Model {
- @SuppressWarnings("unused")
- private static final String TAG = "SlideshowDataAdapter";
-
- private static final int IMAGE_QUEUE_CAPACITY = 3;
-
- public interface SlideshowSource {
- public void addContentListener(ContentListener listener);
- public void removeContentListener(ContentListener listener);
- public long reload();
- public MediaItem getMediaItem(int index);
- public int findItemIndex(Path path, int hint);
- }
-
- private final SlideshowSource mSource;
-
- private int mLoadIndex = 0;
- private int mNextOutput = 0;
- private boolean mIsActive = false;
- private boolean mNeedReset;
- private boolean mDataReady;
- private Path mInitialPath;
-
- private final LinkedList<Slide> mImageQueue = new LinkedList<Slide>();
-
- private Future<Void> mReloadTask;
- private final ThreadPool mThreadPool;
-
- private long mDataVersion = MediaObject.INVALID_DATA_VERSION;
- private final AtomicBoolean mNeedReload = new AtomicBoolean(false);
- private final SourceListener mSourceListener = new SourceListener();
-
- // The index is just a hint if initialPath is set
- public SlideshowDataAdapter(GalleryContext context, SlideshowSource source, int index,
- Path initialPath) {
- mSource = source;
- mInitialPath = initialPath;
- mLoadIndex = index;
- mNextOutput = index;
- mThreadPool = context.getThreadPool();
- }
-
- private MediaItem loadItem() {
- if (mNeedReload.compareAndSet(true, false)) {
- long v = mSource.reload();
- if (v != mDataVersion) {
- mDataVersion = v;
- mNeedReset = true;
- return null;
- }
- }
- int index = mLoadIndex;
- if (mInitialPath != null) {
- index = mSource.findItemIndex(mInitialPath, index);
- mInitialPath = null;
- }
- return mSource.getMediaItem(index);
- }
-
- private class ReloadTask implements Job<Void> {
- @Override
- public Void run(JobContext jc) {
- while (true) {
- synchronized (SlideshowDataAdapter.this) {
- while (mIsActive && (!mDataReady
- || mImageQueue.size() >= IMAGE_QUEUE_CAPACITY)) {
- try {
- SlideshowDataAdapter.this.wait();
- } catch (InterruptedException ex) {
- // ignored.
- }
- continue;
- }
- }
- if (!mIsActive) return null;
- mNeedReset = false;
-
- MediaItem item = loadItem();
-
- if (mNeedReset) {
- synchronized (SlideshowDataAdapter.this) {
- mImageQueue.clear();
- mLoadIndex = mNextOutput;
- }
- continue;
- }
-
- if (item == null) {
- synchronized (SlideshowDataAdapter.this) {
- if (!mNeedReload.get()) mDataReady = false;
- SlideshowDataAdapter.this.notifyAll();
- }
- continue;
- }
-
- Bitmap bitmap = item
- .requestImage(MediaItem.TYPE_THUMBNAIL)
- .run(jc);
-
- if (bitmap != null) {
- synchronized (SlideshowDataAdapter.this) {
- mImageQueue.addLast(
- new Slide(item, mLoadIndex, bitmap));
- if (mImageQueue.size() == 1) {
- SlideshowDataAdapter.this.notifyAll();
- }
- }
- }
- ++mLoadIndex;
- }
- }
- }
-
- private class SourceListener implements ContentListener {
- @Override
- public void onContentDirty() {
- synchronized (SlideshowDataAdapter.this) {
- mNeedReload.set(true);
- mDataReady = true;
- SlideshowDataAdapter.this.notifyAll();
- }
- }
- }
-
- private synchronized Slide innerNextBitmap() {
- while (mIsActive && mDataReady && mImageQueue.isEmpty()) {
- try {
- wait();
- } catch (InterruptedException t) {
- throw new AssertionError();
- }
- }
- if (mImageQueue.isEmpty()) return null;
- mNextOutput++;
- this.notifyAll();
- return mImageQueue.removeFirst();
- }
-
- @Override
- public Future<Slide> nextSlide(FutureListener<Slide> listener) {
- return mThreadPool.submit(new Job<Slide>() {
- @Override
- public Slide run(JobContext jc) {
- jc.setMode(ThreadPool.MODE_NONE);
- return innerNextBitmap();
- }
- }, listener);
- }
-
- @Override
- public void pause() {
- synchronized (this) {
- mIsActive = false;
- notifyAll();
- }
- mSource.removeContentListener(mSourceListener);
- mReloadTask.cancel();
- mReloadTask.waitDone();
- mReloadTask = null;
- }
-
- @Override
- public synchronized void resume() {
- mIsActive = true;
- mSource.addContentListener(mSourceListener);
- mNeedReload.set(true);
- mDataReady = true;
- mReloadTask = mThreadPool.submit(new ReloadTask());
- }
-}
diff --git a/src/com/android/gallery3d/app/SlideshowPage.java b/src/com/android/gallery3d/app/SlideshowPage.java
deleted file mode 100644
index 174058dc8..000000000
--- a/src/com/android/gallery3d/app/SlideshowPage.java
+++ /dev/null
@@ -1,366 +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.app;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.view.MotionEvent;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.ContentListener;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.glrenderer.GLCanvas;
-import com.android.gallery3d.ui.GLView;
-import com.android.gallery3d.ui.SlideshowView;
-import com.android.gallery3d.ui.SynchronizedHandler;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.FutureListener;
-
-import java.util.ArrayList;
-import java.util.Random;
-
-public class SlideshowPage extends ActivityState {
- private static final String TAG = "SlideshowPage";
-
- public static final String KEY_SET_PATH = "media-set-path";
- public static final String KEY_ITEM_PATH = "media-item-path";
- public static final String KEY_PHOTO_INDEX = "photo-index";
- public static final String KEY_RANDOM_ORDER = "random-order";
- public static final String KEY_REPEAT = "repeat";
- public static final String KEY_DREAM = "dream";
-
- private static final long SLIDESHOW_DELAY = 3000; // 3 seconds
-
- private static final int MSG_LOAD_NEXT_BITMAP = 1;
- private static final int MSG_SHOW_PENDING_BITMAP = 2;
-
- public static interface Model {
- public void pause();
-
- public void resume();
-
- public Future<Slide> nextSlide(FutureListener<Slide> listener);
- }
-
- public static class Slide {
- public Bitmap bitmap;
- public MediaItem item;
- public int index;
-
- public Slide(MediaItem item, int index, Bitmap bitmap) {
- this.bitmap = bitmap;
- this.item = item;
- this.index = index;
- }
- }
-
- private Handler mHandler;
- private Model mModel;
- private SlideshowView mSlideshowView;
-
- private Slide mPendingSlide = null;
- private boolean mIsActive = false;
- private final Intent mResultIntent = new Intent();
-
- @Override
- protected int getBackgroundColorId() {
- return R.color.slideshow_background;
- }
-
- private final GLView mRootPane = new GLView() {
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- mSlideshowView.layout(0, 0, right - left, bottom - top);
- }
-
- @Override
- protected boolean onTouch(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_UP) {
- onBackPressed();
- }
- return true;
- }
-
- @Override
- protected void renderBackground(GLCanvas canvas) {
- canvas.clearBuffer(getBackgroundColor());
- }
- };
-
- @Override
- public void onCreate(Bundle data, Bundle restoreState) {
- super.onCreate(data, restoreState);
- mFlags |= (FLAG_HIDE_ACTION_BAR | FLAG_HIDE_STATUS_BAR);
- if (data.getBoolean(KEY_DREAM)) {
- // Dream screensaver only keeps screen on for plugged devices.
- mFlags |= FLAG_SCREEN_ON_WHEN_PLUGGED | FLAG_SHOW_WHEN_LOCKED;
- } else {
- // User-initiated slideshow would always keep screen on.
- mFlags |= FLAG_SCREEN_ON_ALWAYS;
- }
-
- mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_SHOW_PENDING_BITMAP:
- showPendingBitmap();
- break;
- case MSG_LOAD_NEXT_BITMAP:
- loadNextBitmap();
- break;
- default: throw new AssertionError();
- }
- }
- };
- initializeViews();
- initializeData(data);
- }
-
- private void loadNextBitmap() {
- mModel.nextSlide(new FutureListener<Slide>() {
- @Override
- public void onFutureDone(Future<Slide> future) {
- mPendingSlide = future.get();
- mHandler.sendEmptyMessage(MSG_SHOW_PENDING_BITMAP);
- }
- });
- }
-
- private void showPendingBitmap() {
- // mPendingBitmap could be null, if
- // 1.) there is no more items
- // 2.) mModel is paused
- Slide slide = mPendingSlide;
- if (slide == null) {
- if (mIsActive) {
- mActivity.getStateManager().finishState(SlideshowPage.this);
- }
- return;
- }
-
- mSlideshowView.next(slide.bitmap, slide.item.getRotation());
-
- setStateResult(Activity.RESULT_OK, mResultIntent
- .putExtra(KEY_ITEM_PATH, slide.item.getPath().toString())
- .putExtra(KEY_PHOTO_INDEX, slide.index));
- mHandler.sendEmptyMessageDelayed(MSG_LOAD_NEXT_BITMAP, SLIDESHOW_DELAY);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mIsActive = false;
- mModel.pause();
- mSlideshowView.release();
-
- mHandler.removeMessages(MSG_LOAD_NEXT_BITMAP);
- mHandler.removeMessages(MSG_SHOW_PENDING_BITMAP);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mIsActive = true;
- mModel.resume();
-
- if (mPendingSlide != null) {
- showPendingBitmap();
- } else {
- loadNextBitmap();
- }
- }
-
- private void initializeData(Bundle data) {
- boolean random = data.getBoolean(KEY_RANDOM_ORDER, false);
-
- // We only want to show slideshow for images only, not videos.
- String mediaPath = data.getString(KEY_SET_PATH);
- mediaPath = FilterUtils.newFilterPath(mediaPath, FilterUtils.FILTER_IMAGE_ONLY);
- MediaSet mediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
-
- if (random) {
- boolean repeat = data.getBoolean(KEY_REPEAT);
- mModel = new SlideshowDataAdapter(mActivity,
- new ShuffleSource(mediaSet, repeat), 0, null);
- setStateResult(Activity.RESULT_OK, mResultIntent.putExtra(KEY_PHOTO_INDEX, 0));
- } else {
- int index = data.getInt(KEY_PHOTO_INDEX);
- String itemPath = data.getString(KEY_ITEM_PATH);
- Path path = itemPath != null ? Path.fromString(itemPath) : null;
- boolean repeat = data.getBoolean(KEY_REPEAT);
- mModel = new SlideshowDataAdapter(mActivity, new SequentialSource(mediaSet, repeat),
- index, path);
- setStateResult(Activity.RESULT_OK, mResultIntent.putExtra(KEY_PHOTO_INDEX, index));
- }
- }
-
- private void initializeViews() {
- mSlideshowView = new SlideshowView();
- mRootPane.addComponent(mSlideshowView);
- setContentPane(mRootPane);
- }
-
- private static MediaItem findMediaItem(MediaSet mediaSet, int index) {
- for (int i = 0, n = mediaSet.getSubMediaSetCount(); i < n; ++i) {
- MediaSet subset = mediaSet.getSubMediaSet(i);
- int count = subset.getTotalMediaItemCount();
- if (index < count) {
- return findMediaItem(subset, index);
- }
- index -= count;
- }
- ArrayList<MediaItem> list = mediaSet.getMediaItem(index, 1);
- return list.isEmpty() ? null : list.get(0);
- }
-
- private static class ShuffleSource implements SlideshowDataAdapter.SlideshowSource {
- private static final int RETRY_COUNT = 5;
- private final MediaSet mMediaSet;
- private final Random mRandom = new Random();
- private int mOrder[] = new int[0];
- private final boolean mRepeat;
- private long mSourceVersion = MediaSet.INVALID_DATA_VERSION;
- private int mLastIndex = -1;
-
- public ShuffleSource(MediaSet mediaSet, boolean repeat) {
- mMediaSet = Utils.checkNotNull(mediaSet);
- mRepeat = repeat;
- }
-
- @Override
- public int findItemIndex(Path path, int hint) {
- return hint;
- }
-
- @Override
- public MediaItem getMediaItem(int index) {
- if (!mRepeat && index >= mOrder.length) return null;
- if (mOrder.length == 0) return null;
- mLastIndex = mOrder[index % mOrder.length];
- MediaItem item = findMediaItem(mMediaSet, mLastIndex);
- for (int i = 0; i < RETRY_COUNT && item == null; ++i) {
- Log.w(TAG, "fail to find image: " + mLastIndex);
- mLastIndex = mRandom.nextInt(mOrder.length);
- item = findMediaItem(mMediaSet, mLastIndex);
- }
- return item;
- }
-
- @Override
- public long reload() {
- long version = mMediaSet.reload();
- if (version != mSourceVersion) {
- mSourceVersion = version;
- int count = mMediaSet.getTotalMediaItemCount();
- if (count != mOrder.length) generateOrderArray(count);
- }
- return version;
- }
-
- private void generateOrderArray(int totalCount) {
- if (mOrder.length != totalCount) {
- mOrder = new int[totalCount];
- for (int i = 0; i < totalCount; ++i) {
- mOrder[i] = i;
- }
- }
- for (int i = totalCount - 1; i > 0; --i) {
- Utils.swap(mOrder, i, mRandom.nextInt(i + 1));
- }
- if (mOrder[0] == mLastIndex && totalCount > 1) {
- Utils.swap(mOrder, 0, mRandom.nextInt(totalCount - 1) + 1);
- }
- }
-
- @Override
- public void addContentListener(ContentListener listener) {
- mMediaSet.addContentListener(listener);
- }
-
- @Override
- public void removeContentListener(ContentListener listener) {
- mMediaSet.removeContentListener(listener);
- }
- }
-
- private static class SequentialSource implements SlideshowDataAdapter.SlideshowSource {
- private static final int DATA_SIZE = 32;
-
- private ArrayList<MediaItem> mData = new ArrayList<MediaItem>();
- private int mDataStart = 0;
- private long mDataVersion = MediaObject.INVALID_DATA_VERSION;
- private final MediaSet mMediaSet;
- private final boolean mRepeat;
-
- public SequentialSource(MediaSet mediaSet, boolean repeat) {
- mMediaSet = mediaSet;
- mRepeat = repeat;
- }
-
- @Override
- public int findItemIndex(Path path, int hint) {
- return mMediaSet.getIndexOfItem(path, hint);
- }
-
- @Override
- public MediaItem getMediaItem(int index) {
- int dataEnd = mDataStart + mData.size();
-
- if (mRepeat) {
- int count = mMediaSet.getMediaItemCount();
- if (count == 0) return null;
- index = index % count;
- }
- if (index < mDataStart || index >= dataEnd) {
- mData = mMediaSet.getMediaItem(index, DATA_SIZE);
- mDataStart = index;
- dataEnd = index + mData.size();
- }
-
- return (index < mDataStart || index >= dataEnd) ? null : mData.get(index - mDataStart);
- }
-
- @Override
- public long reload() {
- long version = mMediaSet.reload();
- if (version != mDataVersion) {
- mDataVersion = version;
- mData.clear();
- }
- return mDataVersion;
- }
-
- @Override
- public void addContentListener(ContentListener listener) {
- mMediaSet.addContentListener(listener);
- }
-
- @Override
- public void removeContentListener(ContentListener listener) {
- mMediaSet.removeContentListener(listener);
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/StateManager.java b/src/com/android/gallery3d/app/StateManager.java
deleted file mode 100644
index 53c3fc228..000000000
--- a/src/com/android/gallery3d/app/StateManager.java
+++ /dev/null
@@ -1,339 +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.app;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.view.Menu;
-import android.view.MenuItem;
-
-import com.android.camera.CameraActivity;
-import com.android.gallery3d.anim.StateTransitionAnimation;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.util.UsageStatistics;
-
-import java.util.Stack;
-
-public class StateManager {
- @SuppressWarnings("unused")
- private static final String TAG = "StateManager";
- private boolean mIsResumed = false;
-
- private static final String KEY_MAIN = "activity-state";
- private static final String KEY_DATA = "data";
- private static final String KEY_STATE = "bundle";
- private static final String KEY_CLASS = "class";
-
- private AbstractGalleryActivity mActivity;
- private Stack<StateEntry> mStack = new Stack<StateEntry>();
- private ActivityState.ResultEntry mResult;
-
- public StateManager(AbstractGalleryActivity activity) {
- mActivity = activity;
- }
-
- public void startState(Class<? extends ActivityState> klass,
- Bundle data) {
- Log.v(TAG, "startState " + klass);
- ActivityState state = null;
- try {
- state = klass.newInstance();
- } catch (Exception e) {
- throw new AssertionError(e);
- }
- if (!mStack.isEmpty()) {
- ActivityState top = getTopState();
- top.transitionOnNextPause(top.getClass(), klass,
- StateTransitionAnimation.Transition.Incoming);
- if (mIsResumed) top.onPause();
- }
-
- UsageStatistics.onContentViewChanged(
- UsageStatistics.COMPONENT_GALLERY,
- klass.getSimpleName());
- state.initialize(mActivity, data);
-
- mStack.push(new StateEntry(data, state));
- state.onCreate(data, null);
- if (mIsResumed) state.resume();
- }
-
- public void startStateForResult(Class<? extends ActivityState> klass,
- int requestCode, Bundle data) {
- Log.v(TAG, "startStateForResult " + klass + ", " + requestCode);
- ActivityState state = null;
- try {
- state = klass.newInstance();
- } catch (Exception e) {
- throw new AssertionError(e);
- }
- state.initialize(mActivity, data);
- state.mResult = new ActivityState.ResultEntry();
- state.mResult.requestCode = requestCode;
-
- if (!mStack.isEmpty()) {
- ActivityState as = getTopState();
- as.transitionOnNextPause(as.getClass(), klass,
- StateTransitionAnimation.Transition.Incoming);
- as.mReceivedResults = state.mResult;
- if (mIsResumed) as.onPause();
- } else {
- mResult = state.mResult;
- }
- UsageStatistics.onContentViewChanged(UsageStatistics.COMPONENT_GALLERY,
- klass.getSimpleName());
- mStack.push(new StateEntry(data, state));
- state.onCreate(data, null);
- if (mIsResumed) state.resume();
- }
-
- public boolean createOptionsMenu(Menu menu) {
- if (mStack.isEmpty()) {
- return false;
- } else {
- return getTopState().onCreateActionBar(menu);
- }
- }
-
- public void onConfigurationChange(Configuration config) {
- for (StateEntry entry : mStack) {
- entry.activityState.onConfigurationChanged(config);
- }
- }
-
- public void resume() {
- if (mIsResumed) return;
- mIsResumed = true;
- if (!mStack.isEmpty()) getTopState().resume();
- }
-
- public void pause() {
- if (!mIsResumed) return;
- mIsResumed = false;
- if (!mStack.isEmpty()) getTopState().onPause();
- }
-
- public void notifyActivityResult(int requestCode, int resultCode, Intent data) {
- getTopState().onStateResult(requestCode, resultCode, data);
- }
-
- public void clearActivityResult() {
- if (!mStack.isEmpty()) {
- getTopState().clearStateResult();
- }
- }
-
- public int getStateCount() {
- return mStack.size();
- }
-
- public boolean itemSelected(MenuItem item) {
- if (!mStack.isEmpty()) {
- if (getTopState().onItemSelected(item)) return true;
- if (item.getItemId() == android.R.id.home) {
- if (mStack.size() > 1) {
- getTopState().onBackPressed();
- }
- return true;
- }
- }
- return false;
- }
-
- public void onBackPressed() {
- if (!mStack.isEmpty()) {
- getTopState().onBackPressed();
- }
- }
-
- void finishState(ActivityState state) {
- finishState(state, true);
- }
-
- public void clearTasks() {
- // Remove all the states that are on top of the bottom PhotoPage state
- while (mStack.size() > 1) {
- mStack.pop().activityState.onDestroy();
- }
- }
-
- void finishState(ActivityState state, boolean fireOnPause) {
- // The finish() request could be rejected (only happens under Monkey),
- // If it is rejected, we won't close the last page.
- if (mStack.size() == 1) {
- Activity activity = (Activity) mActivity.getAndroidContext();
- if (mResult != null) {
- activity.setResult(mResult.resultCode, mResult.resultData);
- }
- activity.finish();
- if (!activity.isFinishing()) {
- Log.w(TAG, "finish is rejected, keep the last state");
- return;
- }
- Log.v(TAG, "no more state, finish activity");
- }
-
- Log.v(TAG, "finishState " + state);
- if (state != mStack.peek().activityState) {
- if (state.isDestroyed()) {
- Log.d(TAG, "The state is already destroyed");
- return;
- } else {
- throw new IllegalArgumentException("The stateview to be finished"
- + " is not at the top of the stack: " + state + ", "
- + mStack.peek().activityState);
- }
- }
-
- // Remove the top state.
- mStack.pop();
- state.mIsFinishing = true;
- ActivityState top = !mStack.isEmpty() ? mStack.peek().activityState : null;
- if (mIsResumed && fireOnPause) {
- if (top != null) {
- state.transitionOnNextPause(state.getClass(), top.getClass(),
- StateTransitionAnimation.Transition.Outgoing);
- }
- state.onPause();
- }
- mActivity.getGLRoot().setContentPane(null);
- state.onDestroy();
-
- if (top != null && mIsResumed) top.resume();
- if (top != null) {
- UsageStatistics.onContentViewChanged(UsageStatistics.COMPONENT_GALLERY,
- top.getClass().getSimpleName());
- }
- }
-
- public void switchState(ActivityState oldState,
- Class<? extends ActivityState> klass, Bundle data) {
- Log.v(TAG, "switchState " + oldState + ", " + klass);
- if (oldState != mStack.peek().activityState) {
- throw new IllegalArgumentException("The stateview to be finished"
- + " is not at the top of the stack: " + oldState + ", "
- + mStack.peek().activityState);
- }
- // Remove the top state.
- mStack.pop();
- if (!data.containsKey(PhotoPage.KEY_APP_BRIDGE)) {
- // Do not do the fade out stuff when we are switching camera modes
- oldState.transitionOnNextPause(oldState.getClass(), klass,
- StateTransitionAnimation.Transition.Incoming);
- }
- if (mIsResumed) oldState.onPause();
- oldState.onDestroy();
-
- // Create new state.
- ActivityState state = null;
- try {
- state = klass.newInstance();
- } catch (Exception e) {
- throw new AssertionError(e);
- }
- state.initialize(mActivity, data);
- mStack.push(new StateEntry(data, state));
- state.onCreate(data, null);
- if (mIsResumed) state.resume();
- UsageStatistics.onContentViewChanged(UsageStatistics.COMPONENT_GALLERY,
- klass.getSimpleName());
- }
-
- public void destroy() {
- Log.v(TAG, "destroy");
- while (!mStack.isEmpty()) {
- mStack.pop().activityState.onDestroy();
- }
- mStack.clear();
- }
-
- @SuppressWarnings("unchecked")
- public void restoreFromState(Bundle inState) {
- Log.v(TAG, "restoreFromState");
- Parcelable list[] = inState.getParcelableArray(KEY_MAIN);
- ActivityState topState = null;
- for (Parcelable parcelable : list) {
- Bundle bundle = (Bundle) parcelable;
- Class<? extends ActivityState> klass =
- (Class<? extends ActivityState>) bundle.getSerializable(KEY_CLASS);
-
- Bundle data = bundle.getBundle(KEY_DATA);
- Bundle state = bundle.getBundle(KEY_STATE);
-
- ActivityState activityState;
- try {
- Log.v(TAG, "restoreFromState " + klass);
- activityState = klass.newInstance();
- } catch (Exception e) {
- throw new AssertionError(e);
- }
- activityState.initialize(mActivity, data);
- activityState.onCreate(data, state);
- mStack.push(new StateEntry(data, activityState));
- topState = activityState;
- }
- if (topState != null) {
- UsageStatistics.onContentViewChanged(UsageStatistics.COMPONENT_GALLERY,
- topState.getClass().getSimpleName());
- }
- }
-
- public void saveState(Bundle outState) {
- Log.v(TAG, "saveState");
-
- Parcelable list[] = new Parcelable[mStack.size()];
- int i = 0;
- for (StateEntry entry : mStack) {
- Bundle bundle = new Bundle();
- bundle.putSerializable(KEY_CLASS, entry.activityState.getClass());
- bundle.putBundle(KEY_DATA, entry.data);
- Bundle state = new Bundle();
- entry.activityState.onSaveState(state);
- bundle.putBundle(KEY_STATE, state);
- Log.v(TAG, "saveState " + entry.activityState.getClass());
- list[i++] = bundle;
- }
- outState.putParcelableArray(KEY_MAIN, list);
- }
-
- public boolean hasStateClass(Class<? extends ActivityState> klass) {
- for (StateEntry entry : mStack) {
- if (klass.isInstance(entry.activityState)) {
- return true;
- }
- }
- return false;
- }
-
- public ActivityState getTopState() {
- Utils.assertTrue(!mStack.isEmpty());
- return mStack.peek().activityState;
- }
-
- private static class StateEntry {
- public Bundle data;
- public ActivityState activityState;
-
- public StateEntry(Bundle data, ActivityState state) {
- this.data = data;
- this.activityState = state;
- }
- }
-}
diff --git a/src/com/android/gallery3d/app/StitchingChangeListener.java b/src/com/android/gallery3d/app/StitchingChangeListener.java
deleted file mode 100644
index 0b8c2d6d6..000000000
--- a/src/com/android/gallery3d/app/StitchingChangeListener.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.net.Uri;
-
-public interface StitchingChangeListener {
- public void onStitchingQueued(Uri uri);
-
- public void onStitchingResult(Uri uri);
-
- public void onStitchingProgress(Uri uri, int progress);
-}
diff --git a/src/com/android/gallery3d/app/TimeBar.java b/src/com/android/gallery3d/app/TimeBar.java
deleted file mode 100644
index 246346a56..000000000
--- a/src/com/android/gallery3d/app/TimeBar.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2011 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.app;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.util.DisplayMetrics;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.Utils;
-
-/**
- * The time bar view, which includes the current and total time, the progress
- * bar, and the scrubber.
- */
-public class TimeBar extends View {
-
- public interface Listener {
- void onScrubbingStart();
-
- void onScrubbingMove(int time);
-
- void onScrubbingEnd(int time, int start, int end);
- }
-
- // Padding around the scrubber to increase its touch target
- private static final int SCRUBBER_PADDING_IN_DP = 10;
-
- // The total padding, top plus bottom
- private static final int V_PADDING_IN_DP = 30;
-
- private static final int TEXT_SIZE_IN_DP = 14;
-
- protected final Listener mListener;
-
- // the bars we use for displaying the progress
- protected final Rect mProgressBar;
- protected final Rect mPlayedBar;
-
- protected final Paint mProgressPaint;
- protected final Paint mPlayedPaint;
- protected final Paint mTimeTextPaint;
-
- protected final Bitmap mScrubber;
- protected int mScrubberPadding; // adds some touch tolerance around the
- // scrubber
-
- protected int mScrubberLeft;
- protected int mScrubberTop;
- protected int mScrubberCorrection;
- protected boolean mScrubbing;
- protected boolean mShowTimes;
- protected boolean mShowScrubber;
-
- protected int mTotalTime;
- protected int mCurrentTime;
-
- protected final Rect mTimeBounds;
-
- protected int mVPaddingInPx;
-
- public TimeBar(Context context, Listener listener) {
- super(context);
- mListener = Utils.checkNotNull(listener);
-
- mShowTimes = true;
- mShowScrubber = true;
-
- mProgressBar = new Rect();
- mPlayedBar = new Rect();
-
- mProgressPaint = new Paint();
- mProgressPaint.setColor(0xFF808080);
- mPlayedPaint = new Paint();
- mPlayedPaint.setColor(0xFFFFFFFF);
-
- DisplayMetrics metrics = context.getResources().getDisplayMetrics();
- float textSizeInPx = metrics.density * TEXT_SIZE_IN_DP;
- mTimeTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mTimeTextPaint.setColor(0xFFCECECE);
- mTimeTextPaint.setTextSize(textSizeInPx);
- mTimeTextPaint.setTextAlign(Paint.Align.CENTER);
-
- mTimeBounds = new Rect();
- mTimeTextPaint.getTextBounds("0:00:00", 0, 7, mTimeBounds);
-
- mScrubber = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_knob);
- mScrubberPadding = (int) (metrics.density * SCRUBBER_PADDING_IN_DP);
-
- mVPaddingInPx = (int) (metrics.density * V_PADDING_IN_DP);
- }
-
- private void update() {
- mPlayedBar.set(mProgressBar);
-
- if (mTotalTime > 0) {
- mPlayedBar.right =
- mPlayedBar.left + (int) ((mProgressBar.width() * (long) mCurrentTime) / mTotalTime);
- } else {
- mPlayedBar.right = mProgressBar.left;
- }
-
- if (!mScrubbing) {
- mScrubberLeft = mPlayedBar.right - mScrubber.getWidth() / 2;
- }
- invalidate();
- }
-
- /**
- * @return the preferred height of this view, including invisible padding
- */
- public int getPreferredHeight() {
- return mTimeBounds.height() + mVPaddingInPx + mScrubberPadding;
- }
-
- /**
- * @return the height of the time bar, excluding invisible padding
- */
- public int getBarHeight() {
- return mTimeBounds.height() + mVPaddingInPx;
- }
-
- public void setTime(int currentTime, int totalTime,
- int trimStartTime, int trimEndTime) {
- if (mCurrentTime == currentTime && mTotalTime == totalTime) {
- return;
- }
- mCurrentTime = currentTime;
- mTotalTime = totalTime;
- update();
- }
-
- private boolean inScrubber(float x, float y) {
- int scrubberRight = mScrubberLeft + mScrubber.getWidth();
- int scrubberBottom = mScrubberTop + mScrubber.getHeight();
- return mScrubberLeft - mScrubberPadding < x && x < scrubberRight + mScrubberPadding
- && mScrubberTop - mScrubberPadding < y && y < scrubberBottom + mScrubberPadding;
- }
-
- private void clampScrubber() {
- int half = mScrubber.getWidth() / 2;
- int max = mProgressBar.right - half;
- int min = mProgressBar.left - half;
- mScrubberLeft = Math.min(max, Math.max(min, mScrubberLeft));
- }
-
- private int getScrubberTime() {
- return (int) ((long) (mScrubberLeft + mScrubber.getWidth() / 2 - mProgressBar.left)
- * mTotalTime / mProgressBar.width());
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- int w = r - l;
- int h = b - t;
- if (!mShowTimes && !mShowScrubber) {
- mProgressBar.set(0, 0, w, h);
- } else {
- int margin = mScrubber.getWidth() / 3;
- if (mShowTimes) {
- margin += mTimeBounds.width();
- }
- int progressY = (h + mScrubberPadding) / 2;
- mScrubberTop = progressY - mScrubber.getHeight() / 2 + 1;
- mProgressBar.set(
- getPaddingLeft() + margin, progressY,
- w - getPaddingRight() - margin, progressY + 4);
- }
- update();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- // draw progress bars
- canvas.drawRect(mProgressBar, mProgressPaint);
- canvas.drawRect(mPlayedBar, mPlayedPaint);
-
- // draw scrubber and timers
- if (mShowScrubber) {
- canvas.drawBitmap(mScrubber, mScrubberLeft, mScrubberTop, null);
- }
- if (mShowTimes) {
- canvas.drawText(
- stringForTime(mCurrentTime),
- mTimeBounds.width() / 2 + getPaddingLeft(),
- mTimeBounds.height() + mVPaddingInPx / 2 + mScrubberPadding + 1,
- mTimeTextPaint);
- canvas.drawText(
- stringForTime(mTotalTime),
- getWidth() - getPaddingRight() - mTimeBounds.width() / 2,
- mTimeBounds.height() + mVPaddingInPx / 2 + mScrubberPadding + 1,
- mTimeTextPaint);
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (mShowScrubber) {
- int x = (int) event.getX();
- int y = (int) event.getY();
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN: {
- mScrubberCorrection = inScrubber(x, y)
- ? x - mScrubberLeft
- : mScrubber.getWidth() / 2;
- mScrubbing = true;
- mListener.onScrubbingStart();
- }
- // fall-through
- case MotionEvent.ACTION_MOVE: {
- mScrubberLeft = x - mScrubberCorrection;
- clampScrubber();
- mCurrentTime = getScrubberTime();
- mListener.onScrubbingMove(mCurrentTime);
- invalidate();
- return true;
- }
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP: {
- mListener.onScrubbingEnd(getScrubberTime(), 0, 0);
- mScrubbing = false;
- return true;
- }
- }
- }
- return false;
- }
-
- protected String stringForTime(long millis) {
- int totalSeconds = (int) millis / 1000;
- int seconds = totalSeconds % 60;
- int minutes = (totalSeconds / 60) % 60;
- int hours = totalSeconds / 3600;
- if (hours > 0) {
- return String.format("%d:%02d:%02d", hours, minutes, seconds).toString();
- } else {
- return String.format("%02d:%02d", minutes, seconds).toString();
- }
- }
-
- public void setSeekable(boolean canSeek) {
- mShowScrubber = canSeek;
- }
-
-}
diff --git a/src/com/android/gallery3d/app/TransitionStore.java b/src/com/android/gallery3d/app/TransitionStore.java
deleted file mode 100644
index aa38ed77e..000000000
--- a/src/com/android/gallery3d/app/TransitionStore.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import java.util.HashMap;
-
-public class TransitionStore {
- private HashMap<Object, Object> mStorage = new HashMap<Object, Object>();
-
- public void put(Object key, Object value) {
- mStorage.put(key, value);
- }
-
- public <T> void putIfNotPresent(Object key, T valueIfNull) {
- mStorage.put(key, get(key, valueIfNull));
- }
-
- @SuppressWarnings("unchecked")
- public <T> T get(Object key) {
- return (T) mStorage.get(key);
- }
-
- @SuppressWarnings("unchecked")
- public <T> T get(Object key, T valueIfNull) {
- T value = (T) mStorage.get(key);
- return value == null ? valueIfNull : value;
- }
-
- public void clear() {
- mStorage.clear();
- }
-}
diff --git a/src/com/android/gallery3d/app/TrimControllerOverlay.java b/src/com/android/gallery3d/app/TrimControllerOverlay.java
deleted file mode 100644
index cae016626..000000000
--- a/src/com/android/gallery3d/app/TrimControllerOverlay.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.gallery3d.common.ApiHelper;
-
-/**
- * The controller for the Trimming Video.
- */
-public class TrimControllerOverlay extends CommonControllerOverlay {
-
- public TrimControllerOverlay(Context context) {
- super(context);
- }
-
- @Override
- protected void createTimeBar(Context context) {
- mTimeBar = new TrimTimeBar(context, this);
- }
-
- private void hidePlayButtonIfPlaying() {
- if (mState == State.PLAYING) {
- mPlayPauseReplayView.setVisibility(View.INVISIBLE);
- }
- if (ApiHelper.HAS_OBJECT_ANIMATION) {
- mPlayPauseReplayView.setAlpha(1f);
- }
- }
-
- @Override
- public void showPlaying() {
- super.showPlaying();
- if (ApiHelper.HAS_OBJECT_ANIMATION) {
- // Add animation to hide the play button while playing.
- ObjectAnimator anim = ObjectAnimator.ofFloat(mPlayPauseReplayView, "alpha", 1f, 0f);
- anim.setDuration(200);
- anim.start();
- anim.addListener(new AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- hidePlayButtonIfPlaying();
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- hidePlayButtonIfPlaying();
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- });
- } else {
- hidePlayButtonIfPlaying();
- }
- }
-
- @Override
- public void setTimes(int currentTime, int totalTime, int trimStartTime, int trimEndTime) {
- mTimeBar.setTime(currentTime, totalTime, trimStartTime, trimEndTime);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (super.onTouchEvent(event)) {
- return true;
- }
-
- // The special thing here is that the State.ENDED include both cases of
- // the video completed and current == trimEnd. Both request a replay.
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- if (mState == State.PLAYING || mState == State.PAUSED) {
- mListener.onPlayPause();
- } else if (mState == State.ENDED) {
- if (mCanReplay) {
- mListener.onReplay();
- }
- }
- break;
- case MotionEvent.ACTION_UP:
- break;
- }
- return true;
- }
-}
diff --git a/src/com/android/gallery3d/app/TrimTimeBar.java b/src/com/android/gallery3d/app/TrimTimeBar.java
deleted file mode 100644
index f8dbc749e..000000000
--- a/src/com/android/gallery3d/app/TrimTimeBar.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.view.MotionEvent;
-
-import com.android.gallery3d.R;
-
-/**
- * The trim time bar view, which includes the current and total time, the progress
- * bar, and the scrubbers for current time, start and end time for trimming.
- */
-public class TrimTimeBar extends TimeBar {
-
- public static final int SCRUBBER_NONE = 0;
- public static final int SCRUBBER_START = 1;
- public static final int SCRUBBER_CURRENT = 2;
- public static final int SCRUBBER_END = 3;
-
- private int mPressedThumb = SCRUBBER_NONE;
-
- // On touch event, the setting order is Scrubber Position -> Time ->
- // PlayedBar. At the setTimes(), activity can update the Time directly, then
- // PlayedBar will be updated too.
- private int mTrimStartScrubberLeft;
- private int mTrimEndScrubberLeft;
-
- private int mTrimStartScrubberTop;
- private int mTrimEndScrubberTop;
-
- private int mTrimStartTime;
- private int mTrimEndTime;
-
- private final Bitmap mTrimStartScrubber;
- private final Bitmap mTrimEndScrubber;
- public TrimTimeBar(Context context, Listener listener) {
- super(context, listener);
-
- mTrimStartTime = 0;
- mTrimEndTime = 0;
- mTrimStartScrubberLeft = 0;
- mTrimEndScrubberLeft = 0;
- mTrimStartScrubberTop = 0;
- mTrimEndScrubberTop = 0;
-
- mTrimStartScrubber = BitmapFactory.decodeResource(getResources(),
- R.drawable.text_select_handle_left);
- mTrimEndScrubber = BitmapFactory.decodeResource(getResources(),
- R.drawable.text_select_handle_right);
- // Increase the size of this trimTimeBar, but minimize the scrubber
- // touch padding since we have 3 scrubbers now.
- mScrubberPadding = 0;
- mVPaddingInPx = mVPaddingInPx * 3 / 2;
- }
-
- private int getBarPosFromTime(int time) {
- return mProgressBar.left +
- (int) ((mProgressBar.width() * (long) time) / mTotalTime);
- }
-
- private int trimStartScrubberTipOffset() {
- return mTrimStartScrubber.getWidth() * 3 / 4;
- }
-
- private int trimEndScrubberTipOffset() {
- return mTrimEndScrubber.getWidth() / 4;
- }
-
- // Based on all the time info (current, total, trimStart, trimEnd), we
- // decide the playedBar size.
- private void updatePlayedBarAndScrubberFromTime() {
- // According to the Time, update the Played Bar
- mPlayedBar.set(mProgressBar);
- if (mTotalTime > 0) {
- // set playedBar according to the trim time.
- mPlayedBar.left = getBarPosFromTime(mTrimStartTime);
- mPlayedBar.right = getBarPosFromTime(mCurrentTime);
- if (!mScrubbing) {
- mScrubberLeft = mPlayedBar.right - mScrubber.getWidth() / 2;
- mTrimStartScrubberLeft = mPlayedBar.left - trimStartScrubberTipOffset();
- mTrimEndScrubberLeft = getBarPosFromTime(mTrimEndTime)
- - trimEndScrubberTipOffset();
- }
- } else {
- // If the video is not prepared, just show the scrubber at the end
- // of progressBar
- mPlayedBar.right = mProgressBar.left;
- mScrubberLeft = mProgressBar.left - mScrubber.getWidth() / 2;
- mTrimStartScrubberLeft = mProgressBar.left - trimStartScrubberTipOffset();
- mTrimEndScrubberLeft = mProgressBar.right - trimEndScrubberTipOffset();
- }
- }
-
- private void initTrimTimeIfNeeded() {
- if (mTotalTime > 0 && mTrimEndTime == 0) {
- mTrimEndTime = mTotalTime;
- }
- }
-
- private void update() {
- initTrimTimeIfNeeded();
- updatePlayedBarAndScrubberFromTime();
- invalidate();
- }
-
- @Override
- public void setTime(int currentTime, int totalTime,
- int trimStartTime, int trimEndTime) {
- if (mCurrentTime == currentTime && mTotalTime == totalTime
- && mTrimStartTime == trimStartTime && mTrimEndTime == trimEndTime) {
- return;
- }
- mCurrentTime = currentTime;
- mTotalTime = totalTime;
- mTrimStartTime = trimStartTime;
- mTrimEndTime = trimEndTime;
- update();
- }
-
- private int whichScrubber(float x, float y) {
- if (inScrubber(x, y, mTrimStartScrubberLeft, mTrimStartScrubberTop, mTrimStartScrubber)) {
- return SCRUBBER_START;
- } else if (inScrubber(x, y, mTrimEndScrubberLeft, mTrimEndScrubberTop, mTrimEndScrubber)) {
- return SCRUBBER_END;
- } else if (inScrubber(x, y, mScrubberLeft, mScrubberTop, mScrubber)) {
- return SCRUBBER_CURRENT;
- }
- return SCRUBBER_NONE;
- }
-
- private boolean inScrubber(float x, float y, int startX, int startY, Bitmap scrubber) {
- int scrubberRight = startX + scrubber.getWidth();
- int scrubberBottom = startY + scrubber.getHeight();
- return startX < x && x < scrubberRight && startY < y && y < scrubberBottom;
- }
-
- private int clampScrubber(int scrubberLeft, int offset, int lowerBound, int upperBound) {
- int max = upperBound - offset;
- int min = lowerBound - offset;
- return Math.min(max, Math.max(min, scrubberLeft));
- }
-
- private int getScrubberTime(int scrubberLeft, int offset) {
- return (int) ((long) (scrubberLeft + offset - mProgressBar.left)
- * mTotalTime / mProgressBar.width());
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- int w = r - l;
- int h = b - t;
- if (!mShowTimes && !mShowScrubber) {
- mProgressBar.set(0, 0, w, h);
- } else {
- int margin = mScrubber.getWidth() / 3;
- if (mShowTimes) {
- margin += mTimeBounds.width();
- }
- int progressY = h / 4;
- int scrubberY = progressY - mScrubber.getHeight() / 2 + 1;
- mScrubberTop = scrubberY;
- mTrimStartScrubberTop = progressY;
- mTrimEndScrubberTop = progressY;
- mProgressBar.set(
- getPaddingLeft() + margin, progressY,
- w - getPaddingRight() - margin, progressY + 4);
- }
- update();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- // draw progress bars
- canvas.drawRect(mProgressBar, mProgressPaint);
- canvas.drawRect(mPlayedBar, mPlayedPaint);
-
- if (mShowTimes) {
- canvas.drawText(
- stringForTime(mCurrentTime),
- mTimeBounds.width() / 2 + getPaddingLeft(),
- mTimeBounds.height() / 2 + mTrimStartScrubberTop,
- mTimeTextPaint);
- canvas.drawText(
- stringForTime(mTotalTime),
- getWidth() - getPaddingRight() - mTimeBounds.width() / 2,
- mTimeBounds.height() / 2 + mTrimStartScrubberTop,
- mTimeTextPaint);
- }
-
- // draw extra scrubbers
- if (mShowScrubber) {
- canvas.drawBitmap(mScrubber, mScrubberLeft, mScrubberTop, null);
- canvas.drawBitmap(mTrimStartScrubber, mTrimStartScrubberLeft,
- mTrimStartScrubberTop, null);
- canvas.drawBitmap(mTrimEndScrubber, mTrimEndScrubberLeft,
- mTrimEndScrubberTop, null);
- }
- }
-
- private void updateTimeFromPos() {
- mCurrentTime = getScrubberTime(mScrubberLeft, mScrubber.getWidth() / 2);
- mTrimStartTime = getScrubberTime(mTrimStartScrubberLeft, trimStartScrubberTipOffset());
- mTrimEndTime = getScrubberTime(mTrimEndScrubberLeft, trimEndScrubberTipOffset());
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (mShowScrubber) {
- int x = (int) event.getX();
- int y = (int) event.getY();
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mPressedThumb = whichScrubber(x, y);
- switch (mPressedThumb) {
- case SCRUBBER_NONE:
- break;
- case SCRUBBER_CURRENT:
- mScrubbing = true;
- mScrubberCorrection = x - mScrubberLeft;
- break;
- case SCRUBBER_START:
- mScrubbing = true;
- mScrubberCorrection = x - mTrimStartScrubberLeft;
- break;
- case SCRUBBER_END:
- mScrubbing = true;
- mScrubberCorrection = x - mTrimEndScrubberLeft;
- break;
- }
- if (mScrubbing == true) {
- mListener.onScrubbingStart();
- return true;
- }
- break;
- case MotionEvent.ACTION_MOVE:
- if (mScrubbing) {
- int seekToTime = -1;
- int lowerBound = mTrimStartScrubberLeft + trimStartScrubberTipOffset();
- int upperBound = mTrimEndScrubberLeft + trimEndScrubberTipOffset();
- switch (mPressedThumb) {
- case SCRUBBER_CURRENT:
- mScrubberLeft = x - mScrubberCorrection;
- mScrubberLeft =
- clampScrubber(mScrubberLeft,
- mScrubber.getWidth() / 2,
- lowerBound, upperBound);
- seekToTime = getScrubberTime(mScrubberLeft,
- mScrubber.getWidth() / 2);
- break;
- case SCRUBBER_START:
- mTrimStartScrubberLeft = x - mScrubberCorrection;
- // Limit start <= end
- if (mTrimStartScrubberLeft > mTrimEndScrubberLeft) {
- mTrimStartScrubberLeft = mTrimEndScrubberLeft;
- }
- lowerBound = mProgressBar.left;
- mTrimStartScrubberLeft =
- clampScrubber(mTrimStartScrubberLeft,
- trimStartScrubberTipOffset(),
- lowerBound, upperBound);
- seekToTime = getScrubberTime(mTrimStartScrubberLeft,
- trimStartScrubberTipOffset());
- break;
- case SCRUBBER_END:
- mTrimEndScrubberLeft = x - mScrubberCorrection;
- upperBound = mProgressBar.right;
- mTrimEndScrubberLeft =
- clampScrubber(mTrimEndScrubberLeft,
- trimEndScrubberTipOffset(),
- lowerBound, upperBound);
- seekToTime = getScrubberTime(mTrimEndScrubberLeft,
- trimEndScrubberTipOffset());
- break;
- }
- updateTimeFromPos();
- updatePlayedBarAndScrubberFromTime();
- if (seekToTime != -1) {
- mListener.onScrubbingMove(seekToTime);
- }
- invalidate();
- return true;
- }
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- if (mScrubbing) {
- int seekToTime = 0;
- switch (mPressedThumb) {
- case SCRUBBER_CURRENT:
- seekToTime = getScrubberTime(mScrubberLeft,
- mScrubber.getWidth() / 2);
- break;
- case SCRUBBER_START:
- seekToTime = getScrubberTime(mTrimStartScrubberLeft,
- trimStartScrubberTipOffset());
- mScrubberLeft = mTrimStartScrubberLeft +
- trimStartScrubberTipOffset() - mScrubber.getWidth() / 2;
- break;
- case SCRUBBER_END:
- seekToTime = getScrubberTime(mTrimEndScrubberLeft,
- trimEndScrubberTipOffset());
- mScrubberLeft = mTrimEndScrubberLeft +
- trimEndScrubberTipOffset() - mScrubber.getWidth() / 2;
- break;
- }
- updateTimeFromPos();
- mListener.onScrubbingEnd(seekToTime,
- getScrubberTime(mTrimStartScrubberLeft,
- trimStartScrubberTipOffset()),
- getScrubberTime(mTrimEndScrubberLeft, trimEndScrubberTipOffset()));
- mScrubbing = false;
- mPressedThumb = SCRUBBER_NONE;
- return true;
- }
- break;
- }
- }
- return false;
- }
-}
diff --git a/src/com/android/gallery3d/app/TrimVideo.java b/src/com/android/gallery3d/app/TrimVideo.java
deleted file mode 100644
index 1e7728162..000000000
--- a/src/com/android/gallery3d/app/TrimVideo.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2012 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.app;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.provider.MediaStore;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.widget.TextView;
-import android.widget.Toast;
-import android.widget.VideoView;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.util.SaveVideoFileInfo;
-import com.android.gallery3d.util.SaveVideoFileUtils;
-
-import java.io.File;
-import java.io.IOException;
-
-public class TrimVideo extends Activity implements
- MediaPlayer.OnErrorListener,
- MediaPlayer.OnCompletionListener,
- ControllerOverlay.Listener {
-
- private VideoView mVideoView;
- private TextView mSaveVideoTextView;
- private TrimControllerOverlay mController;
- private Context mContext;
- private Uri mUri;
- private final Handler mHandler = new Handler();
- public static final String TRIM_ACTION = "com.android.camera.action.TRIM";
-
- public ProgressDialog mProgress;
-
- private int mTrimStartTime = 0;
- private int mTrimEndTime = 0;
- private int mVideoPosition = 0;
- public static final String KEY_TRIM_START = "trim_start";
- public static final String KEY_TRIM_END = "trim_end";
- public static final String KEY_VIDEO_POSITION = "video_pos";
- private boolean mHasPaused = false;
-
- private String mSrcVideoPath = null;
- private static final String TIME_STAMP_NAME = "'TRIM'_yyyyMMdd_HHmmss";
- private SaveVideoFileInfo mDstFileInfo = null;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- mContext = getApplicationContext();
- super.onCreate(savedInstanceState);
-
- requestWindowFeature(Window.FEATURE_ACTION_BAR);
- requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
-
- ActionBar actionBar = getActionBar();
- int displayOptions = ActionBar.DISPLAY_SHOW_HOME;
- actionBar.setDisplayOptions(0, displayOptions);
- displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM;
- actionBar.setDisplayOptions(displayOptions, displayOptions);
- actionBar.setCustomView(R.layout.trim_menu);
-
- mSaveVideoTextView = (TextView) findViewById(R.id.start_trim);
- mSaveVideoTextView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View arg0) {
- trimVideo();
- }
- });
- mSaveVideoTextView.setEnabled(false);
-
- Intent intent = getIntent();
- mUri = intent.getData();
- mSrcVideoPath = intent.getStringExtra(PhotoPage.KEY_MEDIA_ITEM_PATH);
- setContentView(R.layout.trim_view);
- View rootView = findViewById(R.id.trim_view_root);
-
- mVideoView = (VideoView) rootView.findViewById(R.id.surface_view);
-
- mController = new TrimControllerOverlay(mContext);
- ((ViewGroup) rootView).addView(mController.getView());
- mController.setListener(this);
- mController.setCanReplay(true);
-
- mVideoView.setOnErrorListener(this);
- mVideoView.setOnCompletionListener(this);
- mVideoView.setVideoURI(mUri);
-
- playVideo();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (mHasPaused) {
- mVideoView.seekTo(mVideoPosition);
- mVideoView.resume();
- mHasPaused = false;
- }
- mHandler.post(mProgressChecker);
- }
-
- @Override
- public void onPause() {
- mHasPaused = true;
- mHandler.removeCallbacksAndMessages(null);
- mVideoPosition = mVideoView.getCurrentPosition();
- mVideoView.suspend();
- super.onPause();
- }
-
- @Override
- public void onStop() {
- if (mProgress != null) {
- mProgress.dismiss();
- mProgress = null;
- }
- super.onStop();
- }
-
- @Override
- public void onDestroy() {
- mVideoView.stopPlayback();
- super.onDestroy();
- }
-
- private final Runnable mProgressChecker = new Runnable() {
- @Override
- public void run() {
- int pos = setProgress();
- mHandler.postDelayed(mProgressChecker, 200 - (pos % 200));
- }
- };
-
- @Override
- public void onSaveInstanceState(Bundle savedInstanceState) {
- savedInstanceState.putInt(KEY_TRIM_START, mTrimStartTime);
- savedInstanceState.putInt(KEY_TRIM_END, mTrimEndTime);
- savedInstanceState.putInt(KEY_VIDEO_POSITION, mVideoPosition);
- super.onSaveInstanceState(savedInstanceState);
- }
-
- @Override
- public void onRestoreInstanceState(Bundle savedInstanceState) {
- super.onRestoreInstanceState(savedInstanceState);
- mTrimStartTime = savedInstanceState.getInt(KEY_TRIM_START, 0);
- mTrimEndTime = savedInstanceState.getInt(KEY_TRIM_END, 0);
- mVideoPosition = savedInstanceState.getInt(KEY_VIDEO_POSITION, 0);
- }
-
- // This updates the time bar display (if necessary). It is called by
- // mProgressChecker and also from places where the time bar needs
- // to be updated immediately.
- private int setProgress() {
- mVideoPosition = mVideoView.getCurrentPosition();
- // If the video position is smaller than the starting point of trimming,
- // correct it.
- if (mVideoPosition < mTrimStartTime) {
- mVideoView.seekTo(mTrimStartTime);
- mVideoPosition = mTrimStartTime;
- }
- // If the position is bigger than the end point of trimming, show the
- // replay button and pause.
- if (mVideoPosition >= mTrimEndTime && mTrimEndTime > 0) {
- if (mVideoPosition > mTrimEndTime) {
- mVideoView.seekTo(mTrimEndTime);
- mVideoPosition = mTrimEndTime;
- }
- mController.showEnded();
- mVideoView.pause();
- }
-
- int duration = mVideoView.getDuration();
- if (duration > 0 && mTrimEndTime == 0) {
- mTrimEndTime = duration;
- }
- mController.setTimes(mVideoPosition, duration, mTrimStartTime, mTrimEndTime);
- return mVideoPosition;
- }
-
- private void playVideo() {
- mVideoView.start();
- mController.showPlaying();
- setProgress();
- }
-
- private void pauseVideo() {
- mVideoView.pause();
- mController.showPaused();
- }
-
-
- private boolean isModified() {
- int delta = mTrimEndTime - mTrimStartTime;
-
- // Considering that we only trim at sync frame, we don't want to trim
- // when the time interval is too short or too close to the origin.
- if (delta < 100 || Math.abs(mVideoView.getDuration() - delta) < 100) {
- return false;
- } else {
- return true;
- }
- }
-
- private void trimVideo() {
-
- mDstFileInfo = SaveVideoFileUtils.getDstMp4FileInfo(TIME_STAMP_NAME,
- getContentResolver(), mUri, getString(R.string.folder_download));
- final File mSrcFile = new File(mSrcVideoPath);
-
- showProgressDialog();
-
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- VideoUtils.startTrim(mSrcFile, mDstFileInfo.mFile,
- mTrimStartTime, mTrimEndTime);
- // Update the database for adding a new video file.
- SaveVideoFileUtils.insertContent(mDstFileInfo,
- getContentResolver(), mUri);
- } catch (IOException e) {
- e.printStackTrace();
- }
- // After trimming is done, trigger the UI changed.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(getApplicationContext(),
- getString(R.string.save_into, mDstFileInfo.mFolderName),
- Toast.LENGTH_SHORT)
- .show();
- // TODO: change trimming into a service to avoid
- // this progressDialog and add notification properly.
- if (mProgress != null) {
- mProgress.dismiss();
- mProgress = null;
- // Show the result only when the activity not stopped.
- Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
- intent.setDataAndType(Uri.fromFile(mDstFileInfo.mFile), "video/*");
- intent.putExtra(MediaStore.EXTRA_FINISH_ON_COMPLETION, false);
- startActivity(intent);
- finish();
- }
- }
- });
- }
- }).start();
- }
-
- private void showProgressDialog() {
- // create a background thread to trim the video.
- // and show the progress.
- mProgress = new ProgressDialog(this);
- mProgress.setTitle(getString(R.string.trimming));
- mProgress.setMessage(getString(R.string.please_wait));
- // TODO: make this cancelable.
- mProgress.setCancelable(false);
- mProgress.setCanceledOnTouchOutside(false);
- mProgress.show();
- }
-
- @Override
- public void onPlayPause() {
- if (mVideoView.isPlaying()) {
- pauseVideo();
- } else {
- playVideo();
- }
- }
-
- @Override
- public void onSeekStart() {
- pauseVideo();
- }
-
- @Override
- public void onSeekMove(int time) {
- mVideoView.seekTo(time);
- }
-
- @Override
- public void onSeekEnd(int time, int start, int end) {
- mVideoView.seekTo(time);
- mTrimStartTime = start;
- mTrimEndTime = end;
- setProgress();
- // Enable save if there's modifications
- mSaveVideoTextView.setEnabled(isModified());
- }
-
- @Override
- public void onShown() {
- }
-
- @Override
- public void onHidden() {
- }
-
- @Override
- public void onReplay() {
- mVideoView.seekTo(mTrimStartTime);
- playVideo();
- }
-
- @Override
- public void onCompletion(MediaPlayer mp) {
- mController.showEnded();
- }
-
- @Override
- public boolean onError(MediaPlayer mp, int what, int extra) {
- return false;
- }
-}
diff --git a/src/com/android/gallery3d/app/VideoUtils.java b/src/com/android/gallery3d/app/VideoUtils.java
deleted file mode 100644
index a3c3ef273..000000000
--- a/src/com/android/gallery3d/app/VideoUtils.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// Modified example based on mp4parser google code open source project.
-// http://code.google.com/p/mp4parser/source/browse/trunk/examples/src/main/java/com/googlecode/mp4parser/ShortenExample.java
-
-package com.android.gallery3d.app;
-
-import android.media.MediaCodec.BufferInfo;
-import android.media.MediaExtractor;
-import android.media.MediaFormat;
-import android.media.MediaMetadataRetriever;
-import android.media.MediaMuxer;
-import android.util.Log;
-
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.util.SaveVideoFileInfo;
-import com.coremedia.iso.IsoFile;
-import com.coremedia.iso.boxes.TimeToSampleBox;
-import com.googlecode.mp4parser.authoring.Movie;
-import com.googlecode.mp4parser.authoring.Track;
-import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
-import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
-import com.googlecode.mp4parser.authoring.tracks.CroppedTrack;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-
-public class VideoUtils {
- private static final String LOGTAG = "VideoUtils";
- private static final int DEFAULT_BUFFER_SIZE = 1 * 1024 * 1024;
-
- /**
- * Remove the sound track.
- */
- public static void startMute(String filePath, SaveVideoFileInfo dstFileInfo)
- throws IOException {
- if (ApiHelper.HAS_MEDIA_MUXER) {
- genVideoUsingMuxer(filePath, dstFileInfo.mFile.getPath(), -1, -1,
- false, true);
- } else {
- startMuteUsingMp4Parser(filePath, dstFileInfo);
- }
- }
-
- /**
- * Shortens/Crops tracks
- */
- public static void startTrim(File src, File dst, int startMs, int endMs)
- throws IOException {
- if (ApiHelper.HAS_MEDIA_MUXER) {
- genVideoUsingMuxer(src.getPath(), dst.getPath(), startMs, endMs,
- true, true);
- } else {
- trimUsingMp4Parser(src, dst, startMs, endMs);
- }
- }
-
- private static void startMuteUsingMp4Parser(String filePath,
- SaveVideoFileInfo dstFileInfo) throws FileNotFoundException, IOException {
- File dst = dstFileInfo.mFile;
- File src = new File(filePath);
- RandomAccessFile randomAccessFile = new RandomAccessFile(src, "r");
- Movie movie = MovieCreator.build(randomAccessFile.getChannel());
-
- // remove all tracks we will create new tracks from the old
- List<Track> tracks = movie.getTracks();
- movie.setTracks(new LinkedList<Track>());
-
- for (Track track : tracks) {
- if (track.getHandler().equals("vide")) {
- movie.addTrack(track);
- }
- }
- writeMovieIntoFile(dst, movie);
- randomAccessFile.close();
- }
-
- private static void writeMovieIntoFile(File dst, Movie movie)
- throws IOException {
- if (!dst.exists()) {
- dst.createNewFile();
- }
-
- IsoFile out = new DefaultMp4Builder().build(movie);
- FileOutputStream fos = new FileOutputStream(dst);
- FileChannel fc = fos.getChannel();
- out.getBox(fc); // This one build up the memory.
-
- fc.close();
- fos.close();
- }
-
- /**
- * @param srcPath the path of source video file.
- * @param dstPath the path of destination video file.
- * @param startMs starting time in milliseconds for trimming. Set to
- * negative if starting from beginning.
- * @param endMs end time for trimming in milliseconds. Set to negative if
- * no trimming at the end.
- * @param useAudio true if keep the audio track from the source.
- * @param useVideo true if keep the video track from the source.
- * @throws IOException
- */
- private static void genVideoUsingMuxer(String srcPath, String dstPath,
- int startMs, int endMs, boolean useAudio, boolean useVideo)
- throws IOException {
- // Set up MediaExtractor to read from the source.
- MediaExtractor extractor = new MediaExtractor();
- extractor.setDataSource(srcPath);
-
- int trackCount = extractor.getTrackCount();
-
- // Set up MediaMuxer for the destination.
- MediaMuxer muxer;
- muxer = new MediaMuxer(dstPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
-
- // Set up the tracks and retrieve the max buffer size for selected
- // tracks.
- HashMap<Integer, Integer> indexMap = new HashMap<Integer,
- Integer>(trackCount);
- int bufferSize = -1;
- for (int i = 0; i < trackCount; i++) {
- MediaFormat format = extractor.getTrackFormat(i);
- String mime = format.getString(MediaFormat.KEY_MIME);
-
- boolean selectCurrentTrack = false;
-
- if (mime.startsWith("audio/") && useAudio) {
- selectCurrentTrack = true;
- } else if (mime.startsWith("video/") && useVideo) {
- selectCurrentTrack = true;
- }
-
- if (selectCurrentTrack) {
- extractor.selectTrack(i);
- int dstIndex = muxer.addTrack(format);
- indexMap.put(i, dstIndex);
- if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
- int newSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
- bufferSize = newSize > bufferSize ? newSize : bufferSize;
- }
- }
- }
-
- if (bufferSize < 0) {
- bufferSize = DEFAULT_BUFFER_SIZE;
- }
-
- // Set up the orientation and starting time for extractor.
- MediaMetadataRetriever retrieverSrc = new MediaMetadataRetriever();
- retrieverSrc.setDataSource(srcPath);
- String degreesString = retrieverSrc.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
- if (degreesString != null) {
- int degrees = Integer.parseInt(degreesString);
- if (degrees >= 0) {
- muxer.setOrientationHint(degrees);
- }
- }
-
- if (startMs > 0) {
- extractor.seekTo(startMs * 1000, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
- }
-
- // Copy the samples from MediaExtractor to MediaMuxer. We will loop
- // for copying each sample and stop when we get to the end of the source
- // file or exceed the end time of the trimming.
- int offset = 0;
- int trackIndex = -1;
- ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize);
- BufferInfo bufferInfo = new BufferInfo();
-
- muxer.start();
- while (true) {
- bufferInfo.offset = offset;
- bufferInfo.size = extractor.readSampleData(dstBuf, offset);
- if (bufferInfo.size < 0) {
- Log.d(LOGTAG, "Saw input EOS.");
- bufferInfo.size = 0;
- break;
- } else {
- bufferInfo.presentationTimeUs = extractor.getSampleTime();
- if (endMs > 0 && bufferInfo.presentationTimeUs > (endMs * 1000)) {
- Log.d(LOGTAG, "The current sample is over the trim end time.");
- break;
- } else {
- bufferInfo.flags = extractor.getSampleFlags();
- trackIndex = extractor.getSampleTrackIndex();
-
- muxer.writeSampleData(indexMap.get(trackIndex), dstBuf,
- bufferInfo);
- extractor.advance();
- }
- }
- }
-
- muxer.stop();
- muxer.release();
- return;
- }
-
- private static void trimUsingMp4Parser(File src, File dst, int startMs, int endMs)
- throws FileNotFoundException, IOException {
- RandomAccessFile randomAccessFile = new RandomAccessFile(src, "r");
- Movie movie = MovieCreator.build(randomAccessFile.getChannel());
-
- // remove all tracks we will create new tracks from the old
- List<Track> tracks = movie.getTracks();
- movie.setTracks(new LinkedList<Track>());
-
- double startTime = startMs / 1000;
- double endTime = endMs / 1000;
-
- boolean timeCorrected = false;
-
- // Here we try to find a track that has sync samples. Since we can only
- // start decoding at such a sample we SHOULD make sure that the start of
- // the new fragment is exactly such a frame.
- for (Track track : tracks) {
- if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
- if (timeCorrected) {
- // This exception here could be a false positive in case we
- // have multiple tracks with sync samples at exactly the
- // same positions. E.g. a single movie containing multiple
- // qualities of the same video (Microsoft Smooth Streaming
- // file)
- throw new RuntimeException(
- "The startTime has already been corrected by" +
- " another track with SyncSample. Not Supported.");
- }
- startTime = correctTimeToSyncSample(track, startTime, false);
- endTime = correctTimeToSyncSample(track, endTime, true);
- timeCorrected = true;
- }
- }
-
- for (Track track : tracks) {
- long currentSample = 0;
- double currentTime = 0;
- long startSample = -1;
- long endSample = -1;
-
- for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
- TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
- for (int j = 0; j < entry.getCount(); j++) {
- // entry.getDelta() is the amount of time the current sample
- // covers.
-
- if (currentTime <= startTime) {
- // current sample is still before the new starttime
- startSample = currentSample;
- }
- if (currentTime <= endTime) {
- // current sample is after the new start time and still
- // before the new endtime
- endSample = currentSample;
- } else {
- // current sample is after the end of the cropped video
- break;
- }
- currentTime += (double) entry.getDelta()
- / (double) track.getTrackMetaData().getTimescale();
- currentSample++;
- }
- }
- movie.addTrack(new CroppedTrack(track, startSample, endSample));
- }
- writeMovieIntoFile(dst, movie);
- randomAccessFile.close();
- }
-
- private static double correctTimeToSyncSample(Track track, double cutHere,
- boolean next) {
- double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
- long currentSample = 0;
- double currentTime = 0;
- for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
- TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
- for (int j = 0; j < entry.getCount(); j++) {
- if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
- // samples always start with 1 but we start with zero
- // therefore +1
- timeOfSyncSamples[Arrays.binarySearch(
- track.getSyncSamples(), currentSample + 1)] = currentTime;
- }
- currentTime += (double) entry.getDelta()
- / (double) track.getTrackMetaData().getTimescale();
- currentSample++;
- }
- }
- double previous = 0;
- for (double timeOfSyncSample : timeOfSyncSamples) {
- if (timeOfSyncSample > cutHere) {
- if (next) {
- return timeOfSyncSample;
- } else {
- return previous;
- }
- }
- previous = timeOfSyncSample;
- }
- return timeOfSyncSamples[timeOfSyncSamples.length - 1];
- }
-
-}
diff --git a/src/com/android/gallery3d/app/Wallpaper.java b/src/com/android/gallery3d/app/Wallpaper.java
deleted file mode 100644
index b0a26c236..000000000
--- a/src/com/android/gallery3d/app/Wallpaper.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2007 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.app;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Point;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.view.Display;
-
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.filtershow.crop.CropActivity;
-import com.android.gallery3d.filtershow.crop.CropExtras;
-
-/**
- * Wallpaper picker for the gallery application. This just redirects to the
- * standard pick action.
- */
-public class Wallpaper extends Activity {
- @SuppressWarnings("unused")
- private static final String TAG = "Wallpaper";
-
- private static final String IMAGE_TYPE = "image/*";
- private static final String KEY_STATE = "activity-state";
- private static final String KEY_PICKED_ITEM = "picked-item";
-
- private static final int STATE_INIT = 0;
- private static final int STATE_PHOTO_PICKED = 1;
-
- private int mState = STATE_INIT;
- private Uri mPickedItem;
-
- @Override
- protected void onCreate(Bundle bundle) {
- super.onCreate(bundle);
- if (bundle != null) {
- mState = bundle.getInt(KEY_STATE);
- mPickedItem = (Uri) bundle.getParcelable(KEY_PICKED_ITEM);
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle saveState) {
- saveState.putInt(KEY_STATE, mState);
- if (mPickedItem != null) {
- saveState.putParcelable(KEY_PICKED_ITEM, mPickedItem);
- }
- }
-
- @SuppressWarnings("deprecation")
- @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
- private Point getDefaultDisplaySize(Point size) {
- Display d = getWindowManager().getDefaultDisplay();
- if (Build.VERSION.SDK_INT >= ApiHelper.VERSION_CODES.HONEYCOMB_MR2) {
- d.getSize(size);
- } else {
- size.set(d.getWidth(), d.getHeight());
- }
- return size;
- }
-
- @SuppressWarnings("fallthrough")
- @Override
- protected void onResume() {
- super.onResume();
- Intent intent = getIntent();
- switch (mState) {
- case STATE_INIT: {
- mPickedItem = intent.getData();
- if (mPickedItem == null) {
- Intent request = new Intent(Intent.ACTION_GET_CONTENT)
- .setClass(this, DialogPicker.class)
- .setType(IMAGE_TYPE);
- startActivityForResult(request, STATE_PHOTO_PICKED);
- return;
- }
- mState = STATE_PHOTO_PICKED;
- // fall-through
- }
- case STATE_PHOTO_PICKED: {
- int width = getWallpaperDesiredMinimumWidth();
- int height = getWallpaperDesiredMinimumHeight();
- Point size = getDefaultDisplaySize(new Point());
- float spotlightX = (float) size.x / width;
- float spotlightY = (float) size.y / height;
- Intent request = new Intent(CropActivity.CROP_ACTION)
- .setDataAndType(mPickedItem, IMAGE_TYPE)
- .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
- .putExtra(CropExtras.KEY_OUTPUT_X, width)
- .putExtra(CropExtras.KEY_OUTPUT_Y, height)
- .putExtra(CropExtras.KEY_ASPECT_X, width)
- .putExtra(CropExtras.KEY_ASPECT_Y, height)
- .putExtra(CropExtras.KEY_SPOTLIGHT_X, spotlightX)
- .putExtra(CropExtras.KEY_SPOTLIGHT_Y, spotlightY)
- .putExtra(CropExtras.KEY_SCALE, true)
- .putExtra(CropExtras.KEY_SCALE_UP_IF_NEEDED, true)
- .putExtra(CropExtras.KEY_SET_AS_WALLPAPER, true);
- startActivity(request);
- finish();
- }
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode != RESULT_OK) {
- setResult(resultCode);
- finish();
- return;
- }
- mState = requestCode;
- if (mState == STATE_PHOTO_PICKED) {
- mPickedItem = data.getData();
- }
-
- // onResume() would be called next
- }
-}