/*
* WebAppSession
* Connect SDK
*
* Copyright (c) 2014 LG Electronics.
* Created by Jeffrey Glenn on 07 Mar 2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.connectsdk.service.sessions;
import com.connectsdk.core.MediaInfo;
import com.connectsdk.core.Util;
import com.connectsdk.service.DeviceService;
import com.connectsdk.service.capability.MediaControl;
import com.connectsdk.service.capability.MediaPlayer;
import com.connectsdk.service.capability.PlaylistControl;
import com.connectsdk.service.capability.listeners.ResponseListener;
import com.connectsdk.service.command.ServiceCommandError;
import com.connectsdk.service.command.ServiceSubscription;
import org.json.JSONObject;
/**
* ###Overview When a web app is launched on a first screen device, there are
* certain tasks that can be performed with that web app. WebAppSession serves
* as a second screen reference of the web app that was launched. It behaves
* similarly to LaunchSession, but is not nearly as static.
*
* ###In Depth On top of maintaining session information (contained in the
* launchSession property), WebAppSession provides access to a number of
* capabilities. - MediaPlayer - MediaControl - Bi-directional communication
* with web app
*
* MediaPlayer and MediaControl are provided to allow for the most common first
* screen use cases -- a media player (audio, video, & images).
*
* The Connect SDK JavaScript Bridge has been produced to provide normalized
* support for these capabilities across protocols (Chromecast, webOS, etc).
*/
public class WebAppSession implements MediaControl, MediaPlayer, PlaylistControl {
/** Status of the web app */
public enum WebAppStatus {
/** Web app status is unknown */
Unknown,
/** Web app is running and in the foreground */
Open,
/** Web app is running and in the background */
Background,
/** Web app is in the foreground but has not started running yet */
Foreground,
/** Web app is not running and is not in the foreground or background */
Closed
}
/**
* Success block that is called upon successfully getting a web app's status.
*
* @param status The current running & foreground status of the web app
*/
public static interface WebAppPinStatusListener extends ResponseListener<Boolean> { }
/**
* LaunchSession object containing key session information. Much of this
* information is required for web app messaging & closing the web app.
*/
public LaunchSession launchSession;
// @cond INTERNAL
protected DeviceService service;
private WebAppSessionListener webAppListener;
// @endcond
/**
* Instantiates a WebAppSession object with all the information necessary to
* interact with a web app.
*
* @param launchSession
* LaunchSession containing info about the web app session
* @param service
* DeviceService that was responsible for launching this web app
*/
public WebAppSession(LaunchSession launchSession, DeviceService service) {
this.launchSession = launchSession;
this.service = service;
}
/**
* DeviceService that was responsible for launching this web app.
*/
protected void setService(DeviceService service) {
}
/**
* Subscribes to changes in the web app's status.
*
* @param listener
* (optional) MessageListener to be called on app status change
*/
public ServiceSubscription<MessageListener> subscribeWebAppStatus(
MessageListener listener) {
if (listener != null)
listener.onError(ServiceCommandError.notSupported());
return null;
}
/**
* Establishes a communication channel with the web app.
*
* @param connectionListener
* (optional) ResponseListener to be called on success
*/
public void connect(ResponseListener<Object> connectionListener) {
Util.postError(connectionListener, ServiceCommandError.notSupported());
}
/**
* Establishes a communication channel with a currently running web app.
*
* @param connectionListener
*/
public void join(ResponseListener<Object> connectionListener) {
Util.postError(connectionListener, ServiceCommandError.notSupported());
}
/**
* Closes any open communication channel with the web app.
*/
public void disconnectFromWebApp() {
}
/**
* Pin the web app on the launcher.
*/
public void pinWebApp(String webAppId, ResponseListener<Object> listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
/**
* UnPin the web app on the launcher.
*
* @param webAppId NSString webAppId to be unpinned.
*/
public void unPinWebApp(String webAppId, ResponseListener<Object> listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
/**
* To check if the web app is pinned or not
*/
public void isWebAppPinned(String webAppId, WebAppPinStatusListener listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
/**
* Subscribe to check if the web app is pinned or not
*/
public ServiceSubscription<WebAppPinStatusListener> subscribeIsWebAppPinned(String webAppId, WebAppPinStatusListener listener) {
Util.postError(listener, ServiceCommandError.notSupported());
return null;
}
/**
* Closes the web app on the first screen device.
*
* @param listener
* (optional) ResponseListener to be called on success
*/
public void close(ResponseListener<Object> listener) {
if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
/**
* Sends a simple string to the web app. The Connect SDK JavaScript Bridge
* will receive this message and hand it off as a string object.
*
* @param listener
* (optional) ResponseListener to be called on success
*/
public void sendMessage(String message, ResponseListener<Object> listener) {
if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
/**
* Sends a JSON object to the web app. The Connect SDK JavaScript Bridge
* will receive this message and hand it off as a JavaScript object.
*
* @param success
* (optional) ResponseListener to be called on success
*/
public void sendMessage(JSONObject message,
ResponseListener<Object> listener) {
if (listener != null) {
listener.onError(ServiceCommandError.notSupported());
}
}
// @cond INTERNAL
@Override
public MediaControl getMediaControl() {
return null;
}
@Override
public CapabilityPriorityLevel getMediaControlCapabilityLevel() {
return CapabilityPriorityLevel.VERY_LOW;
}
@Override
public void getMediaInfo(MediaInfoListener listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
@Override
public ServiceSubscription<MediaInfoListener> subscribeMediaInfo(
MediaInfoListener listener) {
listener.onError(ServiceCommandError.notSupported());
return null;
}
@Override
public void play(ResponseListener<Object> listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.play(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void pause(ResponseListener<Object> listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.pause(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void stop(ResponseListener<Object> listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.stop(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void rewind(ResponseListener<Object> listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.rewind(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void fastForward(ResponseListener<Object> listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.fastForward(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void previous(ResponseListener<Object> listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.previous(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void next(ResponseListener<Object> listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.next(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void seek(long position, ResponseListener<Object> listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.seek(position, listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void getDuration(DurationListener listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.getDuration(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void getPosition(PositionListener listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.getPosition(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public void getPlayState(PlayStateListener listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
mediaControl.getPlayState(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
}
@Override
public ServiceSubscription<PlayStateListener> subscribePlayState(
PlayStateListener listener) {
MediaControl mediaControl = null;
if (service != null)
mediaControl = service.getAPI(MediaControl.class);
if (mediaControl != null)
return mediaControl.subscribePlayState(listener);
else if (listener != null)
listener.onError(ServiceCommandError.notSupported());
return null;
}
@Override
public void closeMedia(LaunchSession launchSession,
ResponseListener<Object> listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
@Override
public void displayImage(String url, String mimeType, String title,
String description, String iconSrc,
MediaPlayer.LaunchListener listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
@Override
public void displayImage(MediaInfo mediaInfo, MediaPlayer.LaunchListener listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
@Override
public void playMedia(String url, String mimeType, String title, String description, String iconSrc, boolean shouldLoop, MediaPlayer.LaunchListener listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
@Override
public void playMedia(MediaInfo mediaInfo, boolean shouldLoop,
MediaPlayer.LaunchListener listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
@Override
public MediaPlayer getMediaPlayer() {
return null;
}
@Override
public CapabilityPriorityLevel getMediaPlayerCapabilityLevel() {
return CapabilityPriorityLevel.VERY_LOW;
}
@Override
public PlaylistControl getPlaylistControl() {
return null;
}
@Override
public CapabilityPriorityLevel getPlaylistControlCapabilityLevel() {
return CapabilityPriorityLevel.VERY_LOW;
}
@Override
public void jumpToTrack(long index, ResponseListener<Object> listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
@Override
public void setPlayMode(PlayMode playMode, ResponseListener<Object> listener) {
Util.postError(listener, ServiceCommandError.notSupported());
}
// @endcond
/**
* When messages are received from a web app, they are parsed into the
* appropriate object type (string vs JSON/NSDictionary) and routed to the
* WebAppSessionListener.
*/
public WebAppSessionListener getWebAppSessionListener() {
return webAppListener;
}
/**
* When messages are received from a web app, they are parsed into the
* appropriate object type (string vs JSON/NSDictionary) and routed to the
* WebAppSessionListener.
*
* @param listener
* WebAppSessionListener to be called when messages are received
* from the web app
*/
public void setWebAppSessionListener(WebAppSessionListener listener) {
webAppListener = listener;
}
/**
* Success block that is called upon successfully launch of a web app.
*
* Passes a WebAppSession Object containing important information about the
* web app's session. This object is required to perform many functions with
* the web app, including app-to-app communication, media playback, closing,
* etc.
*/
public static interface LaunchListener extends
ResponseListener<WebAppSession> {
}
/**
* Success block that is called upon successfully getting a web app's
* status.
*
* Passes a WebAppStatus of the current running & foreground status of the
* web app
*/
public static interface StatusListener extends
ResponseListener<WebAppStatus> {
}
// @cond INTERNAL
public static interface MessageListener extends ResponseListener<Object> {
abstract public void onMessage(Object message);
}
// @endcond
}