summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLikai Ding <likaid@codeaurora.org>2013-08-15 15:02:24 +0800
committeremancebo <emancebo@cyngn.com>2014-09-04 10:40:18 -0700
commit93a66b850bdb0a06ad7fda0549eb47b8123292bc (patch)
treee7a0d0ce434eff6e9757f728fc80d413fe34dce2 /src
parentbce738c2b78bd4ec6dbdfc8f808059f882e59595 (diff)
downloadandroid_packages_apps_Gallery2-93a66b850bdb0a06ad7fda0549eb47b8123292bc.tar.gz
android_packages_apps_Gallery2-93a66b850bdb0a06ad7fda0549eb47b8123292bc.tar.bz2
android_packages_apps_Gallery2-93a66b850bdb0a06ad7fda0549eb47b8123292bc.zip
Gallery2: support live streaming and bookmarks
(cherry picked new files from commit id 990c6d43ea7c184846e19d41bef0d93aee4e581b) Change-Id: Idc254cf0f7e8a9b492203313fa63349d07d19d5c
Diffstat (limited to 'src')
-rwxr-xr-xsrc/com/qcom/gallery3d/video/BookmarkActivity.java242
-rwxr-xr-xsrc/com/qcom/gallery3d/video/BookmarkEnhance.java132
-rwxr-xr-xsrc/com/qcom/gallery3d/video/BookmarkHooker.java72
-rwxr-xr-xsrc/com/qcom/gallery3d/video/DmReceiver.java82
-rwxr-xr-xsrc/com/qcom/gallery3d/video/MovieTitleHelper.java98
-rwxr-xr-xsrc/com/qcom/gallery3d/video/QcomVideoView.java721
-rwxr-xr-xsrc/com/qcom/gallery3d/video/SettingsActivity.java371
-rwxr-xr-xsrc/com/qcom/gallery3d/video/StreamingHooker.java89
8 files changed, 1807 insertions, 0 deletions
diff --git a/src/com/qcom/gallery3d/video/BookmarkActivity.java b/src/com/qcom/gallery3d/video/BookmarkActivity.java
new file mode 100755
index 000000000..8e792815c
--- /dev/null
+++ b/src/com/qcom/gallery3d/video/BookmarkActivity.java
@@ -0,0 +1,242 @@
+package com.qcom.gallery3d.video;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.app.MovieActivity;
+import com.qcom.gallery3d.ext.QcomLog;
+
+public class BookmarkActivity extends Activity implements OnItemClickListener {
+ private static final String TAG = "BookmarkActivity";
+ private static final boolean LOG = true;
+
+ private BookmarkEnhance mBookmark;
+ private BookmarkAdapter mAdapter;
+ private Cursor mCursor;
+ private ListView mListView;
+ private TextView mEmptyView;
+
+ private static final int MENU_DELETE_ALL = 1;
+ private static final int MENU_DELETE_ONE = 2;
+ private static final int MENU_EDIT = 3;
+
+ public static final String KEY_LOGO_BITMAP = "logo-bitmap";
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.bookmark);
+
+ Bitmap logo = getIntent().getParcelableExtra(KEY_LOGO_BITMAP);
+ if (logo != null) {
+ getActionBar().setLogo(new BitmapDrawable(getResources(), logo));
+ }
+
+ mListView = (ListView) findViewById(android.R.id.list);
+ mEmptyView = (TextView) findViewById(android.R.id.empty);
+
+ mBookmark = new BookmarkEnhance(this);
+ mCursor = mBookmark.query();
+ mAdapter = new BookmarkAdapter(this, R.layout.bookmark_item, null, new String[]{}, new int[]{});
+ mListView.setEmptyView(mEmptyView);
+ mListView.setAdapter(mAdapter);
+ mAdapter.changeCursor(mCursor);
+
+ mListView.setOnItemClickListener(this);
+ registerForContextMenu(mListView);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (mAdapter != null) {
+ mAdapter.changeCursor(null);
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(final Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ menu.add(0, MENU_DELETE_ALL, 0, R.string.delete_all)
+ .setIcon(android.R.drawable.ic_menu_delete);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(final MenuItem item) {
+ switch(item.getItemId()) {
+ case MENU_DELETE_ALL:
+ mBookmark.deleteAll();
+ return true;
+ default:
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private class BookmarkAdapter extends SimpleCursorAdapter {
+
+ public BookmarkAdapter(final Context context, final int layout, final Cursor c,
+ final String[] from, final int[] to) {
+ super(context, layout, c, from, to);
+ }
+
+ @Override
+ public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {
+ final View view = super.newView(context, cursor, parent);
+ final ViewHolder holder = new ViewHolder();
+ holder.mTitleView = (TextView) view.findViewById(R.id.title);
+ holder.mDataView = (TextView) view.findViewById(R.id.data);
+ view.setTag(holder);
+ return view;
+ }
+
+ @Override
+ public void bindView(final View view, final Context context, final Cursor cursor) {
+ final ViewHolder holder = (ViewHolder) view.getTag();
+ holder.mId = cursor.getLong(BookmarkEnhance.INDEX_ID);
+ holder.mTitle = cursor.getString(BookmarkEnhance.INDEX_TITLE);
+ holder.mData = cursor.getString(BookmarkEnhance.INDEX_DATA);
+ holder.mMimetype = cursor.getString(BookmarkEnhance.INDEX_MIME_TYPE);
+ holder.mTitleView.setText(holder.mTitle);
+ holder.mDataView.setText(holder.mData);
+ }
+
+ @Override
+ public void changeCursor(final Cursor c) {
+ super.changeCursor(c);
+ }
+
+ }
+
+ private class ViewHolder {
+ long mId;
+ String mTitle;
+ String mData;
+ String mMimetype;
+ TextView mTitleView;
+ TextView mDataView;
+ }
+
+ @Override
+ public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
+ final Object o = view.getTag();
+ if (o instanceof ViewHolder) {
+ final ViewHolder holder = (ViewHolder) o;
+ finish();
+ final Intent intent = new Intent(this, MovieActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ String mime = "video/*";
+ if (!(holder.mMimetype == null || "".equals(holder.mMimetype.trim()))) {
+ mime = holder.mMimetype;
+ }
+ intent.setDataAndType(Uri.parse(holder.mData), mime);
+ startActivity(intent);
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "onItemClick(" + position + ", " + id + ")");
+ }
+ }
+
+ @Override
+ public void onCreateContextMenu(final ContextMenu menu, final View v,
+ final ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ menu.add(0, MENU_DELETE_ONE, 0, R.string.delete);
+ menu.add(0, MENU_EDIT, 0, R.string.edit);
+ }
+
+ @Override
+ public boolean onContextItemSelected(final MenuItem item) {
+ final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+ switch (item.getItemId()) {
+ case MENU_DELETE_ONE:
+ mBookmark.delete(info.id);
+ return true;
+ case MENU_EDIT:
+ final Object obj = info.targetView.getTag();
+ if (obj instanceof ViewHolder) {
+ showEditDialog((ViewHolder)obj);
+ } else {
+ QcomLog.w(TAG, "wrong context item info " + info);
+ }
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ private void showEditDialog(final ViewHolder holder) {
+ if (LOG) {
+ QcomLog.v(TAG, "showEditDialog(" + holder + ")");
+ }
+ if (holder == null) {
+ return;
+ }
+ final LayoutInflater inflater = LayoutInflater.from(this);
+ final View v = inflater.inflate(R.layout.bookmark_edit_dialog, null);
+ final EditText titleView = (EditText)v.findViewById(R.id.title);
+ final EditText dataView = (EditText)v.findViewById(R.id.data);
+ titleView.setText(holder.mTitle);
+ dataView.setText(holder.mData);
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.edit);
+ builder.setView(v);
+ builder.setIcon(R.drawable.ic_menu_display_bookmark);
+ builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
+
+ @Override
+ public void onClick(final DialogInterface dialog, final int which) {
+ mBookmark.update(holder.mId, titleView.getText().toString(),
+ dataView.getText().toString(), 0);
+ }
+
+ });
+ builder.setNegativeButton(android.R.string.cancel, null);
+ final AlertDialog dialog = builder.create();
+ dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ dialog.setInverseBackgroundForced(true);
+ dialog.show();
+ }
+}
diff --git a/src/com/qcom/gallery3d/video/BookmarkEnhance.java b/src/com/qcom/gallery3d/video/BookmarkEnhance.java
new file mode 100755
index 000000000..033b055b5
--- /dev/null
+++ b/src/com/qcom/gallery3d/video/BookmarkEnhance.java
@@ -0,0 +1,132 @@
+package com.qcom.gallery3d.video;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+
+import com.android.gallery3d.R;
+import com.qcom.gallery3d.ext.QcomLog;
+
+public class BookmarkEnhance {
+ private static final String TAG = "BookmarkEnhance";
+ private static final boolean LOG = true;
+
+ private static final Uri BOOKMARK_URI = Uri.parse("content://media/internal/bookmark");
+
+ public static final String COLUMN_ID = "_id";
+ public static final String COLUMN_DATA = "_data";
+ public static final String COLUMN_TITLE = "_display_name";
+ public static final String COLUMN_ADD_DATE = "date_added";
+ public static final String COLUMN_MEDIA_TYPE = "mime_type";
+ private static final String COLUMN_POSITION = "position";
+ private static final String COLUMN_MIME_TYPE = "media_type";
+
+ private static final String NULL_HOCK = COLUMN_POSITION;
+ public static final String ORDER_COLUMN = COLUMN_ADD_DATE + " ASC ";
+ private static final String VIDEO_STREAMING_MEDIA_TYPE = "streaming";
+
+ public static final int INDEX_ID = 0;
+ public static final int INDEX_DATA = 1;
+ public static final int INDEX_TITLE = 2;
+ public static final int INDEX_ADD_DATE = 3;
+ public static final int INDEX_MIME_TYPE = 4;
+ private static final int INDEX_POSITION = 5;
+ private static final int INDEX_MEDIA_TYPE = 6;
+
+ public static final String[] PROJECTION = new String[]{
+ COLUMN_ID,
+ COLUMN_DATA,
+ COLUMN_TITLE,
+ COLUMN_ADD_DATE,
+ COLUMN_MIME_TYPE,
+ };
+
+ private final Context mContext;
+ private final ContentResolver mCr;
+
+ public BookmarkEnhance(final Context context) {
+ mContext = context;
+ mCr = context.getContentResolver();
+ }
+
+ public Uri insert(final String title, final String uri, final String mimeType,final long position) {
+ final ContentValues values = new ContentValues();
+ final String mytitle = (title == null ? mContext.getString(R.string.default_title) : title);
+ values.put(COLUMN_TITLE, mytitle);
+ values.put(COLUMN_DATA, uri);
+ values.put(COLUMN_POSITION, position);
+ values.put(COLUMN_ADD_DATE, System.currentTimeMillis());
+ values.put(COLUMN_MEDIA_TYPE, VIDEO_STREAMING_MEDIA_TYPE);
+ values.put(COLUMN_MIME_TYPE, mimeType);
+ final Uri insertUri = mCr.insert(BOOKMARK_URI, values);
+ if (LOG) {
+ QcomLog.v(TAG, "insert(" + title + "," + uri + ", " + position + ") return " + insertUri);
+ }
+ return insertUri;
+ }
+
+ public int delete(final long id) {
+ final Uri uri = ContentUris.withAppendedId(BOOKMARK_URI, id);
+ final int count = mCr.delete(uri, null, null);
+ if (LOG) {
+ QcomLog.v(TAG, "delete(" + id + ") return " + count);
+ }
+ return count;
+ }
+
+ public int deleteAll() {
+ final int count = mCr.delete(BOOKMARK_URI, COLUMN_MEDIA_TYPE + "=? ", new String[]{VIDEO_STREAMING_MEDIA_TYPE});
+ if (LOG) {
+ QcomLog.v(TAG, "deleteAll() return " + count);
+ }
+ return count;
+ }
+
+ public boolean exists(final String uri) {
+ final Cursor cursor = mCr.query(BOOKMARK_URI,
+ PROJECTION,
+ COLUMN_DATA + "=? and " + COLUMN_MEDIA_TYPE + "=? ",
+ new String[]{uri, VIDEO_STREAMING_MEDIA_TYPE},
+ null
+ );
+ boolean exist = false;
+ if (cursor != null) {
+ exist = cursor.moveToFirst();
+ cursor.close();
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "exists(" + uri + ") return " + exist);
+ }
+ return exist;
+ }
+
+ public Cursor query() {
+ final Cursor cursor = mCr.query(BOOKMARK_URI,
+ PROJECTION,
+ COLUMN_MEDIA_TYPE + "='" + VIDEO_STREAMING_MEDIA_TYPE + "' ",
+ null,
+ ORDER_COLUMN
+ );
+ if (LOG) {
+ QcomLog.v(TAG, "query() return cursor=" + (cursor == null ? -1 : cursor.getCount()));
+ }
+ return cursor;
+ }
+
+ public int update(final long id, final String title, final String uri, final int position) {
+ final ContentValues values = new ContentValues();
+ values.put(COLUMN_TITLE, title);
+ values.put(COLUMN_DATA, uri);
+ values.put(COLUMN_POSITION, position);
+ final Uri updateUri = ContentUris.withAppendedId(BOOKMARK_URI, id);
+ final int count = mCr.update(updateUri, values, null, null);
+ if (LOG) {
+ QcomLog.v(TAG, "update(" + id + ", " + title + ", " + uri + ", " + position + ")" +
+ " return " + count);
+ }
+ return count;
+ }
+}
diff --git a/src/com/qcom/gallery3d/video/BookmarkHooker.java b/src/com/qcom/gallery3d/video/BookmarkHooker.java
new file mode 100755
index 000000000..fc8bcd885
--- /dev/null
+++ b/src/com/qcom/gallery3d/video/BookmarkHooker.java
@@ -0,0 +1,72 @@
+package com.qcom.gallery3d.video;
+
+import android.content.Intent;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.gallery3d.R;
+import com.qcom.gallery3d.ext.MovieUtils;
+
+public class BookmarkHooker extends MovieHooker {
+ private static final String TAG = "BookmarkHooker";
+ private static final boolean LOG = true;
+
+ private static final String ACTION_BOOKMARK = "com.qcom.bookmark.VIEW";
+ private static final int MENU_BOOKMARK_ADD = 1;
+ private static final int MENU_BOOKMARK_DISPLAY = 2;
+ private MenuItem mMenuBookmarks;
+ private MenuItem mMenuBookmarkAdd;
+
+ public static final String KEY_LOGO_BITMAP = "logo-bitmap";
+
+ @Override
+ public boolean onCreateOptionsMenu(final Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ mMenuBookmarkAdd = menu.add(0, getMenuActivityId(MENU_BOOKMARK_ADD), 0, R.string.bookmark_add);
+ mMenuBookmarks = menu.add(0, getMenuActivityId(MENU_BOOKMARK_DISPLAY), 0, R.string.bookmark_display);
+ return true;
+ }
+ @Override
+ public boolean onPrepareOptionsMenu(final Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ if (MovieUtils.isLocalFile(getMovieItem().getUri(), getMovieItem().getMimeType())) {
+ if (mMenuBookmarkAdd != null) {
+ mMenuBookmarkAdd.setVisible(false);
+ }
+ if (mMenuBookmarks != null) {
+ mMenuBookmarks.setVisible(false);
+ }
+ } else {
+ if (mMenuBookmarkAdd != null) {
+ mMenuBookmarkAdd.setVisible(true);
+ }
+ if (mMenuBookmarks != null) {
+ mMenuBookmarks.setVisible(true);
+ }
+ }
+ return true;
+ }
+ @Override
+ public boolean onOptionsItemSelected(final MenuItem item) {
+ super.onOptionsItemSelected(item);
+ switch(getMenuOriginalId(item.getItemId())) {
+ case MENU_BOOKMARK_ADD:
+ getPlayer().addBookmark();
+ return true;
+ case MENU_BOOKMARK_DISPLAY:
+ gotoBookmark();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private void gotoBookmark() {
+ final Intent intent = new Intent(ACTION_BOOKMARK);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+ | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
+ intent.putExtra(KEY_LOGO_BITMAP, getIntent().getParcelableExtra(KEY_LOGO_BITMAP));
+ getContext().startActivity(intent);
+ }
+} \ No newline at end of file
diff --git a/src/com/qcom/gallery3d/video/DmReceiver.java b/src/com/qcom/gallery3d/video/DmReceiver.java
new file mode 100755
index 000000000..4b4b6aa20
--- /dev/null
+++ b/src/com/qcom/gallery3d/video/DmReceiver.java
@@ -0,0 +1,82 @@
+
+
+
+package com.qcom.gallery3d.video;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.PowerManager;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+public class DmReceiver extends BroadcastReceiver {
+ private static final String TAG = "DmReceiver";
+ public static final String WRITE_SETTING_ACTION = "streaming.action.WRITE_SETTINGS";
+ public static final String BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
+
+ private SharedPreferences mPref;
+ static final int STREAMING_CONNPROFILE_IO_HANDLER_TYPE = 1;
+ static final int STREAMING_MAX_UDP_PORT_IO_HANDLER_TYPE = 3;
+ static final int STREAMING_MIN_UDP_PORT_IO_HANDLER_TYPE = 4;
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "z32 ### onReceive ###");
+ if (mPref == null) {
+ mPref = PreferenceManager.getDefaultSharedPreferences(context);
+ }
+ if (BOOT_COMPLETED.equals(intent.getAction()) )
+ {
+ Log.d(TAG, "z46 onReceive BOOT_COMPLETED ###");
+ String rtpMaxport
+ = mPref.getString(SettingsActivity.PREFERENCE_RTP_MAXPORT, "65535");
+ String rtpMinport
+ = mPref.getString(SettingsActivity.PREFERENCE_RTP_MINPORT, "8192");
+ String apn
+ = mPref.getString(SettingsActivity.PREFERENCE_APN, "CMWAP");
+ Log.d(TAG, "z43 rtpMinport = " + rtpMinport + ";rtpMaxport = " + rtpMaxport);
+
+ android.provider.Settings.System.putString(context.getContentResolver(), "streaming_max_udp_port", rtpMaxport);
+ android.provider.Settings.System.putString(context.getContentResolver(), "streaming_min_udp_port", rtpMinport);
+ android.provider.Settings.System.putString(context.getContentResolver(), "apn", apn);
+ }
+ else if (WRITE_SETTING_ACTION.equals(intent.getAction()))
+ {
+ Log.d(TAG, "z52 onReceive WRITE_SETTING_ACTION ###");
+ int valueType = intent.getIntExtra("type", 0);
+ String value = intent.getStringExtra("value");
+ if (valueType == STREAMING_MAX_UDP_PORT_IO_HANDLER_TYPE)
+ {
+ mPref.edit().putString(SettingsActivity.PREFERENCE_RTP_MAXPORT,
+ value).commit();
+ android.provider.Settings.System.putString(context.getContentResolver(),
+ "streaming_max_udp_port", value);
+ }
+ else if (valueType == STREAMING_MIN_UDP_PORT_IO_HANDLER_TYPE)
+ {
+ mPref.edit().putString(SettingsActivity.PREFERENCE_RTP_MINPORT,
+ value).commit();
+ android.provider.Settings.System.putString(context.getContentResolver(),
+ "streaming_min_udp_port", value);
+ }
+ else if (valueType == STREAMING_CONNPROFILE_IO_HANDLER_TYPE)
+ {
+ mPref.edit().putString(SettingsActivity.PREFERENCE_APN,
+ // "CMWAP").commit();
+ value).commit();
+ android.provider.Settings.System.putString(context.getContentResolver(),
+ "apn", value);
+ }
+ }
+ }
+}
+
diff --git a/src/com/qcom/gallery3d/video/MovieTitleHelper.java b/src/com/qcom/gallery3d/video/MovieTitleHelper.java
new file mode 100755
index 000000000..42ba3ec90
--- /dev/null
+++ b/src/com/qcom/gallery3d/video/MovieTitleHelper.java
@@ -0,0 +1,98 @@
+package com.qcom.gallery3d.video;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.provider.OpenableColumns;
+
+import com.qcom.gallery3d.ext.QcomLog;
+
+import java.io.File;
+
+public class MovieTitleHelper {
+ private static final String TAG = "MovieTitleHelper";
+ private static final boolean LOG = true;
+
+ public static String getTitleFromMediaData(final Context context, final Uri uri) {
+ String title = null;
+ Cursor cursor = null;
+ try {
+ String data = Uri.decode(uri.toString());
+ data = data.replaceAll("'", "''");
+ final String where = "_data LIKE '%" + data.replaceFirst("file:///", "") + "'";
+ cursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
+ new String[]{OpenableColumns.DISPLAY_NAME}, where, null, null);
+ if (LOG) {
+ QcomLog.v(TAG, "setInfoFromMediaData() cursor=" + (cursor == null ? "null" : cursor.getCount()));
+ }
+ if (cursor != null && cursor.moveToFirst()) {
+ title = cursor.getString(0);
+ }
+ } catch (final SQLiteException ex) {
+ ex.printStackTrace();
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "setInfoFromMediaData() return " + title);
+ }
+ return title;
+ }
+
+ public static String getTitleFromDisplayName(final Context context, final Uri uri) {
+ String title = null;
+ Cursor cursor = null;
+ try {
+ cursor = context.getContentResolver().query(uri,
+ new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ title = cursor.getString(0);
+ }
+ } catch (final SQLiteException ex) {
+ ex.printStackTrace();
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "getTitleFromDisplayName() return " + title);
+ }
+ return title;
+ }
+
+ public static String getTitleFromUri(final Uri uri) {
+ final String title = Uri.decode(uri.getLastPathSegment());
+ if (LOG) {
+ QcomLog.v(TAG, "getTitleFromUri() return " + title);
+ }
+ return title;
+ }
+
+ public static String getTitleFromData(final Context context, final Uri uri) {
+ String title = null;
+ Cursor cursor = null;
+ try {
+ cursor = context.getContentResolver().query(uri,
+ new String[]{"_data"}, null, null, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ final File file = new File(cursor.getString(0));
+ title = file.getName();
+ }
+ } catch (final SQLiteException ex) {
+ ex.printStackTrace();
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "getTitleFromData() return " + title);
+ }
+ return title;
+ }
+}
diff --git a/src/com/qcom/gallery3d/video/QcomVideoView.java b/src/com/qcom/gallery3d/video/QcomVideoView.java
new file mode 100755
index 000000000..ba5485544
--- /dev/null
+++ b/src/com/qcom/gallery3d/video/QcomVideoView.java
@@ -0,0 +1,721 @@
+package com.qcom.gallery3d.video;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.sqlite.SQLiteException;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnBufferingUpdateListener;
+import android.media.MediaPlayer.OnInfoListener;
+import android.media.MediaPlayer.OnVideoSizeChangedListener;
+import android.media.Metadata;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.SurfaceHolder;
+import android.widget.VideoView;
+
+import com.android.gallery3d.ui.Log;
+import com.qcom.gallery3d.ext.QcomLog;
+import com.qcom.gallery3d.video.ScreenModeManager.ScreenModeListener;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * QcomVideoView enhance the streaming videoplayer process and UI.
+ * It only supports QcomMediaController.
+ * If you set android's default MediaController,
+ * some state will not be shown well.
+ * Moved from the package android.widget
+ */
+public class QcomVideoView extends VideoView implements ScreenModeListener {
+ private static final String TAG = "QcomVideoView";
+ private static final boolean LOG = true;
+
+ //add info listener to get info whether can get meta data or not for rtsp.
+ private MediaPlayer.OnInfoListener mOnInfoListener;
+ private MediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener;
+ private MediaPlayer.OnVideoSizeChangedListener mVideoSizeListener;
+
+ //when the streaming type is live, metadata maybe not right when prepared.
+ private boolean mHasGotMetaData = false;
+ private boolean mHasGotPreparedCallBack = false;
+
+ private final MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
+
+ public boolean onInfo(final MediaPlayer mp, final int what, final int extra) {
+ if (LOG) {
+ QcomLog.v(TAG, "onInfo() what:" + what + " extra:" + extra);
+ }
+ if (mOnInfoListener != null && mOnInfoListener.onInfo(mp, what, extra)) {
+ return true;
+ } else {
+ // TODO comments by sunlei
+// if (what == MediaPlayer.MEDIA_INFO_METADATA_CHECK_COMPLETE) {
+// mHasGotMetaData = true;
+// doPreparedIfReady(mMediaPlayer);
+// return true;
+// }
+ }
+ return false;
+ }
+
+ };
+
+ private void doPreparedIfReady(final MediaPlayer mp) {
+ if (LOG) {
+ QcomLog.v(TAG, "doPreparedIfReady() mHasGotPreparedCallBack=" + mHasGotPreparedCallBack
+ + ", mHasGotMetaData=" + mHasGotMetaData + ", mNeedWaitLayout=" + mNeedWaitLayout
+ + ", mCurrentState=" + mCurrentState);
+ }
+ if (mHasGotPreparedCallBack && mHasGotMetaData && !mNeedWaitLayout) {
+ doPrepared(mp);
+ }
+ }
+
+ public QcomVideoView(final Context context) {
+ super(context);
+ initialize();
+ }
+
+ public QcomVideoView(final Context context, final AttributeSet attrs) {
+ super(context, attrs);
+ initialize();
+ }
+
+ public QcomVideoView(final Context context, final AttributeSet attrs, final int defStyle) {
+ super(context, attrs, defStyle);
+ initialize();
+ }
+
+ private void initialize() {
+ mPreparedListener = new MediaPlayer.OnPreparedListener() {
+ public void onPrepared(final MediaPlayer mp) {
+ if (LOG) {
+ QcomLog.v(TAG, "mPreparedListener.onPrepared(" + mp + ")");
+ }
+ //Here we can get meta data from mediaplayer.
+ // Get the capabilities of the player for this stream
+ final Metadata data = mp.getMetadata(MediaPlayer.METADATA_ALL,
+ MediaPlayer.BYPASS_METADATA_FILTER);
+ if (data != null) {
+ mCanPause = !data.has(Metadata.PAUSE_AVAILABLE)
+ || data.getBoolean(Metadata.PAUSE_AVAILABLE);
+ mCanSeekBack = !data.has(Metadata.SEEK_BACKWARD_AVAILABLE)
+ || data.getBoolean(Metadata.SEEK_BACKWARD_AVAILABLE);
+ mCanSeekForward = !data.has(Metadata.SEEK_FORWARD_AVAILABLE)
+ || data.getBoolean(Metadata.SEEK_FORWARD_AVAILABLE);
+ } else {
+ mCanPause = true;
+ mCanSeekBack = true;
+ mCanSeekForward = true;
+ QcomLog.w(TAG, "Metadata is null!");
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "mPreparedListener.onPrepared() mCanPause=" + mCanPause);
+ }
+ mHasGotPreparedCallBack = true;
+ doPreparedIfReady(mMediaPlayer);
+ }
+ };
+
+ mErrorListener = new MediaPlayer.OnErrorListener() {
+ public boolean onError(final MediaPlayer mp, final int frameworkErr, final int implErr) {
+ Log.d(TAG, "Error: " + frameworkErr + "," + implErr);
+ if (mCurrentState == STATE_ERROR) {
+ Log.w(TAG, "Duplicate error message. error message has been sent! " +
+ "error=(" + frameworkErr + "," + implErr + ")");
+ return true;
+ }
+ //record error position and duration
+ //here disturb the original logic
+ mSeekWhenPrepared = getCurrentPosition();
+ if (LOG) {
+ Log.v(TAG, "onError() mSeekWhenPrepared=" + mSeekWhenPrepared + ", mDuration=" + mDuration);
+ }
+ //for old version Streaming server, getduration is not valid.
+ mDuration = Math.abs(mDuration);
+ mCurrentState = STATE_ERROR;
+ mTargetState = STATE_ERROR;
+ if (mMediaController != null) {
+ mMediaController.hide();
+ }
+
+ /* If an error handler has been supplied, use it and finish. */
+ if (mOnErrorListener != null) {
+ if (mOnErrorListener.onError(mMediaPlayer, frameworkErr, implErr)) {
+ return true;
+ }
+ }
+
+ /* Otherwise, pop up an error dialog so the user knows that
+ * something bad has happened. Only try and pop up the dialog
+ * if we're attached to a window. When we're going away and no
+ * longer have a window, don't bother showing the user an error.
+ */
+ if (getWindowToken() != null) {
+ final Resources r = mContext.getResources();
+ int messageId;
+
+ // TODO comments by sunlei
+// if (frameworkErr == MediaPlayer.MEDIA_ERROR_BAD_FILE) {
+// messageId = com.mediatek.R.string.VideoView_error_text_bad_file;
+// } else if (frameworkErr == MediaPlayer.MEDIA_ERROR_CANNOT_CONNECT_TO_SERVER) {
+// messageId = com.mediatek.R.string.VideoView_error_text_cannot_connect_to_server;
+// } else if (frameworkErr == MediaPlayer.MEDIA_ERROR_TYPE_NOT_SUPPORTED) {
+// messageId = com.mediatek.R.string.VideoView_error_text_type_not_supported;
+// } else if (frameworkErr == MediaPlayer.MEDIA_ERROR_DRM_NOT_SUPPORTED) {
+// messageId = com.mediatek.R.string.VideoView_error_text_drm_not_supported;
+// } else if (frameworkErr == MediaPlayer.MEDIA_ERROR_INVALID_CONNECTION) {
+// messageId = com.mediatek.internal.R.string.VideoView_error_text_invalid_connection;
+// } else if (frameworkErr == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
+// messageId = com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;
+// } else {
+// messageId = com.android.internal.R.string.VideoView_error_text_unknown;
+// }
+
+ if (frameworkErr == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
+ messageId = com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;
+ } else {
+ messageId = com.android.internal.R.string.VideoView_error_text_unknown;
+ }
+
+ final String errorDialogTag = "ERROR_DIALOG_TAG";
+ FragmentManager fragmentManager = ((Activity)mContext).getFragmentManager();
+ DialogFragment oldFragment = (DialogFragment) fragmentManager
+ .findFragmentByTag(errorDialogTag);
+ if (null != oldFragment) {
+ oldFragment.dismissAllowingStateLoss();
+ }
+ DialogFragment newFragment = ErrorDialogFragment.newInstance(messageId);
+ newFragment.show(fragmentManager, errorDialogTag);
+ fragmentManager.executePendingTransactions();
+ }
+ return true;
+ }
+ };
+
+ mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {
+ public void onBufferingUpdate(final MediaPlayer mp, final int percent) {
+ mCurrentBufferPercentage = percent;
+ if (mOnBufferingUpdateListener != null) {
+ mOnBufferingUpdateListener.onBufferingUpdate(mp, percent);
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "onBufferingUpdate() Buffering percent: " + percent);
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "onBufferingUpdate() mTargetState=" + mTargetState);
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "onBufferingUpdate() mCurrentState=" + mCurrentState);
+ }
+ }
+ };
+
+ mSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() {
+ public void onVideoSizeChanged(final MediaPlayer mp, final int width, final int height) {
+ mVideoWidth = mp.getVideoWidth();
+ mVideoHeight = mp.getVideoHeight();
+ if (LOG) {
+ QcomLog.v(TAG, "OnVideoSizeChagned(" + width + "," + height + ")");
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "OnVideoSizeChagned(" + mVideoWidth + "," + mVideoHeight + ")");
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "OnVideoSizeChagned() mCurrentState=" + mCurrentState);
+ }
+ if (mVideoWidth != 0 && mVideoHeight != 0) {
+ getHolder().setFixedSize(mVideoWidth, mVideoHeight);
+ if (mCurrentState == STATE_PREPARING) {
+ mNeedWaitLayout = true;
+ }
+ }
+ if (mVideoSizeListener != null) {
+ mVideoSizeListener.onVideoSizeChanged(mp, width, height);
+ }
+ QcomVideoView.this.requestLayout();
+ }
+ };
+
+ getHolder().removeCallback(mSHCallback);
+ mSHCallback = new SurfaceHolder.Callback() {
+ public void surfaceChanged(final SurfaceHolder holder, final int format, final int w, final int h) {
+ if (LOG) {
+ Log.v(TAG, "surfaceChanged(" + holder + ", " + format + ", " + w + ", " + h + ")");
+ }
+ if (LOG) {
+ Log.v(TAG, "surfaceChanged() mMediaPlayer=" + mMediaPlayer + ", mTargetState=" + mTargetState
+ + ", mVideoWidth=" + mVideoWidth + ", mVideoHeight=" + mVideoHeight);
+ }
+ mSurfaceWidth = w;
+ mSurfaceHeight = h;
+ final boolean isValidState = (mTargetState == STATE_PLAYING);
+ final boolean hasValidSize = (mVideoWidth == w && mVideoHeight == h);
+ if (mMediaPlayer != null && isValidState && hasValidSize) {
+ if (mSeekWhenPrepared != 0) {
+ seekTo(mSeekWhenPrepared);
+ }
+ Log.v(TAG, "surfaceChanged() start()");
+ start();
+ }
+ }
+
+ public void surfaceCreated(final SurfaceHolder holder) {
+ if (LOG) {
+ Log.v(TAG, "surfaceCreated(" + holder + ")");
+ }
+ mSurfaceHolder = holder;
+ openVideo();
+ }
+
+ public void surfaceDestroyed(final SurfaceHolder holder) {
+ // after we return from this we can't use the surface any more
+ if (LOG) {
+ Log.v(TAG, "surfaceDestroyed(" + holder + ")");
+ }
+ mSurfaceHolder = null;
+ if (mMediaController != null) {
+ mMediaController.hide();
+ }
+ release(true);
+ }
+ };
+ getHolder().addCallback(mSHCallback);
+ }
+
+ @Override
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
+ //Log.i("@@@@", "onMeasure");
+ int width = 0;
+ int height = 0;
+ int screenMode = ScreenModeManager.SCREENMODE_BIGSCREEN;
+ if (mScreenManager != null) {
+ screenMode = mScreenManager.getScreenMode();
+ }
+ switch (screenMode) {
+ case ScreenModeManager.SCREENMODE_BIGSCREEN:
+ width = getDefaultSize(mVideoWidth, widthMeasureSpec);
+ height = getDefaultSize(mVideoHeight, heightMeasureSpec);
+ if (mVideoWidth > 0 && mVideoHeight > 0) {
+ if (mVideoWidth * height > width * mVideoHeight) {
+ //Log.i("@@@", "image too tall, correcting");
+ height = width * mVideoHeight / mVideoWidth;
+ } else if (mVideoWidth * height < width * mVideoHeight) {
+ //Log.i("@@@", "image too wide, correcting");
+ width = height * mVideoWidth / mVideoHeight;
+ } /*else {
+ //Log.i("@@@", "aspect ratio is correct: " +
+ //width+"/"+height+"="+
+ //mVideoWidth+"/"+mVideoHeight);
+ }*/
+ }
+ break;
+ case ScreenModeManager.SCREENMODE_FULLSCREEN:
+ width = getDefaultSize(mVideoWidth, widthMeasureSpec);
+ height = getDefaultSize(mVideoHeight, heightMeasureSpec);
+ break;
+ case ScreenModeManager.SCREENMODE_CROPSCREEN:
+ width = getDefaultSize(mVideoWidth, widthMeasureSpec);
+ height = getDefaultSize(mVideoHeight, heightMeasureSpec);
+ if (mVideoWidth > 0 && mVideoHeight > 0) {
+ if (mVideoWidth * height > width * mVideoHeight) {
+ //extend width to be cropped
+ width = height * mVideoWidth / mVideoHeight;
+ } else if (mVideoWidth * height < width * mVideoHeight) {
+ //extend height to be cropped
+ height = width * mVideoHeight / mVideoWidth;
+ }
+ }
+ break;
+ default:
+ QcomLog.w(TAG, "wrong screen mode : " + screenMode);
+ break;
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "onMeasure() set size: " + width + 'x' + height);
+ QcomLog.v(TAG, "onMeasure() video size: " + mVideoWidth + 'x' + mVideoHeight);
+ QcomLog.v(TAG, "onMeasure() mNeedWaitLayout=" + mNeedWaitLayout);
+ }
+ setMeasuredDimension(width, height);
+ if (mNeedWaitLayout) { //when OnMeasure ok, start video.
+ mNeedWaitLayout = false;
+ mHandler.sendEmptyMessage(MSG_LAYOUT_READY);
+ }
+ }
+
+// @Override
+// public boolean onTouchEvent(MotionEvent ev) {
+// if (LOG) Log.v(TAG, "onTouchEvent(" + ev + ")");
+// if (mMediaController != null) {
+// toggleMediaControlsVisiblity();
+// }
+// return false;
+// }
+
+ @Override
+ public boolean onKeyDown(final int keyCode, final KeyEvent event) {
+ final boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK &&
+ keyCode != KeyEvent.KEYCODE_VOLUME_UP &&
+ keyCode != KeyEvent.KEYCODE_VOLUME_DOWN &&
+ keyCode != KeyEvent.KEYCODE_VOLUME_MUTE &&
+ keyCode != KeyEvent.KEYCODE_MENU &&
+ keyCode != KeyEvent.KEYCODE_CALL &&
+ keyCode != KeyEvent.KEYCODE_ENDCALL &&
+ keyCode != KeyEvent.KEYCODE_CAMERA;
+ if (isInPlaybackState() && isKeyCodeSupported && mMediaController != null) {
+ if (event.getRepeatCount() == 0 && (keyCode == KeyEvent.KEYCODE_HEADSETHOOK ||
+ keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE)) {
+ if (mMediaPlayer.isPlaying()) {
+ pause();
+ mMediaController.show();
+ } else {
+ start();
+ mMediaController.hide();
+ }
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {
+ if (!mMediaPlayer.isPlaying()) {
+ start();
+ mMediaController.hide();
+ }
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
+ || keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {
+ if (mMediaPlayer.isPlaying()) {
+ pause();
+ mMediaController.show();
+ }
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD ||
+ keyCode == KeyEvent.KEYCODE_MEDIA_NEXT ||
+ keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS ||
+ keyCode == KeyEvent.KEYCODE_MEDIA_REWIND ||
+ keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE ||
+ keyCode == KeyEvent.KEYCODE_HEADSETHOOK) {
+ //consume media action, so if video view if front,
+ //other media player will not play any sounds.
+ return true;
+ } else {
+ toggleMediaControlsVisiblity();
+ }
+ }
+
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public void setVideoURI(final Uri uri, final Map<String, String> headers) {
+ mDuration = -1;
+ setResumed(true);
+ super.setVideoURI(uri, headers);
+ }
+
+ public void setVideoURI(final Uri uri, final Map<String, String> headers, final boolean hasGotMetaData) {
+ if (LOG) {
+ QcomLog.v(TAG, "setVideoURI(" + uri + ", " + headers + ")");
+ }
+ //clear the flags
+ mHasGotMetaData = hasGotMetaData;
+ setVideoURI(uri, headers);
+ }
+
+ private void clearVideoInfo() {
+ if (LOG) {
+ Log.v(TAG, "clearVideoInfo()");
+ }
+ mHasGotPreparedCallBack = false;
+ mNeedWaitLayout = false;
+ }
+
+ @Override
+ protected void openVideo() {
+ if (LOG) {
+ Log.v(TAG, "openVideo() mUri=" + mUri + ", mSurfaceHolder=" + mSurfaceHolder
+ + ", mSeekWhenPrepared=" + mSeekWhenPrepared + ", mMediaPlayer=" + mMediaPlayer
+ + ", mOnResumed=" + mOnResumed);
+ }
+ clearVideoInfo();
+ if (!mOnResumed || mUri == null || mSurfaceHolder == null) {
+ // not ready for playback just yet, will try again later
+ return;
+ }
+
+ // Tell the music playback service to pause
+ // TODO: these constants need to be published somewhere in the framework.
+ final Intent i = new Intent("com.android.music.musicservicecommand");
+ i.putExtra("command", "pause");
+ mContext.sendBroadcast(i);
+
+ // we shouldn't clear the target state, because somebody might have
+ // called start() previously
+ release(false);
+ if ("".equalsIgnoreCase(String.valueOf(mUri))) {
+ Log.w(TAG, "Unable to open content: " + mUri);
+ mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
+ return;
+ }
+ try {
+ mMediaPlayer = new MediaPlayer();
+ //end update status.
+ mMediaPlayer.setOnPreparedListener(mPreparedListener);
+ mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
+ //mDuration = -1;
+ mMediaPlayer.setOnCompletionListener(mCompletionListener);
+ mMediaPlayer.setOnErrorListener(mErrorListener);
+ mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
+ mMediaPlayer.setOnInfoListener(mInfoListener);
+ mCurrentBufferPercentage = 0;
+ Log.w(TAG, "openVideo setDataSource()");
+ mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
+ mMediaPlayer.setDisplay(mSurfaceHolder);
+ mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ mMediaPlayer.setScreenOnWhilePlaying(true);
+ Log.w(TAG, "openVideo prepareAsync()");
+ mMediaPlayer.prepareAsync();
+ // we don't set the target state here either, but preserve the
+ // target state that was there before.
+ mCurrentState = STATE_PREPARING;
+ //attachMediaController();
+ } catch (final IOException ex) {
+ Log.w(TAG, "Unable to open content: " + mUri, ex);
+ mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
+ return;
+ } catch (final IllegalArgumentException ex) {
+ Log.w(TAG, "Unable to open content: " + mUri, ex);
+ mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
+ return;
+ } catch (final SQLiteException ex) {
+ Log.w(TAG, "Unable to open content: " + mUri, ex);
+ mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
+ return;
+ }
+ if (LOG) {
+ Log.v(TAG, "openVideo() mUri=" + mUri + ", mSurfaceHolder=" + mSurfaceHolder
+ + ", mSeekWhenPrepared=" + mSeekWhenPrepared + ", mMediaPlayer=" + mMediaPlayer);
+ }
+ }
+
+ private void doPrepared(final MediaPlayer mp) {
+ if (LOG) {
+ QcomLog.v(TAG, "doPrepared(" + mp + ") start");
+ }
+ mCurrentState = STATE_PREPARED;
+ if (mOnPreparedListener != null) {
+ mOnPreparedListener.onPrepared(mMediaPlayer);
+ }
+ mVideoWidth = mp.getVideoWidth();
+ mVideoHeight = mp.getVideoHeight();
+
+ final int seekToPosition = mSeekWhenPrepared; // mSeekWhenPrepared may be changed after seekTo() call
+ if (seekToPosition != 0) {
+ seekTo(seekToPosition);
+ }
+ if (mVideoWidth != 0 && mVideoHeight != 0) {
+ getHolder().setFixedSize(mVideoWidth, mVideoHeight);
+ }
+
+ if (mTargetState == STATE_PLAYING) {
+ start();
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "doPrepared() end video size: " + mVideoWidth + "," + mVideoHeight
+ + ", mTargetState=" + mTargetState + ", mCurrentState=" + mCurrentState);
+ }
+ }
+
+ private boolean mOnResumed;
+ /**
+ * surfaceCreate will invoke openVideo after the activity stoped.
+ * Here set this flag to avoid openVideo after the activity stoped.
+ * @param resume
+ */
+ public void setResumed(final boolean resume) {
+ if (LOG) {
+ QcomLog.v(TAG, "setResumed(" + resume + ") mUri=" + mUri + ", mOnResumed=" + mOnResumed);
+ }
+ mOnResumed = resume;
+ }
+
+ @Override
+ public void resume() {
+ if (LOG) {
+ QcomLog.v(TAG, "resume() mTargetState=" + mTargetState + ", mCurrentState=" + mCurrentState);
+ }
+ setResumed(true);
+ openVideo();
+ }
+
+ @Override
+ public void suspend() {
+ if (LOG) {
+ QcomLog.v(TAG, "suspend() mTargetState=" + mTargetState + ", mCurrentState=" + mCurrentState);
+ }
+ super.suspend();
+ }
+
+ public void setOnInfoListener(final OnInfoListener l) {
+ mOnInfoListener = l;
+ if (LOG) {
+ QcomLog.v(TAG, "setInfoListener(" + l + ")");
+ }
+ }
+
+ public void setOnBufferingUpdateListener(final OnBufferingUpdateListener l) {
+ mOnBufferingUpdateListener = l;
+ if (LOG) {
+ QcomLog.v(TAG, "setOnBufferingUpdateListener(" + l + ")");
+ }
+ }
+
+ public void setOnVideoSizeChangedListener(final OnVideoSizeChangedListener l) {
+ mVideoSizeListener = l;
+ if (LOG) {
+ Log.i(TAG, "setOnVideoSizeChangedListener(" + l + ")");
+ }
+ }
+
+ @Override
+ public int getCurrentPosition() {
+ int position = 0;
+ if (mSeekWhenPrepared > 0) {
+ //if connecting error before seek,
+ //we should remember this position for retry
+ position = mSeekWhenPrepared;
+ ///M: if player not started, getCurrentPosition() will lead to NE.
+ } else if (isInPlaybackState() && mCurrentState != STATE_PREPARED) {
+ position = mMediaPlayer.getCurrentPosition();
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "getCurrentPosition() return " + position
+ + ", mSeekWhenPrepared=" + mSeekWhenPrepared);
+ }
+ return position;
+ }
+
+ //clear the seek position any way.
+ //this will effect the case: stop video before it's seek completed.
+ public void clearSeek() {
+ if (LOG) {
+ QcomLog.v(TAG, "clearSeek() mSeekWhenPrepared=" + mSeekWhenPrepared);
+ }
+ mSeekWhenPrepared = 0;
+ }
+
+ public boolean isTargetPlaying() {
+ if (LOG) {
+ Log.v(TAG, "isTargetPlaying() mTargetState=" + mTargetState);
+ }
+ return mTargetState == STATE_PLAYING;
+ }
+
+ public void dump() {
+ if (LOG) {
+ Log.v(TAG, "dump() mUri=" + mUri
+ + ", mTargetState=" + mTargetState + ", mCurrentState=" + mCurrentState
+ + ", mSeekWhenPrepared=" + mSeekWhenPrepared
+ + ", mVideoWidth=" + mVideoWidth + ", mVideoHeight=" + mVideoHeight
+ + ", mMediaPlayer=" + mMediaPlayer + ", mSurfaceHolder=" + mSurfaceHolder);
+ }
+ }
+
+ @Override
+ public void seekTo(final int msec) {
+ if (LOG) {
+ Log.v(TAG, "seekTo(" + msec + ") isInPlaybackState()=" + isInPlaybackState());
+ }
+ super.seekTo(msec);
+ }
+
+ @Override
+ protected void release(final boolean cleartargetstate) {
+ if (LOG) {
+ Log.v(TAG, "release(" + cleartargetstate + ") mMediaPlayer=" + mMediaPlayer);
+ }
+ super.release(cleartargetstate);
+ }
+
+ //for duration displayed
+ public void setDuration(final int duration) {
+ if (LOG) {
+ Log.v(TAG, "setDuration(" + duration + ")");
+ }
+ mDuration = (duration > 0 ? -duration : duration);
+ }
+
+ @Override
+ public int getDuration() {
+ final boolean inPlaybackState = isInPlaybackState();
+ if (LOG) {
+ Log.v(TAG, "getDuration() mDuration=" + mDuration + ", inPlaybackState=" + inPlaybackState);
+ }
+ if (inPlaybackState) {
+ if (mDuration > 0) {
+ return mDuration;
+ }
+ mDuration = mMediaPlayer.getDuration();
+ return mDuration;
+ }
+ //mDuration = -1;
+ return mDuration;
+ }
+
+ public void clearDuration() {
+ if (LOG) {
+ QcomLog.v(TAG, "clearDuration() mDuration=" + mDuration);
+ }
+ mDuration = -1;
+ }
+
+ //for video size changed before started issue
+ private static final int MSG_LAYOUT_READY = 1;
+ private boolean mNeedWaitLayout = false;
+ private final Handler mHandler = new Handler() {
+ public void handleMessage(final Message msg) {
+ if (LOG) {
+ QcomLog.v(TAG, "handleMessage() to do prepare. msg=" + msg);
+ }
+ switch(msg.what) {
+ case MSG_LAYOUT_READY:
+ if (mMediaPlayer == null || mUri == null) {
+ QcomLog.w(TAG, "Cannot prepare play! mMediaPlayer=" + mMediaPlayer + ", mUri=" + mUri);
+ } else {
+ doPreparedIfReady(mMediaPlayer);
+ }
+ break;
+ default:
+ QcomLog.w(TAG, "Unhandled message " + msg);
+ break;
+ }
+ }
+ };
+
+ private ScreenModeManager mScreenManager;
+ public void setScreenModeManager(final ScreenModeManager manager) {
+ mScreenManager = manager;
+ if (mScreenManager != null) {
+ mScreenManager.addListener(this);
+ }
+ if (LOG) {
+ QcomLog.v(TAG, "setScreenModeManager(" + manager + ")");
+ }
+ }
+
+ @Override
+ public void onScreenModeChanged(final int newMode) {
+ this.requestLayout();
+ }
+}
diff --git a/src/com/qcom/gallery3d/video/SettingsActivity.java b/src/com/qcom/gallery3d/video/SettingsActivity.java
new file mode 100755
index 000000000..0d73c5428
--- /dev/null
+++ b/src/com/qcom/gallery3d/video/SettingsActivity.java
@@ -0,0 +1,371 @@
+
+package com.qcom.gallery3d.video;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.RingtonePreference;
+import android.preference.PreferenceScreen;
+import android.provider.Telephony;
+import android.telephony.MSimTelephonyManager;
+import java.util.ArrayList;
+import android.os.SystemProperties;
+
+
+
+
+
+/* wangyong 2012.2.9 begin*/
+//import android.provider.Calendar;
+/* wangyong 2012.2.9 end*/
+import android.provider.ContactsContract;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MenuItem;
+import android.text.method.DigitsKeyListener;
+import android.net.Uri;
+
+import android.telephony.TelephonyManager;
+import com.android.gallery3d.R;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+
+public class SettingsActivity extends PreferenceActivity {
+ public static final String PREFERENCE_RTP_MINPORT = "rtp_min_port";
+
+ public static final String PREFERENCE_RTP_MAXPORT = "rtp_max_port";
+
+ public static final String PREFERENCE_RTCP_MINPORT = "rtcp_min_port";
+
+ public static final String PREFERENCE_RTCP_MAXPORT = "rtcp_max_port";
+
+ public static final String PREFERENCE_BUFFER_SIZE = "buffer_size";
+
+ public static final String PREFERENCE_APN = "apn";
+
+
+ private EditTextPreference mRtpMinPort;
+
+ private EditTextPreference mRtpMaxPort;
+
+ private EditTextPreference mRtcpMinPort;
+
+ private EditTextPreference mRtcpMaxPort;
+
+ private EditTextPreference mBufferSize;
+
+ private PreferenceScreen mApn;
+
+ private CheckBoxPreference mRepeat;
+
+ private static final int SELECT_APN = 1;
+
+ public static final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
+
+ private static final Uri PREFERAPN_URI = Uri.parse(PREFERRED_APN_URI);
+
+ private static final int ID_INDEX = 0;
+
+ private static final int NAME_INDEX = 1;
+
+ private boolean mUseNvOperatorForEhrpd = SystemProperties.getBoolean(
+ "persist.radio.use_nv_for_ehrpd", false);
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.v("settingActivty", "onCreate");
+ addPreferencesFromResource(R.xml.rtsp_settings_preferences);
+
+ // SharedPreferences mPref =
+ // PreferenceManager.getDefaultSharedPreferences(ComposeMessageActivity.this);
+ SharedPreferences mPref;
+ mPref = getPreferenceScreen().getSharedPreferences();
+ String rtpMinport = mPref.getString(PREFERENCE_RTP_MINPORT, "8192");
+ String rtpMaxport = mPref.getString(PREFERENCE_RTP_MAXPORT, "65535");
+ String rtcpMinport = mPref.getString(PREFERENCE_RTCP_MAXPORT, null);
+ String rtcpMaxport = mPref.getString(PREFERENCE_RTCP_MAXPORT, null);
+ String bufferSize = mPref.getString(PREFERENCE_BUFFER_SIZE, null);
+ // String apn = getSelectedApnKey();//mPref.getString(PREFERENCE_APN,
+ // "CMWAP");
+ mRtpMinPort = (EditTextPreference) findPreference(PREFERENCE_RTP_MINPORT);
+ mRtpMinPort.getEditText().setKeyListener(DigitsKeyListener.getInstance("0123456789"));
+ mRtpMinPort.setSummary(rtpMinport);
+ mRtpMinPort.setText(rtpMinport);
+ mRtpMinPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final String summary = newValue.toString();
+ mRtpMinPort.setSummary(summary);
+ /* Start of zhuzhongwei 2011.2.14 */
+ Log.w("rtsp", "z66 summary = " + summary);
+ android.provider.Settings.System.putString(getContentResolver(),
+ "streaming_min_udp_port", summary);
+ /* End of zhuzhongwei 2011.2.14 */
+ return true;
+ }
+ });
+
+ mRtpMaxPort = (EditTextPreference) findPreference(PREFERENCE_RTP_MAXPORT);
+ mRtpMaxPort.getEditText().setKeyListener(DigitsKeyListener.getInstance("0123456789"));
+ mRtpMaxPort.setSummary(rtpMaxport);
+ mRtpMaxPort.setText(rtpMaxport);
+ mRtpMaxPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final String summary = newValue.toString();
+ mRtpMaxPort.setSummary(summary);
+ /* Start of zhuzhongwei 2011.2.14 */
+ Log.w("rtsp", "z82 summary = " + summary);
+ android.provider.Settings.System.putString(getContentResolver(),
+ "streaming_max_udp_port", summary);
+ /* End of zhuzhongwei 2011.2.14 */
+ return true;
+ }
+ });
+ mRtcpMinPort = (EditTextPreference) findPreference(PREFERENCE_RTCP_MINPORT);
+ mRtcpMinPort.getEditText().setKeyListener(DigitsKeyListener.getInstance("0123456789"));
+ mRtcpMinPort.setSummary(rtcpMinport);
+ mRtcpMinPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final String summary = newValue.toString();
+ mRtcpMinPort.setSummary(summary);
+ return true;
+ }
+ });
+ mRtcpMaxPort = (EditTextPreference) findPreference(PREFERENCE_RTCP_MAXPORT);
+ mRtcpMaxPort.getEditText().setKeyListener(DigitsKeyListener.getInstance("0123456789"));
+ mRtcpMaxPort.setSummary(rtcpMaxport);
+ mRtcpMaxPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final String summary = newValue.toString();
+ mRtcpMaxPort.setSummary(summary);
+ return true;
+ }
+ });
+
+ mBufferSize = (EditTextPreference) findPreference(PREFERENCE_BUFFER_SIZE);
+ mBufferSize.getEditText().setKeyListener(DigitsKeyListener.getInstance("0123456789"));
+ mBufferSize.setSummary(bufferSize);
+ mBufferSize.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final String summary = newValue.toString();
+ mBufferSize.setSummary(summary);
+ return true;
+ }
+ });
+
+ /*
+ * mBufferSize= (EditTextPreference)
+ * findPreference(PREFERENCE_BUFFER_SIZE);
+ * mBufferSize.getEditText().setKeyListener
+ * (DigitsKeyListener.getInstance("0123456789"));
+ * mBufferSize.setSummary(bufferSize);
+ * mBufferSize.setOnPreferenceChangeListener(new
+ * Preference.OnPreferenceChangeListener() { public boolean
+ * onPreferenceChange(Preference preference, Object newValue) { final
+ * String summary = newValue.toString();
+ * mBufferSize.setSummary(summary); return true; } }); <!----
+ * <PreferenceCategory android:title="@string/buffer_size">
+ * <EditTextPreference android:order="5" android:key="buffer_size"
+ * android:title="@string/buffer_size" android:summary=""
+ * android:inputType="number"
+ * android:dialogTitle="@string/set_buffer_size" />
+ * </PreferenceCategory> ---->
+ */
+ /*
+ * mApn = (ListPreference) findPreference(PREFERENCE_APN);
+ * mApn.setValue(apn); mApn.setSummary(mApn.getEntry());
+ * mApn.setOnPreferenceChangeListener(new
+ * Preference.OnPreferenceChangeListener() { public boolean
+ * onPreferenceChange(Preference preference, Object newValue) { final
+ * String summary = newValue.toString(); int index =
+ * mApn.findIndexOfValue(summary);
+ * mApn.setSummary(mApn.getEntries()[index]); mApn.setValue(summary);
+ * android.provider.Settings.System.putString(getContentResolver(),
+ * "apn", summary); return true; } });
+ */
+ /*
+ * mApn = (ListPreference) findPreference(PREFERENCE_APN);
+ * mApn.setValue(getSelectedApnKey()); mApn.setSummary(mApn.getEntry());
+ * mApn.setOnPreferenceChangeListener(new
+ * Preference.OnPreferenceChangeListener() { public boolean
+ * onPreferenceChange(Preference preference, Object newValue) { //final
+ * String summary = newValue.toString(); //int index =
+ * mApn.findIndexOfValue(summary);
+ * ////mApn.setSummary(mApn.getEntries()[index]);
+ * //mApn.setValue(summary);
+ * //android.provider.Settings.System.putString(getContentResolver(),
+ * "apn", summary); Intent intent = new Intent();
+ * intent.setClassName("com.android.settings"
+ * ,"com.android.settings.ApnSettings"); //startActivity(intent);
+ * startActivityForResult(intent, SELECT_APN); return true; } });
+ */
+
+ mApn = (PreferenceScreen) findPreference(PREFERENCE_APN);
+ // mApn.setValue(getSelectedApnKey());
+ mApn.setSummary(getDefaultApnName());
+ mApn.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ // final String summary = newValue.toString();
+ // int index = mApn.findIndexOfValue(summary);
+ // //mApn.setSummary(mApn.getEntries()[index]);
+ // mApn.setValue(summary);
+ // android.provider.Settings.System.putString(getContentResolver(),
+ // "apn", summary);
+
+ Intent intent = new Intent();
+ intent.setClassName("com.android.settings", "com.android.settings.ApnSettings");
+ // startActivity(intent);
+ startActivityForResult(intent, SELECT_APN);
+ return true;
+ }
+ });
+
+
+ // lizhongchao add for 4.0 UI START
+ ActionBar ab = getActionBar();
+ ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+ ab.setDisplayHomeAsUpEnabled(true);
+ ab.setTitle(R.string.setting);
+ // lizhongchao add for 4.0 UI END
+ }
+
+ private String getDefaultApnName() {
+
+ // to find default key
+ String key = null;
+ String name = null;
+ Cursor cursor = getContentResolver().query(PREFERAPN_URI, new String[] {
+ "_id"
+ }, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+ if (cursor.getCount() > 0) {
+ cursor.moveToFirst();
+ key = cursor.getString(ID_INDEX);
+ Log.v("settingActivty", "default apn key = " + key);
+ }
+ cursor.close();
+
+ // to find default proxy
+ /**
+ String where = "numeric=\""
+ + android.os.SystemProperties.get(
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "") + "\"";
+ */
+
+ String where = getOperatorNumericSelection();
+
+ cursor = getContentResolver().query(Telephony.Carriers.CONTENT_URI, new String[] {
+ "_id", "name", "apn", "type"
+ }, where, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+
+ while (cursor != null && cursor.moveToNext()) {
+ String curKey = cursor.getString(cursor.getColumnIndex("_id"));
+ String curName = cursor.getString(cursor.getColumnIndex("name"));
+ Log.v("settingActivty", "default apn curkey = " + curKey);
+ Log.v("settingActivty", "default apn curName = " + curName);
+ // String user = cursor.getString(cursor.getColumnIndex("user"));
+ // String password =
+ // cursor.getString(cursor.getColumnIndex("password"));
+ // a.proxy = cursor.getString(cursor.getColumnIndex("proxy"));
+ // a.type = cursor.getString(cursor.getColumnIndex("type"));
+
+ // logv( "getDefaultApn, a.key=" + a.key + ",a.apn=" + a.apn +
+ // ",a.user=" + a.user + ",a.password=" + a.password + ", a.proxy="
+ // + a.proxy);
+ // Log.d("rtsp","getDefaultApnName, cur, key=" + curKey +
+ // ",curName=" + curName);
+ if (curKey.equals(key)) {
+ Log.d("rtsp", "getDefaultApnName, find, key=" + curKey + ",curName=" + curName);
+ name = curName;
+ break;
+ }
+ }
+
+ if (cursor != null)
+ cursor.close();
+ Log.v("settingActivty", "default apn name = " + name);
+
+ return name;
+
+ }
+
+ private String getSelectedApnKey() {
+ String key = null;
+
+ Cursor cursor = getContentResolver().query(PREFERAPN_URI, new String[] {
+ "_id", "name"
+ }, null, null, null);
+ if (cursor.getCount() > 0) {
+ cursor.moveToFirst();
+ key = cursor.getString(NAME_INDEX);
+ }
+ cursor.close();
+
+ Log.w("rtsp", "getSelectedApnKey key = " + key);
+ if (null == key)
+ return new String("null");
+ return key;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case SELECT_APN:
+ // if (resultCode == RESULT_CANCELED) {
+ setResult(resultCode);
+ finish();
+ Log.w("rtsp", "onActivityResult requestCode = " + requestCode);
+ // mApn.setSummary(getDefaultApnName());
+ // }
+ break;
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // TODO Auto-generated method stub
+ if(item.getItemId() == android.R.id.home){
+ finish();
+ }
+ return true;
+ }
+
+
+ private String getOperatorNumericSelection() {
+ String[] mccmncs = getOperatorNumeric();
+ String where;
+ where = (mccmncs[0] != null) ? "numeric=\"" + mccmncs[0] + "\"" : "";
+ where += (mccmncs[1] != null) ? " or numeric=\"" + mccmncs[1] + "\"" : "";
+ Log.d("SettingsActivity", "getOperatorNumericSelection: " + where);
+ return where;
+ }
+
+ private String[] getOperatorNumeric() {
+ ArrayList<String> result = new ArrayList<String>();
+ String mccMncFromSim = null;
+ if (mUseNvOperatorForEhrpd) {
+ String mccMncForEhrpd = SystemProperties.get("ro.cdma.home.operator.numeric", null);
+ if (mccMncForEhrpd != null && mccMncForEhrpd.length() > 0) {
+ result.add(mccMncForEhrpd);
+ }
+ }
+
+ mccMncFromSim = TelephonyManager.getDefault().getSimOperator();
+
+ if (mccMncFromSim != null && mccMncFromSim.length() > 0) {
+ result.add(mccMncFromSim);
+ }
+ return result.toArray(new String[2]);
+ }
+}
diff --git a/src/com/qcom/gallery3d/video/StreamingHooker.java b/src/com/qcom/gallery3d/video/StreamingHooker.java
new file mode 100755
index 000000000..84152fc9d
--- /dev/null
+++ b/src/com/qcom/gallery3d/video/StreamingHooker.java
@@ -0,0 +1,89 @@
+package com.qcom.gallery3d.video;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Browser;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.gallery3d.R;
+import com.qcom.gallery3d.ext.MovieUtils;
+import com.qcom.gallery3d.ext.QcomLog;
+
+public class StreamingHooker extends MovieHooker {
+ private static final String TAG = "StreamingHooker";
+ private static final boolean LOG = true;
+
+ private static final String ACTION_STREAMING = "com.qcom.settings.streaming";
+ private static final int MENU_INPUT_URL = 1;
+ private static final int MENU_SETTINGS = 2;
+ private static final int MENU_DETAIL = 3;
+ private MenuItem mMenuDetail;
+
+ public static final String KEY_LOGO_BITMAP = "logo-bitmap";
+
+ @Override
+ public boolean onCreateOptionsMenu(final Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ //when in rtsp streaming type, generally it only has one uri.
+ mMenuDetail = menu.add(0, getMenuActivityId(MENU_DETAIL), 0, R.string.media_detail);
+ menu.add(0, getMenuActivityId(MENU_INPUT_URL), 0, R.string.input_url);
+ menu.add(0, getMenuActivityId(MENU_SETTINGS), 0, R.string.streaming_settings);
+ return true;
+ }
+ @Override
+ public boolean onPrepareOptionsMenu(final Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ if (MovieUtils.isLocalFile(getMovieItem().getUri(), getMovieItem().getMimeType())) {
+ if (mMenuDetail != null) {
+ mMenuDetail.setVisible(false);
+ }
+ } else {
+ if (mMenuDetail != null) {
+ mMenuDetail.setVisible(false);
+ }
+ }
+ return true;
+ }
+ @Override
+ public boolean onOptionsItemSelected(final MenuItem item) {
+ super.onOptionsItemSelected(item);
+ switch(getMenuOriginalId(item.getItemId())) {
+ case MENU_INPUT_URL:
+ gotoInputUrl();
+ return true;
+ case MENU_SETTINGS:
+ gotoSettings();
+ return true;
+ case MENU_DETAIL:
+ getPlayer().showDetail();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private void gotoInputUrl() {
+ final String appName = getClass().getName();
+ final Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse("about:blank"));
+ intent.putExtra("inputUrl", true);
+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, appName);
+ getContext().startActivity(intent);
+ if (LOG) {
+ QcomLog.v(TAG, "gotoInputUrl() appName=" + appName);
+ }
+ }
+
+ private void gotoSettings() {
+ final Intent intent = new Intent(ACTION_STREAMING);
+// intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+// | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
+// intent.putExtra(KEY_LOGO_BITMAP, getIntent().getParcelableExtra(KEY_LOGO_BITMAP));
+ getContext().startActivity(intent);
+ if (LOG) {
+ QcomLog.v(TAG, "gotoInputUrl()");
+ }
+ }
+} \ No newline at end of file