diff --git a/src/plugins/backgroundmode.ts b/src/plugins/backgroundmode.ts index 9db7f4c866..ae0c775401 100644 --- a/src/plugins/backgroundmode.ts +++ b/src/plugins/backgroundmode.ts @@ -1,4 +1,6 @@ -import { Cordova, Plugin } from './plugin'; +import { Cordova, CordovaFunctionOverride, Plugin } from './plugin'; + +import { Observable } from 'rxjs/Observable'; /** * @name Background Mode @@ -80,17 +82,25 @@ export class BackgroundMode { @Cordova({ platforms: ['Android'] }) - static update(options?: Configure): void { } + static configure(options?: Configure): void { } /** - * Sets a callback for a specific event - * Can be used to get notified or run function when the background mode has been activated, deactivated or failed. - * @param {string} eventName The name of the event. Available events: activate, deactivate, failure + * Called when background mode is activated. */ - @Cordova({ - sync: true - }) - static on(eventName: string, callback: any): void { } + @CordovaFunctionOverride() + static onactivate(): Observable { return; }; + + /** + * Called when background mode is deactivated. + */ + @CordovaFunctionOverride() + static ondeactivate(): Observable { return; }; + + /** + * Called when background mode fails + */ + @CordovaFunctionOverride() + static onfailure(): Observable { return; }; } diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index 55b3ff0c19..a0acfc9cc3 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -230,6 +230,47 @@ function wrapEventObservable(event: string): Observable { }); } +/** + * Certain plugins expect the user to override methods in the plugin. For example, + * window.cordova.plugins.backgroundMode.onactivate = function() { ... }. + * + * Unfortunately, this is brittle and would be better wrapped as an Observable. overrideFunction + * does just this. + */ +function overrideFunction(pluginObj: any, methodName: string, args: any[], opts: any = {}): Observable { + return new Observable(observer => { + + let pluginInstance = getPlugin(pluginObj.pluginRef); + + if (!pluginInstance) { + // Do this check in here in the case that the Web API for this plugin is available (for example, Geolocation). + if (!window.cordova) { + cordovaWarn(pluginObj.name, methodName); + observer.error({ + error: 'cordova_not_available' + }); + } + + pluginWarn(pluginObj, methodName); + observer.error({ + error: 'plugin_not_installed' + }); + return; + } + + let method = pluginInstance[methodName]; + if (!method) { + observer.error({ + error: 'no_such_method' + }); + observer.complete(); + return; + } + pluginInstance[methodName] = observer.next.bind(observer); + }); +} + + /** * @private * @param pluginObj @@ -364,3 +405,19 @@ export function InstanceProperty(target: any, key: string, descriptor: TypedProp return descriptor; } + +/** + * @private + * + * Wrap a stub function in a call to a Cordova plugin, checking if both Cordova + * and the required plugin are installed. + */ +export function CordovaFunctionOverride(opts: any = {}) { + return (target: Object, methodName: string, descriptor: TypedPropertyDescriptor) => { + return { + value: function(...args: any[]) { + return overrideFunction(this, methodName, opts); + } + }; + }; +}