MessageListItem.java revision f114492537753bc68640d4a0d403861387296bcb
1/*
2 * Copyright (C) 2008 Esmertec AG.
3 * Copyright (C) 2008 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mms.ui;
19
20import java.util.Map;
21import java.util.regex.Matcher;
22import java.util.regex.Pattern;
23
24import android.app.AlertDialog;
25import android.content.Context;
26import android.content.DialogInterface;
27import android.content.Intent;
28import android.graphics.Bitmap;
29import android.graphics.BitmapFactory;
30import android.graphics.Canvas;
31import android.graphics.Paint;
32import android.graphics.Typeface;
33import android.graphics.Paint.FontMetricsInt;
34import android.graphics.drawable.Drawable;
35import android.net.Uri;
36import android.os.Handler;
37import android.os.Message;
38import android.provider.Browser;
39import com.android.mms.telephony.TelephonyProvider.Mms;
40import com.android.mms.telephony.TelephonyProvider.MmsSms;
41import com.android.mms.telephony.TelephonyProvider.Sms;
42import android.telephony.PhoneNumberUtils;
43import android.telephony.TelephonyManager;
44import android.text.Layout;
45import android.text.Spannable;
46import android.text.SpannableStringBuilder;
47import android.text.TextUtils;
48import android.text.method.HideReturnsTransformationMethod;
49import android.text.style.ForegroundColorSpan;
50import android.text.style.LeadingMarginSpan;
51import android.text.style.LineHeightSpan;
52import android.text.style.StyleSpan;
53import android.text.style.TextAppearanceSpan;
54import android.text.style.URLSpan;
55import android.util.AttributeSet;
56import android.view.View;
57import android.view.ViewGroup;
58import android.view.View.OnClickListener;
59import android.widget.ArrayAdapter;
60import android.widget.Button;
61import android.widget.ImageButton;
62import android.widget.ImageView;
63import android.widget.LinearLayout;
64import android.widget.QuickContactBadge;
65import android.widget.TextView;
66
67import com.android.mms.MmsApp;
68import com.android.mms.R;
69import com.android.mms.data.WorkingMessage;
70import com.android.mms.transaction.Transaction;
71import com.android.mms.transaction.TransactionBundle;
72import com.android.mms.transaction.TransactionService;
73import com.android.mms.util.DownloadManager;
74import com.android.mms.util.SmileyParser;
75import com.android.mms.mms.pdu.PduHeaders;
76
77/**
78 * This class provides view of a message in the messages list.
79 */
80public class MessageListItem extends LinearLayout implements
81        SlideViewInterface, OnClickListener {
82    public static final String EXTRA_URLS = "com.android.mms.ExtraUrls";
83
84    private static final String TAG = "MessageListItem";
85    private static final StyleSpan STYLE_BOLD = new StyleSpan(Typeface.BOLD);
86
87    static final int MSG_LIST_EDIT_MMS   = 1;
88    static final int MSG_LIST_EDIT_SMS   = 2;
89
90    private View mMsgListItem;
91    private View mMmsView;
92    private ImageView mImageView;
93    private ImageView mRightStatusIndicator;
94    private ImageButton mSlideShowButton;
95    private TextView mBodyTextView;
96    private Button mDownloadButton;
97    private TextView mDownloadingLabel;
98    private QuickContactBadge mAvatar;
99    private Handler mHandler;
100    private MessageItem mMessageItem;
101
102    public MessageListItem(Context context) {
103        super(context);
104    }
105
106    public MessageListItem(Context context, AttributeSet attrs) {
107        super(context, attrs);
108
109        int color = mContext.getResources().getColor(R.color.timestamp_color);
110        mColorSpan = new ForegroundColorSpan(color);
111    }
112
113    @Override
114    protected void onFinishInflate() {
115        super.onFinishInflate();
116
117        mMsgListItem = findViewById(R.id.msg_list_item);
118        mBodyTextView = (TextView) findViewById(R.id.text_view);
119        mRightStatusIndicator = (ImageView) findViewById(R.id.right_status_indicator);
120        mAvatar = (QuickContactBadge) findViewById(R.id.avatar);
121
122        ViewGroup.MarginLayoutParams badgeParams = (MarginLayoutParams)mAvatar.getLayoutParams();
123        final int badgeWidth = badgeParams.width + badgeParams.rightMargin + badgeParams.leftMargin;
124
125        int lineHeight = mBodyTextView.getLineHeight();
126        int effectiveBadgeHeight = badgeParams.height + badgeParams.topMargin - mBodyTextView.getPaddingTop();
127        final int indentLineCount = (int) ((effectiveBadgeHeight-1) / lineHeight) + 1;
128
129        mLeadingMarginSpan = new LeadingMarginSpan.LeadingMarginSpan2() {
130            public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
131                    int top, int baseline, int bottom, CharSequence text,
132                    int start, int end, boolean first, Layout layout) {
133                // no op
134            }
135
136            public int getLeadingMargin(boolean first) {
137                return first ? badgeWidth : 0;
138            }
139
140            public int getLeadingMarginLineCount() {
141                return indentLineCount;
142            }
143        };
144
145    }
146
147    public void bind(MessageListAdapter.AvatarCache avatarCache, MessageItem msgItem) {
148        mMessageItem = msgItem;
149
150        setLongClickable(false);
151
152        switch (msgItem.mMessageType) {
153            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
154                bindNotifInd(msgItem);
155                break;
156            default:
157                bindCommonMessage(avatarCache, msgItem);
158                break;
159        }
160    }
161
162    public MessageItem getMessageItem() {
163        return mMessageItem;
164    }
165
166    public void setMsgListItemHandler(Handler handler) {
167        mHandler = handler;
168    }
169
170    private void bindNotifInd(final MessageItem msgItem) {
171        hideMmsViewIfNeeded();
172
173        String msgSizeText = mContext.getString(R.string.message_size_label)
174                                + String.valueOf((msgItem.mMessageSize + 1023) / 1024)
175                                + mContext.getString(R.string.kilobyte);
176
177        mBodyTextView.setText(formatMessage(msgItem.mContact, null, msgItem.mSubject,
178                                            msgSizeText + "\n" + msgItem.mTimestamp,
179                                            msgItem.mHighlight));
180
181        int state = DownloadManager.getInstance().getState(msgItem.mMessageUri);
182        switch (state) {
183            case DownloadManager.STATE_DOWNLOADING:
184                inflateDownloadControls();
185                mDownloadingLabel.setVisibility(View.VISIBLE);
186                mDownloadButton.setVisibility(View.GONE);
187                break;
188            case DownloadManager.STATE_UNSTARTED:
189            case DownloadManager.STATE_TRANSIENT_FAILURE:
190            case DownloadManager.STATE_PERMANENT_FAILURE:
191            default:
192                setLongClickable(true);
193                inflateDownloadControls();
194                mDownloadingLabel.setVisibility(View.GONE);
195                mDownloadButton.setVisibility(View.VISIBLE);
196                mDownloadButton.setOnClickListener(new OnClickListener() {
197                    public void onClick(View v) {
198                        mDownloadingLabel.setVisibility(View.VISIBLE);
199                        mDownloadButton.setVisibility(View.GONE);
200                        Intent intent = new Intent(mContext, TransactionService.class);
201                        intent.putExtra(TransactionBundle.URI, msgItem.mMessageUri.toString());
202                        intent.putExtra(TransactionBundle.TRANSACTION_TYPE,
203                                Transaction.RETRIEVE_TRANSACTION);
204                        mContext.startService(intent);
205                    }
206                });
207                break;
208        }
209
210        // Hide the error indicator.
211        mRightStatusIndicator.setVisibility(View.GONE);
212
213        drawLeftStatusIndicator(msgItem.mBoxId);
214    }
215
216    private void bindCommonMessage(final MessageListAdapter.AvatarCache avatarCache, final MessageItem msgItem) {
217        if (mDownloadButton != null) {
218            mDownloadButton.setVisibility(View.GONE);
219            mDownloadingLabel.setVisibility(View.GONE);
220        }
221        // Since the message text should be concatenated with the sender's
222        // address(or name), I have to display it here instead of
223        // displaying it by the Presenter.
224        mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
225
226        String addr = null;
227        if (!Sms.isOutgoingFolder(msgItem.mBoxId)) {
228            addr = msgItem.mAddress;
229        } else {
230            addr = MmsApp.getApplication().getTelephonyManager().getLine1Number();
231        }
232        if (!TextUtils.isEmpty(addr)) {
233            MessageListAdapter.AvatarCache.ContactData contactData = avatarCache.get(addr);
234            mAvatar.setImageDrawable(contactData.getAvatar());
235            mAvatar.assignContactUri(contactData.getContactUri());
236        } else {
237            mAvatar.setImageDrawable(null);
238            mAvatar.assignContactUri(null);
239        }
240
241        // Get and/or lazily set the formatted message from/on the
242        // MessageItem.  Because the MessageItem instances come from a
243        // cache (currently of size ~50), the hit rate on avoiding the
244        // expensive formatMessage() call is very high.
245        CharSequence formattedMessage = msgItem.getCachedFormattedMessage();
246        if (formattedMessage == null) {
247            formattedMessage = formatMessage(msgItem.mContact, msgItem.mBody,
248                                             msgItem.mSubject, msgItem.mTimestamp,
249                                             msgItem.mHighlight);
250            msgItem.setCachedFormattedMessage(formattedMessage);
251        }
252        mBodyTextView.setText(formattedMessage);
253
254        if (msgItem.isSms()) {
255            hideMmsViewIfNeeded();
256        } else {
257            Presenter presenter = PresenterFactory.getPresenter(
258                    "MmsThumbnailPresenter", mContext,
259                    this, msgItem.mSlideshow);
260            presenter.present();
261
262            if (msgItem.mAttachmentType != WorkingMessage.TEXT) {
263                inflateMmsView();
264                mMmsView.setVisibility(View.VISIBLE);
265                setOnClickListener(msgItem);
266                drawPlaybackButton(msgItem);
267            } else {
268                hideMmsViewIfNeeded();
269            }
270        }
271
272        drawLeftStatusIndicator(msgItem.mBoxId);
273        drawRightStatusIndicator(msgItem);
274    }
275
276    private void hideMmsViewIfNeeded() {
277        if (mMmsView != null) {
278            mMmsView.setVisibility(View.GONE);
279        }
280    }
281
282    public void startAudio() {
283        // TODO Auto-generated method stub
284    }
285
286    public void startVideo() {
287        // TODO Auto-generated method stub
288    }
289
290    public void setAudio(Uri audio, String name, Map<String, ?> extras) {
291        // TODO Auto-generated method stub
292    }
293
294    public void setImage(String name, Bitmap bitmap) {
295        inflateMmsView();
296
297        if (null == bitmap) {
298            bitmap = BitmapFactory.decodeResource(getResources(),
299                    R.drawable.ic_missing_thumbnail_picture);
300        }
301        mImageView.setImageBitmap(bitmap);
302        mImageView.setVisibility(VISIBLE);
303    }
304
305    private void inflateMmsView() {
306        if (mMmsView == null) {
307            //inflate the surrounding view_stub
308            findViewById(R.id.mms_layout_view_stub).setVisibility(VISIBLE);
309
310            mMmsView = findViewById(R.id.mms_view);
311            mImageView = (ImageView) findViewById(R.id.image_view);
312            mSlideShowButton = (ImageButton) findViewById(R.id.play_slideshow_button);
313        }
314    }
315
316    private void inflateDownloadControls() {
317        if (mDownloadButton == null) {
318            //inflate the download controls
319            findViewById(R.id.mms_downloading_view_stub).setVisibility(VISIBLE);
320            mDownloadButton = (Button) findViewById(R.id.btn_download_msg);
321            mDownloadingLabel = (TextView) findViewById(R.id.label_downloading);
322        }
323    }
324
325    private LeadingMarginSpan mLeadingMarginSpan;
326
327    private LineHeightSpan mSpan = new LineHeightSpan() {
328        public void chooseHeight(CharSequence text, int start,
329                int end, int spanstartv, int v, FontMetricsInt fm) {
330            fm.ascent -= 10;
331        }
332    };
333
334    TextAppearanceSpan mTextSmallSpan =
335        new TextAppearanceSpan(mContext, android.R.style.TextAppearance_Small);
336
337    ForegroundColorSpan mColorSpan = null;  // set in ctor
338
339    private CharSequence formatMessage(String contact, String body, String subject,
340                                       String timestamp, Pattern highlight) {
341        CharSequence template = mContext.getResources().getText(R.string.name_colon);
342        SpannableStringBuilder buf =
343            new SpannableStringBuilder(TextUtils.replace(template,
344                new String[] { "%s" },
345                new CharSequence[] { contact }));
346
347        boolean hasSubject = !TextUtils.isEmpty(subject);
348        if (hasSubject) {
349            buf.append(mContext.getResources().getString(R.string.inline_subject, subject));
350        }
351
352        if (!TextUtils.isEmpty(body)) {
353            if (hasSubject) {
354                buf.append(" - ");
355            }
356            SmileyParser parser = SmileyParser.getInstance();
357            buf.append(parser.addSmileySpans(body));
358        }
359        if (!TextUtils.isEmpty(timestamp)) {
360            buf.append("\n");
361            int startOffset = buf.length();
362
363            startOffset = buf.length();
364            buf.append(timestamp);
365
366            buf.setSpan(mTextSmallSpan, startOffset, buf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
367            buf.setSpan(mSpan, startOffset+1, buf.length(), 0);
368
369            // Make the timestamp text not as dark
370            buf.setSpan(mColorSpan, startOffset, buf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
371        }
372        if (highlight != null) {
373            Matcher m = highlight.matcher(buf.toString());
374            while (m.find()) {
375                buf.setSpan(new StyleSpan(Typeface.BOLD), m.start(), m.end(), 0);
376            }
377        }
378        buf.setSpan(mLeadingMarginSpan, 0, buf.length(), 0);
379        return buf;
380    }
381
382    private void drawPlaybackButton(MessageItem msgItem) {
383        switch (msgItem.mAttachmentType) {
384            case WorkingMessage.SLIDESHOW:
385            case WorkingMessage.AUDIO:
386            case WorkingMessage.VIDEO:
387                // Show the 'Play' button and bind message info on it.
388                mSlideShowButton.setTag(msgItem);
389                // Set call-back for the 'Play' button.
390                mSlideShowButton.setOnClickListener(this);
391                mSlideShowButton.setVisibility(View.VISIBLE);
392                setLongClickable(true);
393
394                // When we show the mSlideShowButton, this list item's onItemClickListener doesn't
395                // get called. (It gets set in ComposeMessageActivity:
396                // mMsgListView.setOnItemClickListener) Here we explicitly set the item's
397                // onClickListener. It allows the item to respond to embedded html links and at the
398                // same time, allows the slide show play button to work.
399                setOnClickListener(new OnClickListener() {
400                    public void onClick(View v) {
401                        onMessageListItemClick();
402                    }
403                });
404                break;
405            default:
406                mSlideShowButton.setVisibility(View.GONE);
407                break;
408        }
409    }
410
411    // OnClick Listener for the playback button
412    public void onClick(View v) {
413        MessageItem mi = (MessageItem) v.getTag();
414        switch (mi.mAttachmentType) {
415            case WorkingMessage.VIDEO:
416            case WorkingMessage.AUDIO:
417            case WorkingMessage.SLIDESHOW:
418                MessageUtils.viewMmsMessageAttachment(mContext, mi.mMessageUri, mi.mSlideshow);
419                break;
420        }
421    }
422
423    public void onMessageListItemClick() {
424        URLSpan[] spans = mBodyTextView.getUrls();
425
426        if (spans.length == 0) {
427            // Do nothing.
428        } else if (spans.length == 1) {
429            Uri uri = Uri.parse(spans[0].getURL());
430            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
431            intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName());
432            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
433            mContext.startActivity(intent);
434        } else {
435            final java.util.ArrayList<String> urls = MessageUtils.extractUris(spans);
436
437            ArrayAdapter<String> adapter =
438                new ArrayAdapter<String>(mContext, android.R.layout.select_dialog_item, urls) {
439                public View getView(int position, View convertView, ViewGroup parent) {
440                    View v = super.getView(position, convertView, parent);
441                    try {
442                        String url = getItem(position).toString();
443                        TextView tv = (TextView) v;
444                        Drawable d = mContext.getPackageManager().getActivityIcon(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
445                        if (d != null) {
446                            d.setBounds(0, 0, d.getIntrinsicHeight(), d.getIntrinsicHeight());
447                            tv.setCompoundDrawablePadding(10);
448                            tv.setCompoundDrawables(d, null, null, null);
449                        }
450                        final String telPrefix = "tel:";
451                        if (url.startsWith(telPrefix)) {
452                            url = PhoneNumberUtils.formatNumber(url.substring(telPrefix.length()));
453                        }
454                        tv.setText(url);
455                    } catch (android.content.pm.PackageManager.NameNotFoundException ex) {
456                        ;
457                    }
458                    return v;
459                }
460            };
461
462            AlertDialog.Builder b = new AlertDialog.Builder(mContext);
463
464            DialogInterface.OnClickListener click = new DialogInterface.OnClickListener() {
465                public final void onClick(DialogInterface dialog, int which) {
466                    if (which >= 0) {
467                        Uri uri = Uri.parse(urls.get(which));
468                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
469                        intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName());
470                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
471                        mContext.startActivity(intent);
472                    }
473                }
474            };
475
476            b.setTitle(R.string.select_link_title);
477            b.setCancelable(true);
478            b.setAdapter(adapter, click);
479
480            b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
481                public final void onClick(DialogInterface dialog, int which) {
482                    dialog.dismiss();
483                }
484            });
485
486            b.show();
487        }
488    }
489
490
491    private void setOnClickListener(final MessageItem msgItem) {
492        switch(msgItem.mAttachmentType) {
493        case WorkingMessage.IMAGE:
494        case WorkingMessage.VIDEO:
495            mImageView.setOnClickListener(new OnClickListener() {
496                public void onClick(View v) {
497                    MessageUtils.viewMmsMessageAttachment(mContext, null, msgItem.mSlideshow);
498                }
499            });
500            mImageView.setOnLongClickListener(new OnLongClickListener() {
501                public boolean onLongClick(View v) {
502                    return v.showContextMenu();
503                }
504            });
505            break;
506
507        default:
508            mImageView.setOnClickListener(null);
509            break;
510        }
511    }
512
513    private void drawLeftStatusIndicator(int msgBoxId) {
514        switch (msgBoxId) {
515            case Mms.MESSAGE_BOX_INBOX:
516                mMsgListItem.setBackgroundResource(R.drawable.listitem_background_lightblue);
517                break;
518
519            case Mms.MESSAGE_BOX_DRAFTS:
520            case Sms.MESSAGE_TYPE_FAILED:
521            case Sms.MESSAGE_TYPE_QUEUED:
522            case Mms.MESSAGE_BOX_OUTBOX:
523                mMsgListItem.setBackgroundResource(R.drawable.listitem_background);
524                break;
525
526            default:
527                mMsgListItem.setBackgroundResource(R.drawable.listitem_background);
528                break;
529        }
530    }
531
532    public static boolean isFailedMessage(MessageItem msgItem) {
533        boolean isFailedMms = msgItem.isMms()
534                            && (msgItem.mErrorType >= MmsSms.ERR_TYPE_GENERIC_PERMANENT);
535        boolean isFailedSms = msgItem.isSms()
536                            && (msgItem.mBoxId == Sms.MESSAGE_TYPE_FAILED);
537        return isFailedMms || isFailedSms;
538    }
539
540    private void setErrorIndicatorClickListener(final MessageItem msgItem) {
541        String type = msgItem.mType;
542        final int what;
543        if (type.equals("sms")) {
544            what = MSG_LIST_EDIT_SMS;
545        } else {
546            what = MSG_LIST_EDIT_MMS;
547        }
548        mRightStatusIndicator.setOnClickListener(new OnClickListener() {
549            public void onClick(View v) {
550                if (null != mHandler) {
551                    Message msg = Message.obtain(mHandler, what);
552                    msg.obj = new Long(msgItem.mMsgId);
553                    msg.sendToTarget();
554                }
555            }
556        });
557    }
558
559    private void drawRightStatusIndicator(MessageItem msgItem) {
560        if (msgItem.isOutgoingMessage()) {
561            if (isFailedMessage(msgItem)) {
562                mRightStatusIndicator.setImageResource(R.drawable.ic_sms_mms_not_delivered);
563                setErrorIndicatorClickListener(msgItem);
564            } else {
565                mRightStatusIndicator.setImageResource(R.drawable.ic_email_pending);
566            }
567            mRightStatusIndicator.setVisibility(View.VISIBLE);
568        } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.INFO || msgItem.mReadReport) {
569            mRightStatusIndicator.setImageResource(R.drawable.ic_mms_message_details);
570            mRightStatusIndicator.setVisibility(View.VISIBLE);
571        } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.PENDING) {
572            mRightStatusIndicator.setImageResource(R.drawable.ic_sms_mms_pending);
573            mRightStatusIndicator.setVisibility(View.VISIBLE);
574        } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.FAILED) {
575            mRightStatusIndicator.setImageResource(R.drawable.ic_sms_mms_not_delivered);
576            mRightStatusIndicator.setVisibility(View.VISIBLE);
577        } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.RECEIVED) {
578            mRightStatusIndicator.setImageResource(R.drawable.ic_sms_mms_delivered);
579            mRightStatusIndicator.setVisibility(View.VISIBLE);
580        } else if (msgItem.mLocked) {
581            mRightStatusIndicator.setImageResource(R.drawable.ic_lock_message_sms);
582            mRightStatusIndicator.setVisibility(View.VISIBLE);
583        } else {
584            mRightStatusIndicator.setVisibility(View.GONE);
585        }
586    }
587
588    public void setImageRegionFit(String fit) {
589        // TODO Auto-generated method stub
590    }
591
592    public void setImageVisibility(boolean visible) {
593        // TODO Auto-generated method stub
594    }
595
596    public void setText(String name, String text) {
597        // TODO Auto-generated method stub
598    }
599
600    public void setTextVisibility(boolean visible) {
601        // TODO Auto-generated method stub
602    }
603
604    public void setVideo(String name, Uri video) {
605        inflateMmsView();
606        Bitmap bitmap = VideoAttachmentView.createVideoThumbnail(mContext, video);
607        if (null == bitmap) {
608            bitmap = BitmapFactory.decodeResource(getResources(),
609                    R.drawable.ic_missing_thumbnail_video);
610        }
611        mImageView.setImageBitmap(bitmap);
612        mImageView.setVisibility(VISIBLE);
613    }
614
615    public void setVideoVisibility(boolean visible) {
616        // TODO Auto-generated method stub
617    }
618
619    public void stopAudio() {
620        // TODO Auto-generated method stub
621    }
622
623    public void stopVideo() {
624        // TODO Auto-generated method stub
625    }
626
627    public void reset() {
628        if (mImageView != null) {
629            mImageView.setVisibility(GONE);
630        }
631    }
632
633    public void setVisibility(boolean visible) {
634        // TODO Auto-generated method stub
635    }
636
637    public void pauseAudio() {
638        // TODO Auto-generated method stub
639
640    }
641
642    public void pauseVideo() {
643        // TODO Auto-generated method stub
644
645    }
646
647    public void seekAudio(int seekTo) {
648        // TODO Auto-generated method stub
649
650    }
651
652    public void seekVideo(int seekTo) {
653        // TODO Auto-generated method stub
654
655    }
656}
657