diff options
| author | Likai Ding <likaid@codeaurora.org> | 2013-08-15 15:02:24 +0800 |
|---|---|---|
| committer | Xiaojing Zhang <zhangx@codeaurora.org> | 2014-11-04 20:37:59 -0800 |
| commit | 9bc105fca37faf4c868987b3a22992e39e4348f2 (patch) | |
| tree | 4116b76dc60cb3271cbc572c5d1e85d86ff6b3b1 | |
| parent | 60e2e3ff9ee15841099cd057895db838bda0a8d9 (diff) | |
| download | android_packages_apps_Gallery2-9bc105fca37faf4c868987b3a22992e39e4348f2.tar.gz android_packages_apps_Gallery2-9bc105fca37faf4c868987b3a22992e39e4348f2.tar.bz2 android_packages_apps_Gallery2-9bc105fca37faf4c868987b3a22992e39e4348f2.zip | |
Gallery2: support live streaming and bookmarks
(cherry picked new files from commit id
990c6d43ea7c184846e19d41bef0d93aee4e581b)
Change-Id: Idc254cf0f7e8a9b492203313fa63349d07d19d5c
| -rwxr-xr-x | res/drawable-hdpi/ic_menu_display_bookmark.png | bin | 0 -> 1717 bytes | |||
| -rwxr-xr-x | res/drawable-mdpi/ic_menu_display_bookmark.png | bin | 0 -> 1709 bytes | |||
| -rwxr-xr-x | res/drawable-xhdpi/ic_menu_display_bookmark.png | bin | 0 -> 2460 bytes | |||
| -rwxr-xr-x | res/layout/bookmark.xml | 22 | ||||
| -rwxr-xr-x | res/layout/bookmark_edit_dialog.xml | 37 | ||||
| -rwxr-xr-x | res/layout/bookmark_item.xml | 21 | ||||
| -rwxr-xr-x | res/xml/rtsp_settings_preferences.xml | 89 | ||||
| -rwxr-xr-x | src/com/qcom/gallery3d/video/BookmarkActivity.java | 242 | ||||
| -rwxr-xr-x | src/com/qcom/gallery3d/video/BookmarkEnhance.java | 132 | ||||
| -rwxr-xr-x | src/com/qcom/gallery3d/video/BookmarkHooker.java | 72 | ||||
| -rwxr-xr-x | src/com/qcom/gallery3d/video/DmReceiver.java | 82 | ||||
| -rwxr-xr-x | src/com/qcom/gallery3d/video/MovieTitleHelper.java | 98 | ||||
| -rwxr-xr-x | src/com/qcom/gallery3d/video/QcomVideoView.java | 721 | ||||
| -rwxr-xr-x | src/com/qcom/gallery3d/video/SettingsActivity.java | 371 | ||||
| -rwxr-xr-x | src/com/qcom/gallery3d/video/StreamingHooker.java | 89 |
15 files changed, 1976 insertions, 0 deletions
diff --git a/res/drawable-hdpi/ic_menu_display_bookmark.png b/res/drawable-hdpi/ic_menu_display_bookmark.png Binary files differnew file mode 100755 index 000000000..a5118ea85 --- /dev/null +++ b/res/drawable-hdpi/ic_menu_display_bookmark.png diff --git a/res/drawable-mdpi/ic_menu_display_bookmark.png b/res/drawable-mdpi/ic_menu_display_bookmark.png Binary files differnew file mode 100755 index 000000000..a3acdd64b --- /dev/null +++ b/res/drawable-mdpi/ic_menu_display_bookmark.png diff --git a/res/drawable-xhdpi/ic_menu_display_bookmark.png b/res/drawable-xhdpi/ic_menu_display_bookmark.png Binary files differnew file mode 100755 index 000000000..4ad8414be --- /dev/null +++ b/res/drawable-xhdpi/ic_menu_display_bookmark.png diff --git a/res/layout/bookmark.xml b/res/layout/bookmark.xml new file mode 100755 index 000000000..9b765d4d9 --- /dev/null +++ b/res/layout/bookmark.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + <ListView + android:id="@android:id/list" + android:layout_width="match_parent" + android:layout_height="match_parent" + /> + <TextView + android:id="@android:id/empty" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_centerInParent="true" + android:paddingBottom="30dip" + android:gravity ="center" + android:textAppearance="?android:attr/textAppearanceLarge" + android:text="@string/bookmark_empty" + android:visibility="gone" + /> +</FrameLayout> diff --git a/res/layout/bookmark_edit_dialog.xml b/res/layout/bookmark_edit_dialog.xml new file mode 100755 index 000000000..fa1439cdb --- /dev/null +++ b/res/layout/bookmark_edit_dialog.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="8dip" + android:orientation="vertical"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="?android:attr/textAppearanceSmallInverse" + android:text="@string/bookmark_title" /> + <EditText + android:id="@+id/title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="2dip" + android:singleLine="true" + android:inputType="text" + android:scrollHorizontally="true" /> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="?android:attr/textAppearanceSmallInverse" + android:text="@string/bookmark_location" /> + <EditText + android:id="@+id/data" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="2dip" + android:singleLine="true" + android:inputType="textUri" + android:scrollHorizontally="true" /> + </LinearLayout> +</ScrollView>
\ No newline at end of file diff --git a/res/layout/bookmark_item.xml b/res/layout/bookmark_item.xml new file mode 100755 index 000000000..a743e9e17 --- /dev/null +++ b/res/layout/bookmark_item.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/panel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="6dip" + android:orientation="vertical" + > + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:textAppearance="?android:attr/textAppearanceMedium" + android:singleLine="true" + /> + <TextView + android:id="@+id/data" + android:layout_width="wrap_content" + android:layout_height="match_parent" + /> +</LinearLayout> diff --git a/res/xml/rtsp_settings_preferences.xml b/res/xml/rtsp_settings_preferences.xml new file mode 100755 index 000000000..b15080dfa --- /dev/null +++ b/res/xml/rtsp_settings_preferences.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +write by lhy +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + + <PreferenceCategory + android:title="@string/rtp"> + + <EditTextPreference + android:order="1" + android:key="rtp_min_port" + android:title="@string/rtp_min_port" + android:summary="" + android:inputType="number" + android:maxLength="5" + android:dialogTitle="@string/set_rtp_min_port" /> + + <EditTextPreference + android:order="2" + android:key="rtp_max_port" + android:title="@string/rtp_max_port" + android:summary="" + android:inputType="number" + android:maxLength="5" + android:dialogTitle="@string/rtp_max_port" /> + </PreferenceCategory> + + <PreferenceCategory + android:title="@string/rtcp"> + + <EditTextPreference + android:order="3" + android:key="rtcp_min_port" + android:title="@string/rtcp_min_port" + android:summary="" + android:inputType="number" + android:maxLength="5" + android:dialogTitle="@string/set_rtcp_min_port" /> + + <EditTextPreference + android:order="4" + android:key="rtcp_max_port" + android:title="@string/rtcp_max_port" + android:summary="" + android:inputType="number" + android:maxLength="5" + android:dialogTitle="@string/rtcp_max_port" /> + </PreferenceCategory> + + <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:maxLength="5" + android:dialogTitle="@string/set_buffer_size" /> + + </PreferenceCategory> + + <PreferenceCategory android:title="@string/apn"> + <PreferenceScreen + android:key="apn" + android:title="@string/apn"> + <!-- + <intent + android:action="android.intent.action.MAIN" + android:targetPackage="com.android.settings" + android:targetClass="com.android.settings.ApnSettings" /> + --> + </PreferenceScreen> + <!-- + <ListPreference + android:order="6" + android:key="apn" + android:title="@string/apn" + android:entries="@array/apn_entries" + android:entryValues="@array/apn_values" + android:dialogTitle="@string/set_apn" /> + --> + </PreferenceCategory> + + +</PreferenceScreen> 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..b8d661e1f --- /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..b3324e9f2 --- /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 |
