org.deviceconnect.android.deviceplugin.chromecast.profile.ChromeCastMediaPlayerProfile.java Source code

Java tutorial

Introduction

Here is the source code for org.deviceconnect.android.deviceplugin.chromecast.profile.ChromeCastMediaPlayerProfile.java

Source

/*
 ChromeCastMediaPlayerProfile.java
 Copyright (c) 2014 NTT DOCOMO,INC.
 Released under the MIT license
 http://opensource.org/licenses/mit-license.php
 */
package org.deviceconnect.android.deviceplugin.chromecast.profile;

import java.io.File;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import org.apache.http.conn.util.InetAddressUtils;
import org.deviceconnect.android.deviceplugin.chromecast.BuildConfig;
import org.deviceconnect.android.deviceplugin.chromecast.ChromeCastService;
import org.deviceconnect.android.deviceplugin.chromecast.core.ChromeCastHttpServer;
import org.deviceconnect.android.deviceplugin.chromecast.core.ChromeCastMediaPlayer;
import org.deviceconnect.android.event.EventError;
import org.deviceconnect.android.event.EventManager;
import org.deviceconnect.android.message.MessageUtils;
import org.deviceconnect.android.profile.MediaPlayerProfile;
import org.deviceconnect.message.DConnectMessage;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.webkit.MimeTypeMap;

import com.google.android.gms.cast.MediaMetadata;
import com.google.android.gms.cast.MediaStatus;

/**
 * MediaPlayer  (Chromecast)
 * <p>
 * Chromecast?????
 * </p>
 * @author NTT DOCOMO, INC.
 */
public class ChromeCastMediaPlayerProfile extends MediaPlayerProfile {

    private static final int ERROR_VALUE_IS_NULL = 100;
    private static final String MESSAGE_BUFFERING = "buffering";
    private static final String MESSAGE_IDLE = "stop";
    private static final String MESSAGE_PAUSED = "pause";
    private static final String MESSAGE_PALYING = "play";
    private static final String MESSAGE_UNKNOWN = "unknown";
    private static final String ERROR_MESSAGE_DEVICE_NOT_ENABLE = "Device is not enable";
    private static final String ERROR_MESSAGE_MEDIA_NOT_SELECTED = "Media is not selected";
    private static final String ERROR_MESSAGE_PLAYSTATE_IS_NOT = "Playstate is not";
    private static final String ERROR_MESSAGE_MEDIA_PLAY = ERROR_MESSAGE_PLAYSTATE_IS_NOT + " " + MESSAGE_IDLE
            + " or " + MESSAGE_PAUSED;
    private static final String ERROR_MESSAGE_MEDIA_RESUME = ERROR_MESSAGE_PLAYSTATE_IS_NOT + " " + MESSAGE_PAUSED;
    private static final String ERROR_MESSAGE_MEDIA_STOP = ERROR_MESSAGE_PLAYSTATE_IS_NOT + " " + MESSAGE_PALYING
            + " or " + MESSAGE_PAUSED + " or " + MESSAGE_BUFFERING;
    private static final String ERROR_MESSAGE_MEDIA_PAUSE = ERROR_MESSAGE_PLAYSTATE_IS_NOT + " " + MESSAGE_PALYING;
    private static final String ERROR_MESSAGE_MEDIA_MUTE = ERROR_MESSAGE_PLAYSTATE_IS_NOT + " " + MESSAGE_PALYING
            + " or " + MESSAGE_PAUSED;
    private static final String ERROR_MESSAGE_MEDIA_VOLUME = ERROR_MESSAGE_MEDIA_MUTE;
    private static final String ERROR_MESSAGE_MEDIA_SEEK = ERROR_MESSAGE_MEDIA_MUTE;
    private String mMediaId = null;

    /**
     * ????
     * 
     * @param   playState   ?
     * @return  ???
     */
    public String getPlayStatus(int playState) {
        switch (playState) {
        case MediaStatus.PLAYER_STATE_BUFFERING:
            return MESSAGE_BUFFERING;
        case MediaStatus.PLAYER_STATE_IDLE:
            return MESSAGE_IDLE;
        case MediaStatus.PLAYER_STATE_PAUSED:
            return MESSAGE_PAUSED;
        case MediaStatus.PLAYER_STATE_PLAYING:
            return MESSAGE_PALYING;
        case MediaStatus.PLAYER_STATE_UNKNOWN:
        default:
            return MESSAGE_UNKNOWN;
        }
    }

    /**
     * ?ChromeCastMediaPlayer??
     * @param   ??
     * @return  ChromeCastMediaPlayer
     */
    private ChromeCastMediaPlayer getChromeCastApplication() {
        return ((ChromeCastService) getContext()).getChromeCastMediaPlayer();
    }

    /**
     * ??????<br/>
     * ????????
     * 
     * @param   response    ?
     * @param   app         ChromeCastMediaPlayer
     * @return  ?????: true, : false
     */
    private boolean isDeviceEnable(final Intent response, ChromeCastMediaPlayer app) {
        if (!app.isDeviceEnable()) {
            MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_DEVICE_NOT_ENABLE);
            setResult(response, DConnectMessage.RESULT_ERROR);
            return false;
        }
        return true;
    }

    /**
     * ???
     * @param   response    ?
     * @param   app         ChromeCastMediaPlayer
     * @return  ?????: true, : false
     */
    private MediaStatus getMediaStatus(final Intent response, ChromeCastMediaPlayer app) {
        MediaStatus status = app.getMediaStatus();
        if (status == null) {
            MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_MEDIA_NOT_SELECTED);
            setResult(response, DConnectMessage.RESULT_ERROR);
        }
        return status;
    }

    @Override
    protected boolean onPutPlay(final Intent request, final Intent response, final String deviceId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        MediaStatus status = getMediaStatus(response, app);
        if (status == null)
            return true;

        if (status.getPlayerState() == MediaStatus.PLAYER_STATE_IDLE) {
            app.play(response);
            return false;
        } else if (status.getPlayerState() == MediaStatus.PLAYER_STATE_PAUSED) {
            app.resume(response);
            return false;
        } else {
            MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_MEDIA_PLAY);
            setResult(response, DConnectMessage.RESULT_ERROR);
            return true;
        }
    }

    @Override
    protected boolean onPutResume(final Intent request, final Intent response, final String deviceId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        MediaStatus status = getMediaStatus(response, app);
        if (status == null)
            return true;

        if (status.getPlayerState() == MediaStatus.PLAYER_STATE_PAUSED) {
            app.resume(response);
            return false;
        } else {
            MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_MEDIA_RESUME);
            setResult(response, DConnectMessage.RESULT_ERROR);
            return true;
        }
    }

    @Override
    protected boolean onPutStop(final Intent request, final Intent response, final String deviceId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        MediaStatus status = getMediaStatus(response, app);
        if (status == null)
            return true;

        if (status.getPlayerState() == MediaStatus.PLAYER_STATE_PLAYING
                || status.getPlayerState() == MediaStatus.PLAYER_STATE_PAUSED
                || status.getPlayerState() == MediaStatus.PLAYER_STATE_BUFFERING) {
            app.stop(response);
            return false;
        } else {
            MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_MEDIA_STOP);
            setResult(response, DConnectMessage.RESULT_ERROR);
            return true;
        }
    }

    @Override
    protected boolean onPutPause(final Intent request, final Intent response, final String deviceId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        MediaStatus status = getMediaStatus(response, app);
        if (status == null)
            return true;

        if (status.getPlayerState() == MediaStatus.PLAYER_STATE_PLAYING) {
            app.pause(response);
            return false;
        } else {
            MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_MEDIA_PAUSE);
            setResult(response, DConnectMessage.RESULT_ERROR);
            return true;
        }
    }

    /**
     * ?<br/>
     * ??????
     * 
     * @param   request     
     * @param   response    ?
     * @param   deviceId    ?ID
     * @param   mute        ????true: ON, false: OFF
     * @return  result      ??true: ?, false: 
     */
    private boolean setMute(final Intent request, final Intent response, final String deviceId, boolean mute) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        MediaStatus status = getMediaStatus(response, app);
        if (status == null)
            return true;
        if (status.getPlayerState() == MediaStatus.PLAYER_STATE_PLAYING
                || status.getPlayerState() == MediaStatus.PLAYER_STATE_PAUSED) {
            app.setMute(response, mute);
            return false;
        } else {
            MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_MEDIA_MUTE);
            setResult(response, DConnectMessage.RESULT_ERROR);
            return true;
        }
    }

    @Override
    protected boolean onPutMute(final Intent request, final Intent response, final String deviceId) {
        return setMute(request, response, deviceId, true);
    }

    @Override
    protected boolean onDeleteMute(final Intent request, final Intent response, final String deviceId) {
        return setMute(request, response, deviceId, false);
    }

    @Override
    protected boolean onGetMute(final Intent request, final Intent response, final String deviceId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        if (getMediaStatus(response, app) == null)
            return true;

        int mute = app.getMute(response);
        if (mute == 1) {
            setMute(response, true);
            setResult(response, DConnectMessage.RESULT_OK);
            return true;
        } else if (mute == 0) {
            setMute(response, false);
            setResult(response, DConnectMessage.RESULT_OK);
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected boolean onPutVolume(final Intent request, final Intent response, final String deviceId,
            final Double volume) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        MediaStatus status = getMediaStatus(response, app);
        if (status == null)
            return true;

        if (volume == null) {
            MessageUtils.setInvalidRequestParameterError(response);
        } else if (0.0 > volume || volume > 1.0) {
            MessageUtils.setInvalidRequestParameterError(response);
        } else {
            if (status.getPlayerState() == MediaStatus.PLAYER_STATE_PLAYING
                    || status.getPlayerState() == MediaStatus.PLAYER_STATE_PAUSED) {
                app.setVolume(response, volume);
                return false;
            } else {
                MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_MEDIA_VOLUME);
                setResult(response, DConnectMessage.RESULT_ERROR);
                return true;
            }
        }
        return true;
    }

    @Override
    protected boolean onGetVolume(final Intent request, final Intent response, final String deviceId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        if (getMediaStatus(response, app) == null)
            return true;

        double volume = app.getVolume(response);
        if (volume >= 0) {
            setVolume(response, volume);
            setResult(response, DConnectMessage.RESULT_OK);
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected boolean onPutSeek(final Intent request, final Intent response, final String deviceId,
            final Integer pos) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;

        if (pos == null) {
            MessageUtils.setInvalidRequestParameterError(response);
            return true;
        } else {
            MediaStatus status = getMediaStatus(response, app);
            if (status == null)
                return true;

            long posMillisecond = pos * 1000;
            if (0 > posMillisecond || posMillisecond > status.getMediaInfo().getStreamDuration()) {
                MessageUtils.setInvalidRequestParameterError(response);
                return true;
            }

            if (status.getPlayerState() == MediaStatus.PLAYER_STATE_PLAYING
                    || status.getPlayerState() == MediaStatus.PLAYER_STATE_PAUSED) {
                app.setSeek(response, posMillisecond);
                return false;
            } else {
                MessageUtils.setIllegalDeviceStateError(response, ERROR_MESSAGE_MEDIA_SEEK);
                setResult(response, DConnectMessage.RESULT_ERROR);
                return true;
            }
        }
    }

    @Override
    protected boolean onGetSeek(final Intent request, final Intent response, final String deviceId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;
        if (getMediaStatus(response, app) == null)
            return true;

        long posSecond = app.getSeek(response) / 1000;
        if (posSecond >= 0) {
            setPos(response, (int) posSecond);
            setResult(response, DConnectMessage.RESULT_OK);
            return true;
        } else {
            return false;
        }
    }

    @Override
    protected boolean onGetPlayStatus(final Intent request, final Intent response, final String deviceId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;

        MediaStatus status = getMediaStatus(response, app);
        if (status == null)
            return true;
        String playStatus = getPlayStatus(status.getPlayerState());
        response.putExtra(MediaPlayerProfile.PARAM_STATUS, playStatus);
        setResult(response, DConnectMessage.RESULT_OK);
        return true;
    }

    @Override
    protected boolean onGetMedia(final Intent request, final Intent response, final String deviceId,
            final String mediaId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;

        MediaStatus status = getMediaStatus(response, app);
        if (status == null)
            return true;
        String playStatus = getPlayStatus(status.getPlayerState());
        response.putExtra(DConnectMessage.EXTRA_RESULT, DConnectMessage.RESULT_OK);
        response.putExtra(MediaPlayerProfile.PARAM_MIME_TYPE, status.getMediaInfo().getContentType());
        response.putExtra(MediaPlayerProfile.PARAM_TITLE,
                status.getMediaInfo().getMetadata().getString(MediaMetadata.KEY_TITLE));
        response.putExtra(MediaPlayerProfile.PARAM_MEDIA_ID, this.mMediaId);
        response.putExtra(MediaPlayerProfile.PARAM_DURATION, status.getMediaInfo().getStreamDuration() / 1000);
        response.putExtra(MediaPlayerProfile.PARAM_POS, status.getStreamPosition() / 1000);
        response.putExtra(MediaPlayerProfile.PARAM_STATUS, playStatus);

        setResult(response, DConnectMessage.RESULT_OK);
        return true;
    }

    /**
     * MD5???
     * 
     * @param   str     
     * @return  result  MD5   
     */
    private String getMd5(String str) {
        String result = null;
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(str.getBytes());
            byte[] hash = digest.digest();
            StringBuffer hex = new StringBuffer();
            for (int i = 0; i < hash.length; i++)
                hex.append(Integer.toHexString(0xFF & hash[i]));
            result = hex.toString();
        } catch (Exception e) {
            if (BuildConfig.DEBUG) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * URL??<br/>
     * ??URL????????
     */
    private class ThreadCheckURL extends Thread {
        private String value;
        private boolean result = false;
        private String message = null;

        public ThreadCheckURL(String url) {
            value = url;
        }

        @Override
        public void run() {
            if (value == null) {
                message = "url is null";
                return;
            }
            try {
                HttpURLConnection con = (HttpURLConnection) (new URL(value)).openConnection();
                con.connect();
                con.disconnect();
                result = true;
            } catch (Exception e) {
                if (BuildConfig.DEBUG) {
                    e.printStackTrace();
                }
                message = e.getMessage();
            }
        }

        public boolean getValue() {
            return this.result;
        }

        public String getMessage() {
            return this.message;
        }
    }

    /**
     * ??URI?key?value?????Cursor??
     * 
     * @param   uri     URI
     * @param   key     
     * @param   value   ?
     * @return  cursor  
     */
    private Cursor getCursorFrom(Uri uri, String key, String value) {
        Cursor cursor = getContext().getApplicationContext().getContentResolver().query(uri, null,
                key + "=" + value + "", null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                if (cursor.getCount() == 1) {
                    return cursor;
                }
                cursor.close();
            }
        }
        return null;
    }

    /**
     * mediaId?dummyUrl??
     * 
     * @param   mediaId     ID
     * @return  dummyUrl    URL
     */
    private String getDummyUrlFromMediaId(int mediaId) {
        Uri targetUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        String path = getPathFromUri(ContentUris.withAppendedId(targetUri, Long.valueOf(mediaId)));

        if (path == null) {
            return null;
        }

        ChromeCastHttpServer server = ((ChromeCastService) getContext()).getChromeCastHttpServer();
        String dir = new File(path).getParent();
        String realName = new File(path).getName();
        String extension = MimeTypeMap.getFileExtensionFromUrl(realName);
        String dummyName = getMd5("" + System.currentTimeMillis()) + "." + extension;

        server.setFilePath(dir, realName, "/" + dummyName);
        return "http://" + getIpAddress() + ":" + server.getListeningPort() + "/" + dummyName;
    }

    @Override
    protected boolean onPutMedia(final Intent request, final Intent response, final String deviceId,
            final String mediaId) {
        ChromeCastMediaPlayer app = getChromeCastApplication();
        if (!isDeviceEnable(response, app))
            return true;

        String url = null;
        String title = null;
        Integer mId = -1;

        if (mediaId == null) {
            response.putExtra(DConnectMessage.EXTRA_VALUE, "mediaId is null");
            setResult(response, DConnectMessage.RESULT_ERROR);
            return true;
        }

        try {
            mId = Integer.parseInt(mediaId);
        } catch (Exception e) {
            url = mediaId;
        }

        if (url != null) {
            this.mMediaId = mediaId;
        } else {
            Cursor cursor = getCursorFrom(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, MediaStore.Video.Media._ID,
                    mediaId);
            if (cursor == null) {
                response.putExtra(DConnectMessage.EXTRA_VALUE, "mediaId is not exist");
                setResult(response, DConnectMessage.RESULT_ERROR);
                return true;
            } else {
                title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE));
                url = getDummyUrlFromMediaId(mId);
                cursor.close();
            }
            this.mMediaId = mId.toString();
        }

        ThreadCheckURL thread = new ThreadCheckURL(url);
        thread.start();
        try {
            thread.join(3000);
            if (!thread.getValue()) {
                response.putExtra(DConnectMessage.EXTRA_VALUE, thread.getMessage());
                setResult(response, DConnectMessage.RESULT_ERROR);
                return true;
            }
        } catch (InterruptedException e) {
            if (BuildConfig.DEBUG) {
                e.printStackTrace();
            }
            response.putExtra(DConnectMessage.EXTRA_VALUE, e.getMessage());
            setResult(response, DConnectMessage.RESULT_ERROR);
            return true;
        }

        if (title == null)
            title = "TITLE";

        app.load(response, url, title);

        return false;
    }

    /**
     * IP??
     * 
     * @param   ??
     * @return  IP
     */
    private String getIpAddress() {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = (NetworkInterface) networkInterfaces.nextElement();
                Enumeration<InetAddress> ipAddrs = networkInterface.getInetAddresses();
                while (ipAddrs.hasMoreElements()) {
                    InetAddress ip = (InetAddress) ipAddrs.nextElement();
                    String ipStr = ip.getHostAddress();
                    if (!ip.isLoopbackAddress() && InetAddressUtils.isIPv4Address(ipStr)) {
                        return ipStr;
                    }
                }
            }
        } catch (SocketException e) {
            if (BuildConfig.DEBUG) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Uri???
     * 
     * @param   mUri    Uri
     * @return  
     */
    private String getPathFromUri(final Uri mUri) {
        try {
            String filename = null;
            Cursor c = this.getContext().getContentResolver().query(mUri, null, null, null, null);
            if (c != null) {
                c.moveToFirst();
                filename = c.getString(c.getColumnIndex(MediaStore.MediaColumns.DATA));
                c.close();
            }
            return filename;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * bundle??
     * 
     * @param   MediaType   
     * @param   Bundle      ?
     * @param   Cursor      
     * @return  ??
     */
    private void setMediaInformation(String MediaType, Bundle bundle, Cursor cursor) {
        if (MediaType.equals("Video")) {
            setType(bundle, MediaType);
            setLanguage(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.LANGUAGE)));
            setMediaId(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media._ID)));
            setMIMEType(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.MIME_TYPE)));
            setTitle(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE)));
            setDuration(bundle, cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.DURATION)));
            Bundle creator = new Bundle();
            setCreator(creator, cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.ARTIST)));
            setCreators(bundle, new Bundle[] { creator });

        } else if (MediaType.equals("Audio")) {
            setType(bundle, "Music");
            setMediaId(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media._ID)));
            setMIMEType(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.MIME_TYPE)));
            setTitle(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)));
            setDuration(bundle, cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)));
            Bundle creator = new Bundle();
            setCreator(creator, cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
            setRole(creator, cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.COMPOSER)));
            setCreators(bundle, new Bundle[] { creator });

        } else if (MediaType.equals("Image")) {
            setType(bundle, MediaType);
            setMediaId(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID)));
            setMIMEType(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.MIME_TYPE)));
            setTitle(bundle, cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.TITLE)));
            Bundle creator = new Bundle();
            setCreators(bundle, new Bundle[] { creator });
        } else {
            setType(bundle, MediaType);
        }
    }

    /**
     * ?
     * 
     * @param   mediaType   
     * @param   list        
     * @param   filter      
     * @param   orderBy     
     * @return  ??
     */
    private void listupMedia(String mediaType, List<Bundle> list, String filter, String orderBy) {
        Uri uriType = null;

        if (mediaType.equals("Video"))
            uriType = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        else if (mediaType.equals("Audio"))
            uriType = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        else if (mediaType.equals("Image"))
            uriType = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

        ContentResolver mContentResolver = this.getContext().getApplicationContext().getContentResolver();
        Cursor cursorVideo = mContentResolver.query(uriType, null, filter, null, orderBy);
        if (cursorVideo != null) {
            cursorVideo.moveToFirst();
            if (cursorVideo.getCount() > 0) {
                do {
                    Bundle medium = new Bundle();
                    setMediaInformation(mediaType, medium, cursorVideo);
                    list.add(medium);
                } while (cursorVideo.moveToNext());
            }
            cursorVideo.close();
        }
    }

    /**
     * ?
     * 
     * @param   mediaType   
     * @param   list        
     * @param   query       
     * @param   mimeType    MIME
     * @param   orders      
     * @return  ??
     */
    private void listupMedia(String mediaType, List<Bundle> list, String query, String mimeType, String[] orders) {
        String filter = "";
        String orderBy = "";

        if (mimeType != null) {
            String key = null;
            if (mediaType.equals("Video")) {
                key = MediaStore.Video.Media.MIME_TYPE;
            } else if (mediaType.equals("Audio")) {
                key = MediaStore.Audio.Media.MIME_TYPE;
            } else if (mediaType.equals("Image")) {
                key = MediaStore.Images.Media.MIME_TYPE;
            }
            filter = "" + key + "='" + mimeType + "'";
        }
        if (query != null) {
            if (!filter.equals("")) {
                filter += " AND ";
            }
            if (mediaType.equals("Video")) {
                filter += "(" + MediaStore.Video.Media.TITLE + " LIKE '%" + query + "%'";
            } else if (mediaType.equals("Audio")) {
                filter += "(" + MediaStore.Audio.Media.TITLE + " LIKE '%" + query + "%'";
                filter += " OR " + MediaStore.Audio.Media.COMPOSER + " LIKE '%" + query + "%')";
            } else if (mediaType.equals("Image")) {
                filter += "(" + MediaStore.Images.Media.TITLE + " LIKE '%" + query + "%'";
            }
        }

        if (orders != null) {
            orderBy = orders[0] + " " + orders[1];
        } else {
            orderBy = "title asc";
        }

        listupMedia(mediaType, list, filter, orderBy);
    }

    @Override
    protected boolean onGetMediaList(Intent request, Intent response, final String deviceId, final String query,
            final String mimeType, final String[] orders, final Integer offset, final Integer limit) {
        List<Bundle> list = new ArrayList<Bundle>();

        Bundle medium = null;
        Bundle creatorVideo = null;

        medium = new Bundle();
        setType(medium, "Video");
        setLanguage(medium, "Language");
        setMediaId(medium, "https://raw.githubusercontent.com/DeviceConnect/DeviceConnect/master/sphero_demo.MOV");
        setMIMEType(medium, "mov");
        setTitle(medium, "Title: Sample");
        setDuration(medium, 9999);
        creatorVideo = new Bundle();
        setCreator(creatorVideo, "Creator: Sample");
        setCreators(medium, new Bundle[] { creatorVideo });
        list.add(medium);

        listupMedia("Video", list, query, mimeType, orders);

        setCount(response, list.size());
        setMedia(response, list.toArray(new Bundle[list.size()]));
        setResult(response, DConnectMessage.RESULT_OK);

        return true;
    }

    @Override
    protected boolean onPutOnStatusChange(final Intent request, final Intent response, final String deviceId,
            final String sessionKey) {
        EventError error = EventManager.INSTANCE.addEvent(request);
        if (error == EventError.NONE) {
            ((ChromeCastService) getContext()).registerOnStatusChange(response, deviceId, sessionKey);
            return false;
        } else {
            MessageUtils.setError(response, ERROR_VALUE_IS_NULL, "Can not register event.");
            return true;
        }
    }

    @Override
    protected boolean onDeleteOnStatusChange(final Intent request, final Intent response, final String deviceId,
            final String sessionKey) {
        EventError error = EventManager.INSTANCE.removeEvent(request);
        if (error == EventError.NONE) {
            ((ChromeCastService) getContext()).unregisterOnStatusChange(response);
            return false;
        } else {
            MessageUtils.setError(response, ERROR_VALUE_IS_NULL, "Can not unregister event.");
            return true;
        }
    }
}