diff options
Diffstat (limited to 'src/org/codeaurora/gallery3d/ext')
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/ActivityHooker.java | 96 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/ActivityHookerGroup.java | 150 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/IActivityHooker.java | 128 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/IContrllerOverlayExt.java | 51 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/IMovieItem.java | 66 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/IMovieList.java | 46 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/IMovieListLoader.java | 51 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/IMoviePlayer.java | 42 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/MovieItem.java | 115 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/MovieList.java | 72 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/MovieListLoader.java | 274 | ||||
-rw-r--r-- | src/org/codeaurora/gallery3d/ext/MovieUtils.java | 98 |
12 files changed, 1189 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..237d7e138 --- /dev/null +++ b/src/org/codeaurora/gallery3d/ext/MovieListLoader.java @@ -0,0 +1,274 @@ +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(); + } + try { + long curId = Long.parseLong(uri.getPathSegments().get(3)); + movieList = fillUriList(MediaStore.Video.Media.BUCKET_ID + "=? ", + new String[]{String.valueOf(bucketId)}, curId, params[0]); + } catch (Exception e) { + Log.e(TAG, "Exception while creating movie list. " + e); + return null; + } + } 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; + } +} |