/*
ChromeCastDiscovery.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.core;
import android.content.Context;
import android.util.Log;
import com.google.android.gms.cast.CastDevice;
import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.cast.framework.CastSession;
import com.google.android.gms.cast.framework.SessionManagerListener;
import org.deviceconnect.android.deviceplugin.chromecast.BuildConfig;
import java.util.ArrayList;
/**
* Chromecast Discovery クラス.
*
* <p>
* ReceiverアプリのアプリケーションIDに対応した、Chromecastデバイスを探索する
* </p>
* @author NTT DOCOMO, INC.
*/
public class ChromeCastDiscovery {
/** 出力するログのタグ名. */
private static final String TAG = ChromeCastDiscovery.class.getSimpleName();
/** 選択されたデバイス. */
private CastDevice mSelectedDevice;
/** Chromecastとの接続状態を通知するコールバック. */
private Callbacks mCallbacks;
/** Route名のリスト. */
private ArrayList<CastDevice> mRouteNames;
/**
* Chromecastとの接続状態を通知するコールバックのインターフェース.
* @author NTT DOCOMO, INC.
*/
public interface Callbacks {
/**
* Chromecastデバイスの探索状態(発見or消失した場合)を通知する.
* @param devices デバイス名のリスト
*/
void onCastDeviceUpdate(final ArrayList<CastDevice> devices);
/**
* Chromecastデバイスが選択されたときに通知する.
*
* @param selectedDevice 選択されたデバイス
*/
void onCastDeviceSelected(final CastDevice selectedDevice);
/**
* Chromecastデバイスが非選択されたときに通知する.
* @param unselectedDevice 選択されたデバイス
*/
void onCastDeviceUnselected(final CastDevice unselectedDevice);
}
/**
* コールバックを登録する.
*
* @param callbacks コールバック
*/
public void setCallbacks(final Callbacks callbacks) {
this.mCallbacks = callbacks;
}
/**
* ChromeCastとの接続を管理する.
*/
private CastContext mCastContext;
/**
* onEndingを通るかどうか.
*/
private boolean mIsEnding;
private SessionManagerListener<CastSession> mSessionListener = new SessionManagerListener<CastSession>() {
@Override
public void onSessionStarting(CastSession castSession) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "================================>");
Log.d(TAG, "SessionManagerListener.onSessionStarting");
Log.d(TAG, "<================================");
}
synchronized (this) {
CastDevice device = castSession.getCastDevice();
if (device != null) {
mRouteNames.add(device);
}
}
mCallbacks.onCastDeviceUpdate(mRouteNames);
}
@Override
public void onSessionStarted(CastSession castSession, String s) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "================================>");
Log.d(TAG, "SessionManagerListener.onSessionStarted");
Log.d(TAG, "<================================");
}
mSelectedDevice = castSession.getCastDevice();
mCallbacks.onCastDeviceSelected(mSelectedDevice);
}
@Override
public void onSessionStartFailed(CastSession castSession, int i) {
}
@Override
public void onSessionEnding(CastSession castSession) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "================================>");
Log.d(TAG, "SessionManagerListener.onSessionEnding");
Log.d(TAG, "<================================");
}
mCallbacks.onCastDeviceUpdate(mRouteNames);
mIsEnding = true;
}
@Override
public void onSessionEnded(CastSession castSession, int i) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "================================>");
Log.d(TAG, "SessionManagerListener.onSessionEnded");
Log.d(TAG, "<================================");
}
// WiFiをOFFにしたのちにChromeCastへリクエストを送ると、onSessionEndingが呼ばれずにこのメソッドが呼ばれる。
if (mIsEnding) {
mCallbacks.onCastDeviceUnselected(mSelectedDevice);
mSelectedDevice = null;
}
mIsEnding = false;
}
@Override
public void onSessionResuming(CastSession castSession, String s) {
}
@Override
public void onSessionResumed(CastSession castSession, boolean b) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "================================>");
Log.d(TAG, "SessionManagerListener.onSessionResumed: " + b);
Log.d(TAG, "<================================");
}
mSelectedDevice = castSession.getCastDevice();
mCallbacks.onCastDeviceSelected(mSelectedDevice);
}
@Override
public void onSessionResumeFailed(CastSession castSession, int i) {
}
@Override
public void onSessionSuspended(CastSession castSession, int i) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "================================>");
Log.d(TAG, "SessionManagerListener.onSessionSuspended");
Log.d(TAG, "<================================");
}
mCallbacks.onCastDeviceUnselected(mSelectedDevice);
}
};
/**
* コンストラクタ.
* <p>
* ReceiverアプリのアプリケーションIDに対応した、Chromecastデバイスの探索を開始する.
* </p>
*
* @param context コンテキスト
*/
public ChromeCastDiscovery(final Context context) {
mCastContext = CastContext.getSharedInstance(context);
mIsEnding = false;
setListener();
mRouteNames = new ArrayList<>();
}
/**
* Listenerを登録する.
*/
private void setListener() {
mCastContext.getSessionManager().removeSessionManagerListener(mSessionListener, CastSession.class);
mCastContext.getSessionManager().addSessionManagerListener(
mSessionListener, CastSession.class);
}
/**
* 選択されたChromecastデバイスを返す.
*
* @return 選択されたデバイス
*/
public CastDevice getSelectedDevice() {
return mSelectedDevice;
}
/**
* 接続可能なChromecastデバイスのデバイス名のリストを返す.
*
* @return デバイス名のリスト
*/
public ArrayList<CastDevice> getDeviceNames() {
return mRouteNames;
}
}