// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; this.EXPORTED_SYMBOLS = ["MediaPlayerApp"]; const { classes: Cc, interfaces: Ci, utils: Cu } = Components; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Messaging.jsm"); var log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.d.bind(null, "MediaPlayerApp"); // Helper function for sending commands to Java. function send(type, data, callback) { let msg = { type: type }; for (let i in data) { msg[i] = data[i]; } Messaging.sendRequestForResult(msg) .then(result => callback(result, null), error => callback(null, error)); } /* These apps represent players supported natively by the platform. This class will proxy commands * to native controls */ function MediaPlayerApp(service) { this.service = service; this.location = service.location; this.id = service.uuid; } MediaPlayerApp.prototype = { start: function start(callback) { send("MediaPlayer:Start", { id: this.id }, (result, err) => { if (callback) { callback(err == null); } }); }, stop: function stop(callback) { send("MediaPlayer:Stop", { id: this.id }, (result, err) => { if (callback) { callback(err == null); } }); }, remoteMedia: function remoteMedia(callback, listener) { if (callback) { callback(new RemoteMedia(this.id, listener)); } }, mirror: function mirror(callback) { send("MediaPlayer:Mirror", { id: this.id }, (result, err) => { if (callback) { callback(err == null); } }); } } /* RemoteMedia provides a proxy to a native media player session. */ function RemoteMedia(id, listener) { this._id = id; this._listener = listener; if ("onRemoteMediaStart" in this._listener) { Services.tm.mainThread.dispatch((function() { this._listener.onRemoteMediaStart(this); }).bind(this), Ci.nsIThread.DISPATCH_NORMAL); } } RemoteMedia.prototype = { shutdown: function shutdown() { Services.obs.removeObserver(this, "MediaPlayer:Playing"); Services.obs.removeObserver(this, "MediaPlayer:Paused"); this._send("MediaPlayer:End", {}, (result, err) => { this._status = "shutdown"; if ("onRemoteMediaStop" in this._listener) { this._listener.onRemoteMediaStop(this); } }); }, play: function play() { this._send("MediaPlayer:Play", {}, (result, err) => { if (err) { Cu.reportError("Can't play " + err); this.shutdown(); return; } this._status = "started"; }); }, pause: function pause() { this._send("MediaPlayer:Pause", {}, (result, err) => { if (err) { Cu.reportError("Can't pause " + err); this.shutdown(); return; } this._status = "paused"; }); }, load: function load(aData) { this._send("MediaPlayer:Load", aData, (result, err) => { if (err) { Cu.reportError("Can't load " + err); this.shutdown(); return; } Services.obs.addObserver(this, "MediaPlayer:Playing", false); Services.obs.addObserver(this, "MediaPlayer:Paused", false); this._status = "started"; }) }, get status() { return this._status; }, observe: function (aSubject, aTopic, aData) { switch (aTopic) { case "MediaPlayer:Playing": if (this._status !== "started") { this._status = "started"; if ("onRemoteMediaStatus" in this._listener) { this._listener.onRemoteMediaStatus(this); } } break; case "MediaPlayer:Paused": if (this._status !== "paused") { this._status = "paused"; if ("onRemoteMediaStatus" in this._listener) { this._listener.onRemoteMediaStatus(this); } } break; default: break; } }, _send: function(msg, data, callback) { data.id = this._id; send(msg, data, callback); } }