Gallery2: support live streaming and bookmarks

(cherry picked new files from commit id
990c6d43ea7c184846e19d41bef0d93aee4e581b)

Change-Id: Idc254cf0f7e8a9b492203313fa63349d07d19d5c
diff --git a/res/drawable-hdpi/ic_menu_display_bookmark.png b/res/drawable-hdpi/ic_menu_display_bookmark.png
new file mode 100755
index 0000000..a5118ea
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_display_bookmark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_display_bookmark.png b/res/drawable-mdpi/ic_menu_display_bookmark.png
new file mode 100755
index 0000000..a3acdd6
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_display_bookmark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_display_bookmark.png b/res/drawable-xhdpi/ic_menu_display_bookmark.png
new file mode 100755
index 0000000..4ad8414
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_display_bookmark.png
Binary files differ
diff --git a/res/layout/bookmark.xml b/res/layout/bookmark.xml
new file mode 100755
index 0000000..9b765d4
--- /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 0000000..fa1439c
--- /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 0000000..a743e9e
--- /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 0000000..b15080d
--- /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 0000000..8e79281
--- /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 0000000..033b055
--- /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 0000000..fc8bcd8
--- /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 0000000..b8d661e
--- /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 0000000..42ba3ec
--- /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 0000000..ba54855
--- /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 0000000..b3324e9
--- /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 0000000..84152fc
--- /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