summaryrefslogtreecommitdiffstats
path: root/src/org/codeaurora/gallery3d/ext
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/codeaurora/gallery3d/ext')
-rw-r--r--src/org/codeaurora/gallery3d/ext/ActivityHooker.java96
-rw-r--r--src/org/codeaurora/gallery3d/ext/ActivityHookerGroup.java150
-rw-r--r--src/org/codeaurora/gallery3d/ext/IActivityHooker.java128
-rw-r--r--src/org/codeaurora/gallery3d/ext/IContrllerOverlayExt.java51
-rw-r--r--src/org/codeaurora/gallery3d/ext/IMovieItem.java66
-rw-r--r--src/org/codeaurora/gallery3d/ext/IMovieList.java46
-rw-r--r--src/org/codeaurora/gallery3d/ext/IMovieListLoader.java51
-rw-r--r--src/org/codeaurora/gallery3d/ext/IMoviePlayer.java42
-rw-r--r--src/org/codeaurora/gallery3d/ext/MovieItem.java115
-rw-r--r--src/org/codeaurora/gallery3d/ext/MovieList.java72
-rw-r--r--src/org/codeaurora/gallery3d/ext/MovieListLoader.java269
-rw-r--r--src/org/codeaurora/gallery3d/ext/MovieUtils.java98
12 files changed, 1184 insertions, 0 deletions
diff --git a/src/org/codeaurora/gallery3d/ext/ActivityHooker.java b/src/org/codeaurora/gallery3d/ext/ActivityHooker.java
new file mode 100644
index 000000000..65761ff23
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/ActivityHooker.java
@@ -0,0 +1,96 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * Default implemention class of IActivityHooker.
+ */
+public class ActivityHooker implements IActivityHooker {
+
+ private static final int MENU_MAX_NUMBER = 100;
+ private static int sMenuId = 1;
+ private int mMenuId;
+ private static Object sMenuLock = new Object();
+ private Activity mContext;
+ private Intent mIntent;
+
+ public ActivityHooker() {
+ synchronized (sMenuLock) {
+ sMenuId++;
+ mMenuId = sMenuId * MENU_MAX_NUMBER;
+ }
+ }
+
+ @Override
+ public int getMenuActivityId(int id) {
+ return mMenuId + id;
+ };
+
+ @Override
+ public int getMenuOriginalId(int id) {
+ return id - mMenuId;
+ }
+
+ @Override
+ public void init(Activity context, Intent intent) {
+ mContext = context;
+ mIntent = intent;
+ }
+
+ @Override
+ public Activity getContext() {
+ return mContext;
+ }
+
+ @Override
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ }
+
+ @Override
+ public void onStart() {
+ }
+
+ @Override
+ public void onResume() {
+ }
+
+ @Override
+ public void onPause() {
+ }
+
+ @Override
+ public void onStop() {
+ }
+
+ @Override
+ public void onDestroy() {
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ return false;
+ }
+
+ @Override
+ public void setParameter(String key, Object value) {
+ }
+}
diff --git a/src/org/codeaurora/gallery3d/ext/ActivityHookerGroup.java b/src/org/codeaurora/gallery3d/ext/ActivityHookerGroup.java
new file mode 100644
index 000000000..4bf8616e7
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/ActivityHookerGroup.java
@@ -0,0 +1,150 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import java.util.ArrayList;
+
+/**
+ * The composite pattern class. It will deliver every action to its leaf
+ * hookers.
+ */
+public class ActivityHookerGroup extends ActivityHooker {
+ private ArrayList<IActivityHooker> mHooks = new ArrayList<IActivityHooker>();
+
+ /**
+ * Add hooker to current group.
+ *
+ * @param hooker
+ * @return
+ */
+ public boolean addHooker(IActivityHooker hooker) {
+ return mHooks.add(hooker);
+ }
+
+ /**
+ * Remove hooker from current group.
+ *
+ * @param hooker
+ * @return
+ */
+ public boolean removeHooker(IActivityHooker hooker) {
+ return mHooks.remove(hooker);
+ }
+
+ /**
+ * Get hooker of requested location.
+ *
+ * @param index
+ * @return
+ */
+ public IActivityHooker getHooker(int index) {
+ return mHooks.get(index);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ for (IActivityHooker hook : mHooks) {
+ hook.onCreate(savedInstanceState);
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ for (IActivityHooker hook : mHooks) {
+ hook.onStart();
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ for (IActivityHooker hook : mHooks) {
+ hook.onResume();
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ for (IActivityHooker hook : mHooks) {
+ hook.onPause();
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ for (IActivityHooker hook : mHooks) {
+ hook.onStop();
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ for (IActivityHooker hook : mHooks) {
+ hook.onDestroy();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ boolean handle = false;
+ for (IActivityHooker hook : mHooks) {
+ boolean one = hook.onCreateOptionsMenu(menu);
+ if (!handle) {
+ handle = one;
+ }
+ }
+ return handle;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ boolean handle = false;
+ for (IActivityHooker hook : mHooks) {
+ boolean one = hook.onPrepareOptionsMenu(menu);
+ if (!handle) {
+ handle = one;
+ }
+ }
+ return handle;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ super.onOptionsItemSelected(item);
+ boolean handle = false;
+ for (IActivityHooker hook : mHooks) {
+ boolean one = hook.onOptionsItemSelected(item);
+ if (!handle) {
+ handle = one;
+ }
+ }
+ return handle;
+ }
+
+ @Override
+ public void setParameter(String key, Object value) {
+ super.setParameter(key, value);
+ for (IActivityHooker hook : mHooks) {
+ hook.setParameter(key, value);
+ }
+ }
+
+ @Override
+ public void init(Activity context, Intent intent) {
+ super.init(context, intent);
+ for (IActivityHooker hook : mHooks) {
+ hook.init(context, intent);
+ }
+ }
+}
diff --git a/src/org/codeaurora/gallery3d/ext/IActivityHooker.java b/src/org/codeaurora/gallery3d/ext/IActivityHooker.java
new file mode 100644
index 000000000..a83799626
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/IActivityHooker.java
@@ -0,0 +1,128 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * Activity action hooker class. Host app's activity will call this hooker's
+ * functions in its lifecycle. For example:
+ * HostActivity.onCreate()-->hooker.onCreate(). But void init(Activity context,
+ * Intent intent) will be called before other functions. <br/>
+ * IActivityHooker objects may show menus, but we should give a unique menu id
+ * to every menus. Hooker can call getMenuActivityId(int) to get a global unique
+ * menu id to be used in menu.add(), and can call getMenuOriginalId(int) to get
+ * the original menu id. the example: class Hooker implements IActivityHooker {
+ * private static final int MENU_EXAMPLE = 1;
+ *
+ * @Override public boolean onCreateOptionsMenu(Menu menu) {
+ * super.onCreateOptionsMenu(menu); menu.add(0,
+ * getMenuActivityId(MENU_EXAMPLE), 0, android.R.string.ok); return
+ * true; }
+ * @Override public boolean onOptionsItemSelected(MenuItem item) {
+ * switch(getMenuOriginalId(item.getItemId())) { case MENU_EXAMPLE:
+ * //do something return true; default: return false; } } }
+ */
+public interface IActivityHooker {
+ /**
+ * Will be called in Host Activity.onCreate(Bundle savedInstanceState)
+ * @param savedInstanceState
+ */
+ void onCreate(Bundle savedInstanceState);
+ /**
+ * Will be called in Host Activity.onStart()
+ */
+ void onStart();
+ /**
+ * Will be called in Host Activity.onStop()
+ */
+ void onStop();
+ /**
+ * Will be called in Host Activity.onPause()
+ */
+ void onPause();
+ /**
+ * Will be called in Host Activity.onResume()
+ */
+ void onResume();
+ /**
+ * Will be called in Host Activity.onDestroy()
+ */
+ void onDestroy();
+ /**
+ * Will be called in Host Activity.onCreateOptionsMenu(Menu menu)
+ * @param menu
+ * @return
+ */
+ /**
+ * Will be called in Host Activity.onCreateOptionsMenu(Menu menu)
+ *
+ * @param menu
+ * @return
+ */
+ boolean onCreateOptionsMenu(Menu menu);
+
+ /**
+ * Will be called in Host Activity.onPrepareOptionsMenu(Menu menu)
+ *
+ * @param menu
+ * @return
+ */
+ boolean onPrepareOptionsMenu(Menu menu);
+
+ /**
+ * Will be called in Host Activity.onOptionsItemSelected(MenuItem item)
+ *
+ * @param item
+ * @return
+ */
+ boolean onOptionsItemSelected(MenuItem item);
+
+ /**
+ * Should be called before any other functions.
+ *
+ * @param context
+ * @param intent
+ */
+ void init(Activity context, Intent intent);
+
+ /**
+ * @return return activity set by init(Activity context, Intent intent)
+ */
+ Activity getContext();
+
+ /**
+ * @return return intent set by init(Activity context, Intent intent)
+ */
+ Intent getIntent();
+
+ /**
+ * IActivityHooker objects may show menus, but we should give a unique menu
+ * id to every menus. Hooker can call this function to get a global unique
+ * menu id to be used in menu.add()
+ *
+ * @param id
+ * @return
+ */
+ int getMenuActivityId(int id);
+
+ /**
+ * When onOptionsItemSelected is called, we can get menu's id from
+ * parameter. You can get the original menu id by calling this function.
+ *
+ * @param id
+ * @return
+ */
+ int getMenuOriginalId(int id);
+
+ /**
+ * Host activity will call this function to set parameter to hooker
+ * activity.
+ *
+ * @param key
+ * @param value
+ */
+ void setParameter(String key, Object value);
+}
diff --git a/src/org/codeaurora/gallery3d/ext/IContrllerOverlayExt.java b/src/org/codeaurora/gallery3d/ext/IContrllerOverlayExt.java
new file mode 100644
index 000000000..da50cdffc
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/IContrllerOverlayExt.java
@@ -0,0 +1,51 @@
+package org.codeaurora.gallery3d.ext;
+/**
+ * Controller overlay extension interface.
+ */
+public interface IContrllerOverlayExt {
+ /**
+ * Show buffering state.
+ * @param fullBuffer
+ * @param percent
+ */
+ void showBuffering(boolean fullBuffer, int percent);
+ /**
+ * Clear buffering state.
+ */
+ void clearBuffering();
+ /**
+ * Show re-connecting state.
+ * @param times
+ */
+ void showReconnecting(int times);
+ /**
+ * Show re-connecting error for connecting fail error.
+ */
+ void showReconnectingError();
+ /**
+ * Show playing info or not.
+ * @param liveStreaming true means showing playing info, otherwise doesn't show playing info.
+ */
+ void setPlayingInfo(boolean liveStreaming);
+ /**
+ * Indicates whether current video can be paused or not.
+ * @param canPause
+ */
+ void setCanPause(boolean canPause);
+ /**
+ * Indicates whether thumb can be scrubbed or not.
+ * @param enable
+ */
+ void setCanScrubbing(boolean enable);
+ /**
+ * Always show bottmon panel or not.
+ * @param alwaysShow
+ * @param foreShow
+ */
+ void setBottomPanel(boolean alwaysShow, boolean foreShow);
+ /**
+ * Is playing end or not.
+ * @return
+ */
+ boolean isPlayingEnd();
+}
diff --git a/src/org/codeaurora/gallery3d/ext/IMovieItem.java b/src/org/codeaurora/gallery3d/ext/IMovieItem.java
new file mode 100644
index 000000000..dece4e803
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/IMovieItem.java
@@ -0,0 +1,66 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.net.Uri;
+
+/**
+ * Movie info class
+ */
+public interface IMovieItem {
+ /**
+ * @return movie Uri, it's may be not the original Uri.
+ */
+ Uri getUri();
+
+ /**
+ * @return MIME type of video
+ */
+ String getMimeType();
+
+ /**
+ * @return title of video
+ */
+ String getTitle();
+
+ /**
+ * @return whether error occured or not.
+ */
+ boolean getError();
+
+ /**
+ * set title of video
+ *
+ * @param title
+ */
+ void setTitle(String title);
+
+ /**
+ * set video Uri
+ *
+ * @param uri
+ */
+ void setUri(Uri uri);
+
+ /**
+ * Set MIME type of video
+ *
+ * @param mimeType
+ */
+ void setMimeType(String mimeType);
+
+ /**
+ * Set error occured flag
+ */
+ void setError();
+
+ /**
+ * @return return original Uri of video.
+ */
+ Uri getOriginalUri();
+
+ /**
+ * Set video original Uri.
+ *
+ * @param uri
+ */
+ void setOriginalUri(Uri uri);
+}
diff --git a/src/org/codeaurora/gallery3d/ext/IMovieList.java b/src/org/codeaurora/gallery3d/ext/IMovieList.java
new file mode 100644
index 000000000..404d24c41
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/IMovieList.java
@@ -0,0 +1,46 @@
+package org.codeaurora.gallery3d.ext;
+/**
+ * Movie list extension interface
+ */
+public interface IMovieList {
+ /**
+ * Add movie item to list.
+ * @param item
+ */
+ void add(IMovieItem item);
+ /**
+ * Get the item index of list
+ * @param item
+ * @return
+ */
+ int index(IMovieItem item);
+ /**
+ *
+ * @return list size
+ */
+ int size();
+ /**
+ *
+ * @param item
+ * @return next item of current item
+ */
+ IMovieItem getNext(IMovieItem item);
+ /**
+ *
+ * @param item
+ * @return previous item of current item
+ */
+ IMovieItem getPrevious(IMovieItem item);
+ /**
+ * Is first item in list
+ * @param item
+ * @return
+ */
+ boolean isFirst(IMovieItem item);
+ /**
+ * Is last item in list.
+ * @param item
+ * @return
+ */
+ boolean isLast(IMovieItem item);
+} \ No newline at end of file
diff --git a/src/org/codeaurora/gallery3d/ext/IMovieListLoader.java b/src/org/codeaurora/gallery3d/ext/IMovieListLoader.java
new file mode 100644
index 000000000..fe5999858
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/IMovieListLoader.java
@@ -0,0 +1,51 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+
+public interface IMovieListLoader {
+ /**
+ * Load all video list or not.[boolean]
+ * "yes" means load all videos in all storages.
+ * "false" means load videos located in current video's folder.
+ */
+ String EXTRA_ALL_VIDEO_FOLDER = "org.codeaurora.intent.extra.ALL_VIDEO_FOLDER";
+ /**
+ * Video list order by column name.[String]
+ */
+ String EXTRA_ORDERBY = "org.codeaurora.intent.extra.VIDEO_LIST_ORDERBY";
+ /**
+ * Enable video list or not.[boolean]
+ */
+ String EXTRA_ENABLE_VIDEO_LIST = "org.codeaurora.intent.extra.ENABLE_VIDEO_LIST";
+ /**
+ * Loader listener interface
+ */
+ public interface LoaderListener {
+ /**
+ * Will be called after movie list loaded.
+ * @param movieList
+ */
+ void onListLoaded(IMovieList movieList);
+ }
+ /**
+ * Build the movie list from current item.
+ * @param context
+ * @param intent
+ * @param l
+ * @param item
+ */
+ void fillVideoList(Activity context, Intent intent, LoaderListener l, IMovieItem item);
+ /**
+ * enable video list or not.
+ * @param intent
+ * @return
+ */
+ boolean isEnabledVideoList(Intent intent);
+ /**
+ * Cancel current loading process.
+ */
+ void cancelList();
+
+}
diff --git a/src/org/codeaurora/gallery3d/ext/IMoviePlayer.java b/src/org/codeaurora/gallery3d/ext/IMoviePlayer.java
new file mode 100644
index 000000000..32d400b0d
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/IMoviePlayer.java
@@ -0,0 +1,42 @@
+package org.codeaurora.gallery3d.ext;
+
+public interface IMoviePlayer {
+
+ /**
+ * add new bookmark Uri.
+ */
+ void addBookmark();
+
+ /**
+ * Loop current video.
+ *
+ * @param loop
+ */
+ void setLoop(boolean loop);
+
+ /**
+ * Loop current video or not
+ *
+ * @return
+ */
+ boolean getLoop();
+
+ /**
+ * Can stop current video or not.
+ *
+ * @return
+ */
+ boolean canStop();
+
+ /**
+ * Stop current video.
+ */
+ void stopVideo();
+
+ /**
+ * start current item and stop playing video.
+ *
+ * @param item
+ */
+ void startNextVideo(IMovieItem item);
+}
diff --git a/src/org/codeaurora/gallery3d/ext/MovieItem.java b/src/org/codeaurora/gallery3d/ext/MovieItem.java
new file mode 100644
index 000000000..56afdda4b
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/MovieItem.java
@@ -0,0 +1,115 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.net.Uri;
+import android.provider.MediaStore;
+
+public class MovieItem implements IMovieItem {
+ private static final String TAG = "MovieItem";
+ private static final boolean LOG = false;
+
+ private Uri mUri;
+ private String mMimeType;
+ private String mTitle;
+ private boolean mError;
+ // private int mStereoType;
+ private Uri mOriginal;
+
+ private static final int STREO_TYPE_2D = 1;
+
+ public MovieItem(Uri uri, String mimeType, String title, int stereoType) {
+ mUri = uri;
+ mMimeType = mimeType;
+ mTitle = title;
+ // mStereoType = stereoType;
+ mOriginal = uri;
+ }
+
+ public MovieItem(String uri, String mimeType, String title, int stereoType) {
+ this(Uri.parse(uri), mimeType, title, stereoType);
+ }
+
+ public MovieItem(Uri uri, String mimeType, String title) {
+ this(uri, mimeType, title, STREO_TYPE_2D);
+ }
+
+ public MovieItem(String uri, String mimeType, String title) {
+ this(Uri.parse(uri), mimeType, title);
+ }
+
+ @Override
+ public Uri getUri() {
+ return mUri;
+ }
+
+ @Override
+ public String getMimeType() {
+ return mMimeType;
+ }
+
+ @Override
+ public String getTitle() {
+ return mTitle;
+ }
+
+ @Override
+ public boolean getError() {
+ return mError;
+ }
+
+ // @Override
+ // public int getStereoType() {
+ // return mStereoType;
+ // }
+
+ public void setTitle(String title) {
+ mTitle = title;
+ }
+
+ @Override
+ public void setUri(Uri uri) {
+ mUri = uri;
+ }
+
+ @Override
+ public void setMimeType(String mimeType) {
+ mMimeType = mimeType;
+ }
+
+ // @Override
+ // public void setStereoType(int stereoType) {
+ // mStereoType = stereoType;
+ // }
+
+ @Override
+ public void setError() {
+ mError = true;
+ }
+
+ @Override
+ public Uri getOriginalUri() {
+ return mOriginal;
+ }
+
+ @Override
+ public void setOriginalUri(Uri uri) {
+ mOriginal = uri;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder().append("MovieItem(uri=")
+ .append(mUri)
+ .append(", mime=")
+ .append(mMimeType)
+ .append(", title=")
+ .append(mTitle)
+ .append(", error=")
+ .append(mError)
+ // .append(", support3D=")
+ // .append(mStereoType)
+ .append(", mOriginal=")
+ .append(mOriginal)
+ .append(")")
+ .toString();
+ }
+}
diff --git a/src/org/codeaurora/gallery3d/ext/MovieList.java b/src/org/codeaurora/gallery3d/ext/MovieList.java
new file mode 100644
index 000000000..ecb7f0db3
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/MovieList.java
@@ -0,0 +1,72 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class MovieList implements IMovieList {
+ private static final String TAG = "MovieList";
+ private static final boolean LOG = false;
+
+ private final ArrayList<IMovieItem> mItems = new ArrayList<IMovieItem>();
+ private static final int UNKNOWN = -1;
+
+ @Override
+ public void add(IMovieItem item) {
+ if (LOG) {
+ Log.v(TAG, "add(" + item + ")");
+ }
+ mItems.add(item);
+ }
+
+ @Override
+ public int index(IMovieItem item) {
+ int find = UNKNOWN;
+ int size = mItems.size();
+ for (int i = 0; i < size; i++) {
+ if (item == mItems.get(i)) {
+ find = i;
+ break;
+ }
+ }
+ if (LOG) {
+ Log.v(TAG, "index(" + item + ") return " + find);
+ }
+ return find;
+ }
+
+ @Override
+ public int size() {
+ return mItems.size();
+ }
+
+ @Override
+ public IMovieItem getNext(IMovieItem item) {
+ IMovieItem next = null;
+ int find = index(item);
+ if (find >= 0 && find < size() - 1) {
+ next = mItems.get(++find);
+ }
+ return next;
+ }
+
+ @Override
+ public IMovieItem getPrevious(IMovieItem item) {
+ IMovieItem prev = null;
+ int find = index(item);
+ if (find > 0 && find < size()) {
+ prev = mItems.get(--find);
+ }
+ return prev;
+ }
+
+ @Override
+ public boolean isFirst(IMovieItem item) {
+ return getPrevious(item) == null;
+ }
+
+ @Override
+ public boolean isLast(IMovieItem item) {
+ return getNext(item) == null;
+ }
+}
diff --git a/src/org/codeaurora/gallery3d/ext/MovieListLoader.java b/src/org/codeaurora/gallery3d/ext/MovieListLoader.java
new file mode 100644
index 000000000..60f0392de
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/MovieListLoader.java
@@ -0,0 +1,269 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.provider.MediaStore;
+import android.provider.OpenableColumns;
+import android.util.Log;
+
+import java.io.File;
+import java.util.ArrayList;
+
+/**
+ * Movie list loader class. It will load videos from MediaProvider database.
+ * If MoviePlayer starting activity doesn't set any thing, default OrderBy will be used.
+ * Default OrderBy: MediaStore.Video.Media.DATE_TAKEN + " DESC, " + MediaStore.Video.Media._ID + " DESC ";
+ */
+public class MovieListLoader implements IMovieListLoader {
+ private static final String TAG = "MovieListLoader";
+ private static final boolean LOG = false;
+
+ private MovieListFetcherTask mListTask;
+
+ @Override
+ public void fillVideoList(Activity activity, Intent intent, final LoaderListener l,
+ IMovieItem currentMovieItem) {
+
+ // determine if a video playlist has been passed in through the intent
+ // if a playlist does exist, use that
+ ArrayList<Uri> uris = intent.getParcelableArrayListExtra("EXTRA_FILE_LIST");
+ if (uris != null) {
+ final MovieList movieList = new MovieList();
+ ContentResolver cr = activity.getContentResolver();
+
+ for(Uri uri : uris) {
+ // add currentMovieItem in its proper place in the video playlist
+ // 'Next' and 'Previous' functionality in MovieListHooker is dependent on reference
+ // matching currentMovieItem
+ if (currentMovieItem.getOriginalUri().equals(uri)) {
+ movieList.add(currentMovieItem);
+ continue;
+ }
+
+ File videoFile = new File(uri.getPath());
+ movieList.add(new MovieItem(uri, cr.getType(uri), videoFile.getName()));
+ }
+
+ // notify callback on main thread
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ l.onListLoaded(movieList);
+ }
+ });
+
+ return;
+ }
+
+ // proceed with creating a playlist if one isn't found
+ boolean fetechAll = false;
+ if (intent.hasExtra(EXTRA_ALL_VIDEO_FOLDER)) {
+ fetechAll = intent.getBooleanExtra(EXTRA_ALL_VIDEO_FOLDER, false);
+ }
+ //default order by
+ String orderBy = MediaStore.Video.Media.DATE_TAKEN + " DESC, " + MediaStore.Video.Media._ID + " DESC ";
+ if (intent.hasExtra(EXTRA_ORDERBY)) {
+ orderBy = intent.getStringExtra(EXTRA_ORDERBY);
+ }
+ cancelList();
+ mListTask = new MovieListFetcherTask(activity, fetechAll, l, orderBy);
+ mListTask.execute(currentMovieItem);
+ if (LOG) {
+ Log.v(TAG, "fillVideoList() fetechAll=" + fetechAll + ", orderBy=" + orderBy);
+ }
+ }
+
+ @Override
+ public boolean isEnabledVideoList(Intent intent) {
+ boolean enable = true;
+ if (intent != null && intent.hasExtra(EXTRA_ENABLE_VIDEO_LIST)) {
+ enable = intent.getBooleanExtra(EXTRA_ENABLE_VIDEO_LIST, true);
+ }
+ if (LOG) {
+ Log.v(TAG, "isEnabledVideoList() return " + enable);
+ }
+ return enable;
+ }
+
+ @Override
+ public void cancelList() {
+ if (mListTask != null) {
+ mListTask.cancel(true);
+ }
+ }
+
+ private class MovieListFetcherTask extends AsyncTask<IMovieItem, Void, IMovieList> {
+ private static final String TAG = "MovieListFetcherTask";
+ private static final boolean LOG = false;
+
+ // TODO comments by sunlei
+// public static final String COLUMN_STEREO_TYPE = MediaStore.Video.Media.STEREO_TYPE;
+// public static final String COLUMN_STEREO_TYPE = "STEREO_TYPE";
+
+ private final ContentResolver mCr;
+ private final LoaderListener mFetecherListener;
+ private final boolean mFetechAll;
+ private final String mOrderBy;
+
+ public MovieListFetcherTask(Context context, boolean fetechAll, LoaderListener l, String orderBy) {
+ mCr = context.getContentResolver();
+ mFetecherListener = l;
+ mFetechAll = fetechAll;
+ mOrderBy = orderBy;
+ if (LOG) {
+ Log.v(TAG, "MovieListFetcherTask() fetechAll=" + fetechAll + ", orderBy=" + orderBy);
+ }
+ }
+
+ @Override
+ protected void onPostExecute(IMovieList params) {
+ if (LOG) {
+ Log.v(TAG, "onPostExecute() isCancelled()=" + isCancelled());
+ }
+ if (isCancelled()) {
+ return;
+ }
+ if (mFetecherListener != null) {
+ mFetecherListener.onListLoaded(params);
+ }
+ }
+
+ @Override
+ protected IMovieList doInBackground(IMovieItem... params) {
+ if (LOG) {
+ Log.v(TAG, "doInBackground() begin");
+ }
+ if (params[0] == null) {
+ return null;
+ }
+ IMovieList movieList = null;
+ Uri uri = params[0].getUri();
+ String mime = params[0].getMimeType();
+ if (mFetechAll) { //get all list
+ if (MovieUtils.isLocalFile(uri, mime)) {
+ String uristr = String.valueOf(uri);
+ if (uristr.toLowerCase().startsWith("content://media")) {
+ //from gallery, gallery3D, videoplayer
+ long curId = Long.parseLong(uri.getPathSegments().get(3));
+ movieList = fillUriList(null, null, curId, params[0]);
+ } else if (uristr.toLowerCase().startsWith("file://")) {
+ long curId = getCursorId(uri);
+ movieList = fillUriList(null, null, curId, params[0]);
+ }
+ }
+ } else { //get current list
+ if (MovieUtils.isLocalFile(uri, mime)) {
+ String uristr = String.valueOf(uri);
+ if (uristr.toLowerCase().startsWith("content://media")) {
+ Cursor cursor = mCr.query(uri,
+ new String[]{MediaStore.Video.Media.BUCKET_ID},
+ null, null, null);
+ long bucketId = -1;
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ bucketId = cursor.getLong(0);
+ }
+ cursor.close();
+ }
+ long curId = Long.parseLong(uri.getPathSegments().get(3));
+ movieList = fillUriList(MediaStore.Video.Media.BUCKET_ID + "=? ",
+ new String[]{String.valueOf(bucketId)}, curId, params[0]);
+ } else if (uristr.toLowerCase().startsWith("file://")) {
+ String data = Uri.decode(uri.toString());
+ data = data.replaceAll("'", "''");
+ String where = "_data LIKE '%" + data.replaceFirst("file:///", "") + "'";
+ Cursor cursor = mCr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
+ new String[]{"_id", MediaStore.Video.Media.BUCKET_ID},
+ where, null, null);
+ long bucketId = -1;
+ long curId = -1;
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ curId = cursor.getLong(0);
+ bucketId = cursor.getLong(1);
+ }
+ cursor.close();
+ }
+ movieList = fillUriList(MediaStore.Video.Media.BUCKET_ID + "=? ",
+ new String[]{String.valueOf(bucketId)}, curId, params[0]);
+ }
+ }
+ }
+ if (LOG) {
+ Log.v(TAG, "doInBackground() done return " + movieList);
+ }
+ return movieList;
+ }
+
+ private IMovieList fillUriList(String where, String[] whereArgs, long curId, IMovieItem current) {
+ IMovieList movieList = null;
+ Cursor cursor = null;
+ try {
+ cursor = mCr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
+ new String[]{"_id", "mime_type", OpenableColumns.DISPLAY_NAME},
+ where,
+ whereArgs,
+ mOrderBy);
+ boolean find = false;
+ if (cursor != null && cursor.getCount() > 0) {
+ movieList = new MovieList();
+ while (cursor.moveToNext()) {
+ long id = cursor.getLong(0);
+ if (!find && id == curId) {
+ find = true;
+ movieList.add(current);
+ continue;
+ }
+ Uri uri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id);
+ String mimeType = cursor.getString(1);
+ String title = cursor.getString(2);
+
+ movieList.add(new MovieItem(uri, mimeType, title));
+ }
+ }
+ } catch (final SQLiteException e) {
+ e.printStackTrace();
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ if (LOG) {
+ Log.v(TAG, "fillUriList() cursor=" + cursor + ", return " + movieList);
+ }
+ return movieList;
+ }
+
+ private long getCursorId(Uri uri) {
+ long curId = -1;
+ Cursor cursor = null;
+ String data = Uri.decode(uri.toString());
+ data = data.replaceAll("'", "''");
+ String where = "_data LIKE '%" + data.replaceFirst("file:///", "") + "'";
+ try {
+ cursor = mCr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
+ new String[] {
+ "_id"
+ }, where, null, null);
+
+ if (cursor != null && cursor.moveToFirst()) {
+ curId = cursor.getLong(0);
+ }
+ } catch (final SQLiteException e) {
+ e.printStackTrace();
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return curId;
+ }
+ }
+}
diff --git a/src/org/codeaurora/gallery3d/ext/MovieUtils.java b/src/org/codeaurora/gallery3d/ext/MovieUtils.java
new file mode 100644
index 000000000..4bc70a39f
--- /dev/null
+++ b/src/org/codeaurora/gallery3d/ext/MovieUtils.java
@@ -0,0 +1,98 @@
+package org.codeaurora.gallery3d.ext;
+
+import android.net.Uri;
+import android.util.Log;
+
+import java.util.Locale;
+
+/**
+ * Util class for Movie functions. *
+ */
+public class MovieUtils {
+ private static final String TAG = "MovieUtils";
+ private static final boolean LOG = false;
+
+ private MovieUtils() {
+ }
+
+ /**
+ * Whether current video(Uri) is RTSP streaming or not.
+ *
+ * @param uri
+ * @param mimeType
+ * @return
+ */
+ public static boolean isRtspStreaming(Uri uri, String mimeType) {
+ boolean rtsp = false;
+ if (uri != null) {
+ if ("rtsp".equalsIgnoreCase(uri.getScheme())) {
+ rtsp = true;
+ }
+ }
+ if (LOG) {
+ Log.v(TAG, "isRtspStreaming(" + uri + ", " + mimeType + ") return " + rtsp);
+ }
+ return rtsp;
+ }
+
+ /**
+ * Whether current video(Uri) is HTTP streaming or not.
+ *
+ * @param uri
+ * @param mimeType
+ * @return
+ */
+ public static boolean isHttpStreaming(Uri uri, String mimeType) {
+ boolean http = false;
+ if (uri != null) {
+ if ("http".equalsIgnoreCase(uri.getScheme())) {
+ http = true;
+ } else if ("https".equalsIgnoreCase(uri.getScheme())) {
+ http = true;
+ }
+ }
+ if (LOG) {
+ Log.v(TAG, "isHttpStreaming(" + uri + ", " + mimeType + ") return " + http);
+ }
+ return http;
+ }
+
+ /**
+ * Whether current video(Uri) is live streaming or not.
+ *
+ * @param uri
+ * @param mimeType
+ * @return
+ */
+ public static boolean isSdpStreaming(Uri uri, String mimeType) {
+ boolean sdp = false;
+ if (uri != null) {
+ if ("application/sdp".equals(mimeType)) {
+ sdp = true;
+ } else if (uri.toString().toLowerCase(Locale.ENGLISH).endsWith(".sdp")) {
+ sdp = true;
+ }
+ }
+ if (LOG) {
+ Log.v(TAG, "isSdpStreaming(" + uri + ", " + mimeType + ") return " + sdp);
+ }
+ return sdp;
+ }
+
+ /**
+ * Whether current video(Uri) is local file or not.
+ *
+ * @param uri
+ * @param mimeType
+ * @return
+ */
+ public static boolean isLocalFile(Uri uri, String mimeType) {
+ boolean local = (!isSdpStreaming(uri, mimeType)
+ && !isRtspStreaming(uri, mimeType)
+ && !isHttpStreaming(uri, mimeType));
+ if (LOG) {
+ Log.v(TAG, "isLocalFile(" + uri + ", " + mimeType + ") return " + local);
+ }
+ return local;
+ }
+}