+
+class Device: public CPlugin {
+ Q_OBJECT
+public:
+ explicit Device(Cordova *cordova);
+
+ virtual const QString fullName() override {
+ return Device::fullID();
+ }
+
+ virtual const QString shortName() override {
+ return "Device";
+ }
+
+ static const QString fullID() {
+ return "com.cordova.Device";
+ }
+
+signals:
+
+public slots:
+ void getInfo(int scId, int ecId);
+};
+
+#endif
diff --git a/cordova/plugins/cordova-plugin-device/src/ubuntu/device.js b/cordova/plugins/cordova-plugin-device/src/ubuntu/device.js
new file mode 100644
index 0000000..3adb110
--- /dev/null
+++ b/cordova/plugins/cordova-plugin-device/src/ubuntu/device.js
@@ -0,0 +1,34 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+*/
+
+var cordova = require('cordova');
+var exec = require('cordova/exec');
+
+module.exports = {
+ getInfo:function(win,fail,args) {
+ Cordova.exec(function (model, cordova, platform, uuid, version) {
+ win({name: name, model: model, cordova: cordova,
+ platform: platform, uuid: uuid, version: version});
+ }, null, "com.cordova.Device", "getInfo", []);
+ }
+};
+
+require("cordova/exec/proxy").add("Device", module.exports);
diff --git a/cordova/plugins/cordova-plugin-device/src/windows/DeviceProxy.js b/cordova/plugins/cordova-plugin-device/src/windows/DeviceProxy.js
new file mode 100644
index 0000000..d21d46b
--- /dev/null
+++ b/cordova/plugins/cordova-plugin-device/src/windows/DeviceProxy.js
@@ -0,0 +1,96 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+*/
+
+var ROOT_CONTAINER = "{00000000-0000-0000-FFFF-FFFFFFFFFFFF}";
+var DEVICE_CLASS_KEY = "{A45C254E-DF1C-4EFD-8020-67D146A850E0},10";
+var DEVICE_CLASS_KEY_NO_SEMICOLON = '{A45C254E-DF1C-4EFD-8020-67D146A850E0}10';
+var ROOT_CONTAINER_QUERY = "System.Devices.ContainerId:=\"" + ROOT_CONTAINER + "\"";
+var HAL_DEVICE_CLASS = "4d36e966-e325-11ce-bfc1-08002be10318";
+var DEVICE_DRIVER_VERSION_KEY = "{A8B865DD-2E3D-4094-AD97-E593A70C75D6},3";
+
+module.exports = {
+
+ getDeviceInfo:function(win, fail, args) {
+
+ // deviceId aka uuid, stored in Windows.Storage.ApplicationData.current.localSettings.values.deviceId
+ var deviceId;
+ // get deviceId, or create and store one
+ var localSettings = Windows.Storage.ApplicationData.current.localSettings;
+ if (localSettings.values.deviceId) {
+ deviceId = localSettings.values.deviceId;
+ }
+ else {
+ // App-specific hardware id could be used as uuid, but it changes if the hardware changes...
+ try {
+ var ASHWID = Windows.System.Profile.HardwareIdentification.getPackageSpecificToken(null).id;
+ deviceId = Windows.Storage.Streams.DataReader.fromBuffer(ASHWID).readGuid();
+ } catch (e) {
+ // Couldn't get the hardware UUID
+ deviceId = createUUID();
+ }
+ //...so cache it per-install
+ localSettings.values.deviceId = deviceId;
+ }
+
+
+ var userAgent = window.clientInformation.userAgent;
+ // this will report "windows" in windows8.1 and windows phone 8.1 apps
+ // and "windows8" in windows 8.0 apps similar to cordova.js
+ // See https://github.com/apache/cordova-js/blob/master/src/windows/platform.js#L25
+ var devicePlatform = userAgent.indexOf("MSAppHost/1.0") == -1 ? "windows" : "windows8";
+ var versionString = userAgent.match(/Windows (?:Phone |NT )?([0-9.]+)/)[1];
+
+ var deviceInfo = new Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation();
+ // Running in the Windows Simulator is a remote session.
+ // Running in the Windows Phone Emulator has the systemProductName set to "Virtual"
+ var isVirtual = Windows.System.RemoteDesktop.InteractiveSession.isRemote || deviceInfo.systemProductName == "Virtual";
+ var manufacturer = deviceInfo.systemManufacturer;
+ var model = deviceInfo.systemProductName;
+
+ var Pnp = Windows.Devices.Enumeration.Pnp;
+
+ Pnp.PnpObject.findAllAsync(Pnp.PnpObjectType.device,
+ [DEVICE_DRIVER_VERSION_KEY, DEVICE_CLASS_KEY],
+ ROOT_CONTAINER_QUERY)
+ .then(function (rootDevices) {
+ for (var i = 0; i < rootDevices.length; i++) {
+ var rootDevice = rootDevices[i];
+ if (!rootDevice.properties) continue;
+ if (rootDevice.properties[DEVICE_CLASS_KEY_NO_SEMICOLON] == HAL_DEVICE_CLASS) {
+ versionString = rootDevice.properties[DEVICE_DRIVER_VERSION_KEY];
+ break;
+ }
+ }
+
+ setTimeout(function () {
+ win({ platform: devicePlatform,
+ version: versionString,
+ uuid: deviceId,
+ isVirtual: isVirtual,
+ model: model,
+ manufacturer:manufacturer});
+ }, 0);
+ });
+ }
+
+}; // exports
+
+require("cordova/exec/proxy").add("Device", module.exports);
diff --git a/cordova/plugins/cordova-plugin-device/src/wp/Device.cs b/cordova/plugins/cordova-plugin-device/src/wp/Device.cs
new file mode 100644
index 0000000..76fe8cf
--- /dev/null
+++ b/cordova/plugins/cordova-plugin-device/src/wp/Device.cs
@@ -0,0 +1,87 @@
+/*
+ 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.
+*/
+
+using Microsoft.Phone.Info;
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+ public class Device : BaseCommand
+ {
+ public void getDeviceInfo(string notused)
+ {
+ string res = String.Format("\"name\":\"{0}\",\"platform\":\"{1}\",\"uuid\":\"{2}\",\"version\":\"{3}\",\"model\":\"{4}\",\"manufacturer\":\"{5}\",\"isVirtual\":{6}",
+ DeviceStatus.DeviceName,
+ Environment.OSVersion.Platform.ToString(),
+ UUID,
+ Environment.OSVersion.Version.ToString(),
+ DeviceStatus.DeviceName,
+ DeviceStatus.DeviceManufacturer,
+ IsVirtual ? "true" : "false");
+ DispatchCommandResult(new PluginResult(PluginResult.Status.OK, "{" + res + "}"));
+ }
+
+
+ public bool IsVirtual
+ {
+ get
+ {
+ return (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Emulator);
+ }
+ }
+
+ public string UUID
+ {
+ get
+ {
+ object id;
+
+ UserExtendedProperties.TryGetValue("ANID", out id);
+ if (id != null)
+ {
+ return id.ToString().Substring(2, 32);
+ }
+
+ UserExtendedProperties.TryGetValue("ANID2", out id);
+ if (id != null)
+ {
+ return id.ToString();
+ }
+
+ string returnVal = "???unknown???";
+
+ using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
+ {
+ try
+ {
+ IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
+
+ using (StreamReader reader = new StreamReader(fileStream))
+ {
+ returnVal = reader.ReadLine();
+ }
+ }
+ catch (Exception /*ex*/)
+ {
+
+ }
+ }
+
+ return returnVal;
+ }
+ }
+ }
+}
diff --git a/cordova/plugins/cordova-plugin-device/tests/plugin.xml b/cordova/plugins/cordova-plugin-device/tests/plugin.xml
new file mode 100644
index 0000000..d5a79a0
--- /dev/null
+++ b/cordova/plugins/cordova-plugin-device/tests/plugin.xml
@@ -0,0 +1,31 @@
+
+
+
+
+ Cordova Device Plugin Tests
+ Apache 2.0
+
+
+
+
diff --git a/cordova/plugins/cordova-plugin-device/tests/tests.js b/cordova/plugins/cordova-plugin-device/tests/tests.js
new file mode 100644
index 0000000..21e4160
--- /dev/null
+++ b/cordova/plugins/cordova-plugin-device/tests/tests.js
@@ -0,0 +1,111 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+*/
+
+exports.defineAutoTests = function() {
+ describe('Device Information (window.device)', function () {
+ it("should exist", function() {
+ expect(window.device).toBeDefined();
+ });
+
+ it("should contain a platform specification that is a string", function() {
+ expect(window.device.platform).toBeDefined();
+ expect((new String(window.device.platform)).length > 0).toBe(true);
+ });
+
+ it("should contain a version specification that is a string", function() {
+ expect(window.device.version).toBeDefined();
+ expect((new String(window.device.version)).length > 0).toBe(true);
+ });
+
+ it("should contain a UUID specification that is a string or a number", function() {
+ expect(window.device.uuid).toBeDefined();
+ if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') {
+ expect((new String(window.device.uuid)).length > 0).toBe(true);
+ } else {
+ expect(window.device.uuid > 0).toBe(true);
+ }
+ });
+
+ it("should contain a cordova specification that is a string", function() {
+ expect(window.device.cordova).toBeDefined();
+ expect((new String(window.device.cordova)).length > 0).toBe(true);
+ });
+
+ it("should depend on the presence of cordova.version string", function() {
+ expect(window.cordova.version).toBeDefined();
+ expect((new String(window.cordova.version)).length > 0).toBe(true);
+ });
+
+ it("should contain device.cordova equal to cordova.version", function() {
+ expect(window.device.cordova).toBe(window.cordova.version);
+ });
+
+ it("should contain a model specification that is a string", function() {
+ expect(window.device.model).toBeDefined();
+ expect((new String(window.device.model)).length > 0).toBe(true);
+ });
+
+ it("should contain a manufacturer property that is a string", function() {
+ expect(window.device.manufacturer).toBeDefined();
+ expect((new String(window.device.manufacturer)).length > 0).toBe(true);
+ });
+
+ it("should contain an isVirtual property that is a boolean", function() {
+ expect(window.device.isVirtual).toBeDefined();
+ expect(typeof window.device.isVirtual).toBe("boolean");
+ });
+
+ it("should contain a serial number specification that is a string", function() {
+ expect(window.device.serial).toBeDefined();
+ expect((new String(window.device.serial)).length > 0).toBe(true);
+
+ });
+
+ });
+};
+
+exports.defineManualTests = function(contentEl, createActionButton) {
+ var logMessage = function (message, color) {
+ var log = document.getElementById('info');
+ var logLine = document.createElement('div');
+ if (color) {
+ logLine.style.color = color;
+ }
+ logLine.innerHTML = message;
+ log.appendChild(logLine);
+ }
+
+ var clearLog = function () {
+ var log = document.getElementById('info');
+ log.innerHTML = '';
+ }
+
+ var device_tests = 'Press Dump Device button to get device information
' +
+ '' +
+ 'Expected result: Status box will get updated with device info. (i.e. platform, version, uuid, model, etc)';
+
+ contentEl.innerHTML = '' + device_tests;
+
+ createActionButton('Dump device', function() {
+ clearLog();
+ logMessage(JSON.stringify(window.device, null, '\t'));
+ }, "dump_device");
+};
diff --git a/cordova/plugins/cordova-plugin-device/www/device.js b/cordova/plugins/cordova-plugin-device/www/device.js
new file mode 100644
index 0000000..f7ed19f
--- /dev/null
+++ b/cordova/plugins/cordova-plugin-device/www/device.js
@@ -0,0 +1,83 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+*/
+
+var argscheck = require('cordova/argscheck'),
+ channel = require('cordova/channel'),
+ utils = require('cordova/utils'),
+ exec = require('cordova/exec'),
+ cordova = require('cordova');
+
+channel.createSticky('onCordovaInfoReady');
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+/**
+ * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+function Device() {
+ this.available = false;
+ this.platform = null;
+ this.version = null;
+ this.uuid = null;
+ this.cordova = null;
+ this.model = null;
+ this.manufacturer = null;
+ this.isVirtual = null;
+ this.serial = null;
+
+ var me = this;
+
+ channel.onCordovaReady.subscribe(function() {
+ me.getInfo(function(info) {
+ //ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js
+ //TODO: CB-5105 native implementations should not return info.cordova
+ var buildLabel = cordova.version;
+ me.available = true;
+ me.platform = info.platform;
+ me.version = info.version;
+ me.uuid = info.uuid;
+ me.cordova = buildLabel;
+ me.model = info.model;
+ me.isVirtual = info.isVirtual;
+ me.manufacturer = info.manufacturer || 'unknown';
+ me.serial = info.serial || 'unknown';
+ channel.onCordovaInfoReady.fire();
+ },function(e) {
+ me.available = false;
+ utils.alert("[ERROR] Error initializing Cordova: " + e);
+ });
+ });
+}
+
+/**
+ * Get device info
+ *
+ * @param {Function} successCallback The function to call when the heading data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
+ */
+Device.prototype.getInfo = function(successCallback, errorCallback) {
+ argscheck.checkArgs('fF', 'Device.getInfo', arguments);
+ exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
+};
+
+module.exports = new Device();
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/CHANGELOG.md b/cordova/plugins/de.appplant.cordova.plugin.background-mode/CHANGELOG.md
new file mode 100644
index 0000000..5ebe71e
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/CHANGELOG.md
@@ -0,0 +1,44 @@
+## ChangeLog
+#### Version 0.6.4 (03.03.2015)
+- Resolve possibly dependency conflict
+
+#### Version 0.6.3 (01.01.2015)
+- [feature:] Silent mode for Android
+
+#### Version 0.6.2 (14.12.2014)
+- [bugfix:] Type error
+- [bugfix:] Wrong default values for `isEnabled` and `isActive`.
+
+#### Version 0.6.1 (14.12.2014)
+- [enhancement:] Set default settings through `setDefaults`.
+- [enhancement:] New method `isEnabled` to receive if mode is enabled.
+- [enhancement:] New method `isActive` to receive if mode is active.
+- [bugfix:] Events caused thread collision.
+
+
+#### Version 0.6.0 (14.12.2014)
+- [feature:] Android support
+- [feature:] Change Android notification through `configure`.
+- [feature:] `onactivate`, `ondeactivate` and `onfailure` callbacks.
+- [___change___:] Disabled by default
+- [enhancement:] Get default settings through `getDefaults`.
+- [enhancement:] iOS does not require user permissions, internet connection and geo location anymore.
+
+#### Version 0.5.0 (13.02.2014)
+- __retired__
+
+#### Version 0.4.1 (13.02.2014)
+- Release under the Apache 2.0 license.
+- [enhancement:] Location tracking is only activated on WP8 if the location service is available.
+- [bigfix:] Nullpointer exception on WP8.
+
+#### Version 0.4.0 (10.10.2013)
+- Added WP8 support
+ The plugin turns the app into an location tracking app *(for the time it runs in the background)*.
+
+#### Version 0.2.1 (09.10.2013)
+- Added js interface to manually enable/disable the background mode.
+
+#### Version 0.2.0 (08.10.2013)
+- Added iOS (>= 5) support
+ The plugin turns the app into an location tracking app for the time it runs in the background.
\ No newline at end of file
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/LICENSE b/cordova/plugins/de.appplant.cordova.plugin.background-mode/LICENSE
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
\ No newline at end of file
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/README.md b/cordova/plugins/de.appplant.cordova.plugin.background-mode/README.md
new file mode 100644
index 0000000..acb5f77
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/README.md
@@ -0,0 +1,273 @@
+
+
+ EXAMPLE :point_right:
+
+
+Cordova Background Plug-in
+==========================
+
+[Cordova][cordova] plugin to prevent the app from going to sleep while in background.
+
+Most mobile operating systems are multitasking capable, but most apps dont need to run while in background and not present for the user. Therefore they pause the app in background mode and resume the app before switching to foreground mode.
+The system keeps all network connections open while in background, but does not deliver the data until the app resumes.
+
+### Plugin's Purpose
+This cordova plug-in can be used for applications, who rely on continuous network communication independent of from direct user interactions and remote push notifications.
+
+### :bangbang: Store Compliance :bangbang:
+The plugin focuses on enterprise-only distribution and may not compliant with all public store vendors.
+
+
+## Overview
+1. [Supported Platforms](#supported-platforms)
+2. [Installation](#installation)
+3. [ChangeLog](#changelog)
+4. [Usage](#usage)
+5. [Examples](#examples)
+6. [Platform specifics](#platform-specifics)
+
+
+## Supported Platforms
+- __iOS__ (_including iOS8_)
+- __Android__ _(SDK >=11)_
+- __WP8__
+
+
+## Installation
+The plugin can either be installed from git repository, from local file system through the [Command-line Interface][CLI]. Or cloud based through [PhoneGap Build][PGB].
+
+### Local development environment
+From master:
+```bash
+# ~~ from master branch ~~
+cordova plugin add https://github.com/katzer/cordova-plugin-background-mode.git
+```
+from a local folder:
+```bash
+# ~~ local folder ~~
+cordova plugin add de.appplant.cordova.plugin.background-mode --searchpath path
+```
+or to use the last stable version:
+```bash
+# ~~ stable version ~~
+cordova plugin add de.appplant.cordova.plugin.background-mode@0.6.3
+```
+
+To remove the plug-in, run the following command:
+```bash
+cordova plugin rm de.appplant.cordova.plugin.background-mode
+```
+
+### PhoneGap Build
+Add the following xml to your config.xml to always use the latest version of this plugin:
+```xml
+
+```
+
+More informations can be found [here][PGB_plugin].
+
+
+## ChangeLog
+#### Version 0.6.4 (03.03.2015)
+- Resolve possibly dependency conflict
+
+#### Version 0.6.3 (01.01.2015)
+- [feature:] Silent mode for Android
+
+#### Version 0.6.2 (14.12.2014)
+- [bugfix:] Type error
+- [bugfix:] Wrong default values for `isEnabled` and `isActive`.
+
+#### Further informations
+- The former `plugin.backgroundMode` namespace has been deprecated and will be removed with the next major release.
+- See [CHANGELOG.md][changelog] to get the full changelog for the plugin.
+
+#### Known issues
+- Plug-in is broken on Windows Phone 8.1 platform.
+
+
+## Usage
+The plugin creates the object `cordova.plugins.backgroundMode` with the following methods:
+
+1. [backgroundMode.enable][enable]
+2. [backgroundMode.disable][disable]
+3. [backgroundMode.isEnabled][is_enabled]
+4. [backgroundMode.isActive][is_active]
+5. [backgroundMode.getDefaults][android_specifics]
+6. [backgroundMode.setDefaults][android_specifics]
+7. [backgroundMode.configure][configure]
+8. [backgroundMode.onactivate][onactivate]
+9. [backgroundMode.ondeactivate][ondeactivate]
+10. [backgroundMode.onfailure][onfailure]
+
+### Plugin initialization
+The plugin and its methods are not available before the *deviceready* event has been fired.
+
+```javascript
+document.addEventListener('deviceready', function () {
+ // cordova.plugins.backgroundMode is now available
+}, false);
+```
+
+### Prevent the app from going to sleep in background
+To prevent the app from being paused while in background, the `backroundMode.enable` interface has to be called.
+
+#### Further informations
+- The background mode will be activated once the app has entered the background and will be deactivated after the app has entered the foreground.
+- To activate the background mode the app needs to be in foreground.
+
+```javascript
+cordova.plugins.backgroundMode.enable();
+```
+
+### Pause the app while in background
+The background mode can be disabled through the `backgroundMode.disable` interface.
+
+#### Further informations
+- Once the background mode has been disabled, the app will be paused when in background.
+
+```javascript
+cordova.plugins.backgroundMode.disable();
+```
+
+### Receive if the background mode is enabled
+The `backgroundMode.isEnabled` interface can be used to get the information if the background mode is enabled or disabled.
+
+```javascript
+cordova.plugins.backgroundMode.isEnabled(); // => boolean
+```
+
+### Receive if the background mode is active
+The `backgroundMode.isActive` interface can be used to get the information if the background mode is active.
+
+```javascript
+cordova.plugins.backgroundMode.isActive(); // => boolean
+```
+
+### Get informed when the background mode has been activated
+The `backgroundMode.onactivate` interface can be used to get notified when the background mode has been activated.
+
+```javascript
+cordova.plugins.backgroundMode.onactivate = function() {};
+```
+
+### Get informed when the background mode has been deactivated
+The `backgroundMode.ondeactivate` interface can be used to get notified when the background mode has been deactivated.
+
+#### Further informations
+- Once the mode has been deactivated the app will be paused soon after the callback has been fired.
+
+```javascript
+cordova.plugins.backgroundMode.ondeactivate = function() {};
+```
+
+### Get informed when the background mode could not been activated
+The `backgroundMode.onfailure` interface can be used to get notified when the background mode could not been activated.
+
+The listener has to be a function and takes the following arguments:
+ - errorCode: Error code which describes the error
+
+```javascript
+cordova.plugins.backgroundMode.onfailure = function(errorCode) {};
+```
+
+
+## Examples
+The following example demonstrates how to enable the background mode after device is ready. The mode itself will be activated when the app has entered the background.
+
+```javascript
+document.addEventListener('deviceready', function () {
+ // Android customization
+ cordova.plugins.backgroundMode.setDefaults({ text:'Doing heavy tasks.'});
+ // Enable background mode
+ cordova.plugins.backgroundMode.enable();
+
+ // Called when background mode has been activated
+ cordova.plugins.backgroundMode.onactivate = function () {
+ setTimeout(function () {
+ // Modify the currently displayed notification
+ cordova.plugins.backgroundMode.configure({
+ text:'Running in background for more than 5s now.'
+ });
+ }, 5000);
+ }
+}, false);
+```
+
+
+## Platform specifics
+
+### Android customization
+To indicate that the app is executing tasks in background and being paused would disrupt the user, the plug-in has to create a notification while in background - like a download progress bar.
+
+#### Override defaults
+The title, ticker and text for that notification can be customized as follows:
+
+```javascript
+cordova.plugins.backgroundMode.setDefaults({
+ title: String,
+ ticker: String,
+ text: String
+})
+```
+
+By default the app will come to foreground when taping on the notification. That can be changed also.
+
+```javascript
+cordova.plugins.backgroundMode.setDefaults({
+ resume: false
+})
+```
+
+#### Modify the currently displayed notification
+It's also possible to modify the currently displayed notification while in background.
+
+```javascript
+cordova.plugins.backgroundMode.configure({
+ title: String,
+ ...
+})
+```
+
+#### Run in background without notification
+In silent mode the plugin will not display a notification - which is not the default. Be aware that Android recommends adding a notification otherwise the OS may pause the app.
+
+```javascript
+cordova.plugins.backgroundMode.configure({
+ silent: true
+})
+```
+
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Add some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
+
+
+## License
+
+This software is released under the [Apache 2.0 License][apache2_license].
+
+© 2013-2014 appPlant UG, Inc. All rights reserved
+
+
+[cordova]: https://cordova.apache.org
+[CLI]: http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface
+[PGB]: http://docs.build.phonegap.com/en_US/index.html
+[PGB_plugin]: https://build.phonegap.com/plugins/2056
+[changelog]: CHANGELOG.md
+[enable]: #prevent-the-app-from-going-to-sleep-in-background
+[disable]: #pause-the-app-while-in-background
+[is_enabled]: #receive-if-the-background-mode-is-enabled
+[is_active]: #receive-if-the-background-mode-is-active
+[android_specifics]: #android-customization
+[configure]: #modify-the-currently-displayed-notification
+[onactivate]: #get-informed-when-the-background-mode-has-been-activated
+[ondeactivate]: #get-informed-when-the-background-mode-has-been-deactivated
+[onfailure]: #get-informed-when-the-background-mode-could-not-been-activated
+[apache2_license]: http://opensource.org/licenses/Apache-2.0
+[appplant]: http://appplant.de
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/appbeep.wav b/cordova/plugins/de.appplant.cordova.plugin.background-mode/appbeep.wav
new file mode 100644
index 0000000..24a13d4
Binary files /dev/null and b/cordova/plugins/de.appplant.cordova.plugin.background-mode/appbeep.wav differ
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/package.json b/cordova/plugins/de.appplant.cordova.plugin.background-mode/package.json
new file mode 100644
index 0000000..da8fc7b
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "de.appplant.cordova.plugin.background-mode",
+ "version": "0.6.4",
+ "description": "Cordova plugin to prevent the app from going to sleep in background.",
+ "cordova": {
+ "id": "de.appplant.cordova.plugin.background-mode",
+ "platforms": [
+ "ios",
+ "android",
+ "wp8"
+ ]
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/katzer/cordova-plugin-background-mode.git"
+ },
+ "keywords": [
+ "appplant",
+ "background",
+ "mode",
+ "background-mode",
+ "katzer",
+ "ecosystem:cordova",
+ "cordova-ios",
+ "cordova-android",
+ "cordova-wp8"
+ ],
+ "engines": [
+ {
+ "name": "cordova",
+ "version": ">=3.0.0"
+ }
+ ],
+ "author": "Sebastián Katzer",
+ "license": "Apache 2.0",
+ "bugs": {
+ "url": "https://github.com/katzer/cordova-plugin-background-mode/issues"
+ },
+ "homepage": "https://github.com/katzer/cordova-plugin-background-mode"
+}
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/plugin.xml b/cordova/plugins/de.appplant.cordova.plugin.background-mode/plugin.xml
new file mode 100644
index 0000000..16b9701
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/plugin.xml
@@ -0,0 +1,111 @@
+
+
+
+
+ BackgroundMode
+
+
+ Cordova plugin to prevent the app from going to sleep in background.
+
+
+ https://github.com/katzer/cordova-plugin-background-mode.git
+
+ appplant, background
+
+ Apache 2.0
+
+ Sebastián Katzer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ audio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/android/BackgroundMode.java b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/android/BackgroundMode.java
new file mode 100644
index 0000000..8b9afe4
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/android/BackgroundMode.java
@@ -0,0 +1,312 @@
+/*
+ Copyright 2013-2014 appPlant UG
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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 de.appplant.cordova.plugin.background;
+
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaPlugin;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+
+public class BackgroundMode extends CordovaPlugin {
+
+ // Event types for callbacks
+ private enum Event {
+ ACTIVATE, DEACTIVATE, FAILURE
+ }
+
+ // Plugin namespace
+ private static final String JS_NAMESPACE = "cordova.plugins.backgroundMode";
+
+ // Flag indicates if the app is in background or foreground
+ private boolean inBackground = false;
+
+ // Flag indicates if the plugin is enabled or disabled
+ private boolean isDisabled = true;
+
+ // Flag indicates if the service is bind
+ private boolean isBind = false;
+
+ // Default settings for the notification
+ private static JSONObject defaultSettings = new JSONObject();
+
+ // Tmp config settings for the notification
+ private static JSONObject updateSettings;
+
+ // Used to (un)bind the service to with the activity
+ private final ServiceConnection connection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder binder) {
+ // Nothing to do here
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ // Nothing to do here
+ }
+ };
+
+ /**
+ * Executes the request.
+ *
+ * @param action The action to execute.
+ * @param args The exec() arguments.
+ * @param callback The callback context used when
+ * calling back into JavaScript.
+ *
+ * @return
+ * Returning false results in a "MethodNotFound" error.
+ *
+ * @throws JSONException
+ */
+ @Override
+ public boolean execute (String action, JSONArray args,
+ CallbackContext callback) throws JSONException {
+
+ if (action.equalsIgnoreCase("configure")) {
+ JSONObject settings = args.getJSONObject(0);
+ boolean update = args.getBoolean(1);
+
+ if (update) {
+ setUpdateSettings(settings);
+ updateNotifcation();
+ } else {
+ setDefaultSettings(settings);
+ }
+
+ return true;
+ }
+
+ if (action.equalsIgnoreCase("enable")) {
+ enableMode();
+ return true;
+ }
+
+ if (action.equalsIgnoreCase("disable")) {
+ disableMode();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Called when the system is about to start resuming a previous activity.
+ *
+ * @param multitasking
+ * Flag indicating if multitasking is turned on for app
+ */
+ @Override
+ public void onPause(boolean multitasking) {
+ super.onPause(multitasking);
+ inBackground = true;
+ startService();
+ }
+
+ /**
+ * Called when the activity will start interacting with the user.
+ *
+ * @param multitasking
+ * Flag indicating if multitasking is turned on for app
+ */
+ @Override
+ public void onResume(boolean multitasking) {
+ super.onResume(multitasking);
+ inBackground = false;
+ stopService();
+ }
+
+ /**
+ * Called when the activity will be destroyed.
+ */
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ stopService();
+ }
+
+ /**
+ * Enable the background mode.
+ */
+ private void enableMode() {
+ isDisabled = false;
+
+ if (inBackground) {
+ startService();
+ }
+ }
+
+ /**
+ * Disable the background mode.
+ */
+ private void disableMode() {
+ stopService();
+ isDisabled = true;
+ }
+
+ /**
+ * Update the default settings for the notification.
+ *
+ * @param settings
+ * The new default settings
+ */
+ private void setDefaultSettings(JSONObject settings) {
+ defaultSettings = settings;
+ }
+
+ /**
+ * Update the config settings for the notification.
+ *
+ * @param settings
+ * The tmp config settings
+ */
+ private void setUpdateSettings(JSONObject settings) {
+ updateSettings = settings;
+ }
+
+ /**
+ * The settings for the new/updated notification.
+ *
+ * @return
+ * updateSettings if set or default settings
+ */
+ protected static JSONObject getSettings() {
+ if (updateSettings != null)
+ return updateSettings;
+
+ return defaultSettings;
+ }
+
+ /**
+ * Called by ForegroundService to delete the update settings.
+ */
+ protected static void deleteUpdateSettings() {
+ updateSettings = null;
+ }
+
+ /**
+ * Update the notification.
+ */
+ private void updateNotifcation() {
+ if (isBind) {
+ stopService();
+ startService();
+ }
+ }
+
+ /**
+ * Bind the activity to a background service and put them into foreground
+ * state.
+ */
+ private void startService() {
+ Activity context = cordova.getActivity();
+
+ Intent intent = new Intent(
+ context, ForegroundService.class);
+
+ if (isDisabled || isBind)
+ return;
+
+ try {
+ context.bindService(
+ intent, connection, Context.BIND_AUTO_CREATE);
+
+ fireEvent(Event.ACTIVATE, null);
+
+ context.startService(intent);
+ } catch (Exception e) {
+ fireEvent(Event.FAILURE, e.getMessage());
+ }
+
+ isBind = true;
+ }
+
+ /**
+ * Bind the activity to a background service and put them into foreground
+ * state.
+ */
+ private void stopService() {
+ Activity context = cordova.getActivity();
+
+ Intent intent = new Intent(
+ context, ForegroundService.class);
+
+ if (!isBind)
+ return;
+
+ fireEvent(Event.DEACTIVATE, null);
+
+ context.unbindService(connection);
+ context.stopService(intent);
+
+ isBind = false;
+ }
+
+ /**
+ * Fire vent with some parameters inside the web view.
+ *
+ * @param event
+ * The name of the event
+ * @param params
+ * Optional arguments for the event
+ */
+ private void fireEvent (Event event, String params) {
+ String eventName;
+
+ if (updateSettings != null && event != Event.FAILURE)
+ return;
+
+ switch (event) {
+ case ACTIVATE:
+ eventName = "activate"; break;
+ case DEACTIVATE:
+ eventName = "deactivate"; break;
+ default:
+ eventName = "failure";
+ }
+
+ String active = event == Event.ACTIVATE ? "true" : "false";
+
+ String flag = String.format("%s._isActive=%s;",
+ JS_NAMESPACE, active);
+
+ String fn = String.format("setTimeout('%s.on%s(%s)',0);",
+ JS_NAMESPACE, eventName, params);
+
+ final String js = flag + fn;
+
+ cordova.getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ webView.loadUrl("javascript:" + js);
+ }
+ });
+ }
+}
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/android/ForegroundService.java b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/android/ForegroundService.java
new file mode 100644
index 0000000..a19283c
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/android/ForegroundService.java
@@ -0,0 +1,190 @@
+/*
+ Copyright 2013-2014 appPlant UG
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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 de.appplant.cordova.plugin.background;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.json.JSONObject;
+
+import android.annotation.SuppressLint;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.Log;
+
+/**
+ * Puts the service in a foreground state, where the system considers it to be
+ * something the user is actively aware of and thus not a candidate for killing
+ * when low on memory.
+ */
+public class ForegroundService extends Service {
+
+ // Fixed ID for the 'foreground' notification
+ private static final int NOTIFICATION_ID = -574543954;
+
+ // Scheduler to exec periodic tasks
+ final Timer scheduler = new Timer();
+
+ // Used to keep the app alive
+ TimerTask keepAliveTask;
+
+ /**
+ * Allow clients to call on to the service.
+ */
+ @Override
+ public IBinder onBind (Intent intent) {
+ return null;
+ }
+
+ /**
+ * Put the service in a foreground state to prevent app from being killed
+ * by the OS.
+ */
+ @Override
+ public void onCreate () {
+ super.onCreate();
+ keepAwake();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ sleepWell();
+ }
+
+ /**
+ * Put the service in a foreground state to prevent app from being killed
+ * by the OS.
+ */
+ public void keepAwake() {
+ final Handler handler = new Handler();
+
+ if (!this.inSilentMode()) {
+ startForeground(NOTIFICATION_ID, makeNotification());
+ } else {
+ Log.w("BackgroundMode", "In silent mode app may be paused by OS!");
+ }
+
+ BackgroundMode.deleteUpdateSettings();
+
+ keepAliveTask = new TimerTask() {
+ @Override
+ public void run() {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ // Nothing to do here
+ // Log.d("BackgroundMode", "" + new Date().getTime());
+ }
+ });
+ }
+ };
+
+ scheduler.schedule(keepAliveTask, 0, 1000);
+ }
+
+ /**
+ * Stop background mode.
+ */
+ private void sleepWell() {
+ stopForeground(true);
+ keepAliveTask.cancel();
+ }
+
+ /**
+ * Create a notification as the visible part to be able to put the service
+ * in a foreground state.
+ *
+ * @return
+ * A local ongoing notification which pending intent is bound to the
+ * main activity.
+ */
+ @SuppressLint("NewApi")
+ @SuppressWarnings("deprecation")
+ private Notification makeNotification() {
+ JSONObject settings = BackgroundMode.getSettings();
+ Context context = getApplicationContext();
+ String pkgName = context.getPackageName();
+ Intent intent = context.getPackageManager()
+ .getLaunchIntentForPackage(pkgName);
+
+ Notification.Builder notification = new Notification.Builder(context)
+ .setContentTitle(settings.optString("title", ""))
+ .setContentText(settings.optString("text", ""))
+ .setTicker(settings.optString("ticker", ""))
+ .setOngoing(true)
+ .setSmallIcon(getIconResId());
+
+ if (intent != null && settings.optBoolean("resume")) {
+
+ PendingIntent contentIntent = PendingIntent.getActivity(
+ context, NOTIFICATION_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+
+ notification.setContentIntent(contentIntent);
+ }
+
+
+ if (Build.VERSION.SDK_INT < 16) {
+ // Build notification for HoneyComb to ICS
+ return notification.getNotification();
+ } else {
+ // Notification for Jellybean and above
+ return notification.build();
+ }
+ }
+
+ /**
+ * Retrieves the resource ID of the app icon.
+ *
+ * @return
+ * The resource ID of the app icon
+ */
+ private int getIconResId() {
+ Context context = getApplicationContext();
+ Resources res = context.getResources();
+ String pkgName = context.getPackageName();
+
+ int resId;
+ resId = res.getIdentifier("icon", "drawable", pkgName);
+
+ return resId;
+ }
+
+ /**
+ * In silent mode no notification has to be added.
+ *
+ * @return
+ * True if silent: was set to true
+ */
+ private boolean inSilentMode() {
+ JSONObject settings = BackgroundMode.getSettings();
+
+ return settings.optBoolean("silent", false);
+ }
+}
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/ios/APPBackgroundMode.h b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/ios/APPBackgroundMode.h
new file mode 100644
index 0000000..c7ed2cf
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/ios/APPBackgroundMode.h
@@ -0,0 +1,37 @@
+/*
+ Copyright 2013-2014 appPlant UG
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+*/
+
+#import
+#import
+#import
+#import
+
+@interface APPBackgroundMode : CDVPlugin {
+ AVAudioPlayer *audioPlayer;
+ BOOL enabled;
+}
+
+// Activate the background mode
+- (void) enable:(CDVInvokedUrlCommand *)command;
+// Deactivate the background mode
+- (void) disable:(CDVInvokedUrlCommand *)command;
+
+@end
\ No newline at end of file
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/ios/APPBackgroundMode.m b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/ios/APPBackgroundMode.m
new file mode 100644
index 0000000..7fcaf6b
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/ios/APPBackgroundMode.m
@@ -0,0 +1,191 @@
+/*
+ Copyright 2013-2014 appPlant UG
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+*/
+
+#import "APPBackgroundMode.h"
+
+@implementation APPBackgroundMode
+
+NSString *const kAPPBackgroundJsNamespace = @"cordova.plugins.backgroundMode";
+NSString *const kAPPBackgroundEventActivate = @"activate";
+NSString *const kAPPBackgroundEventDeactivate = @"deactivate";
+NSString *const kAPPBackgroundEventFailure = @"failure";
+
+#pragma mark -
+#pragma mark Initialization methods
+
+/**
+ * Initialize the plugin.
+ */
+- (void) pluginInitialize
+{
+ [self disable:NULL];
+ [self configureAudioPlayer];
+ [self configureAudioSession];
+ [self observeLifeCycle];
+}
+
+/**
+ * Register the listener for pause and resume events.
+ */
+- (void) observeLifeCycle
+{
+ NSNotificationCenter* listener = [NSNotificationCenter defaultCenter];
+
+ if (&UIApplicationDidEnterBackgroundNotification && &UIApplicationWillEnterForegroundNotification) {
+
+ [listener addObserver:self
+ selector:@selector(keepAwake)
+ name:UIApplicationDidEnterBackgroundNotification
+ object:nil];
+
+ [listener addObserver:self
+ selector:@selector(stopKeepingAwake)
+ name:UIApplicationWillEnterForegroundNotification
+ object:nil];
+
+ [listener addObserver:self
+ selector:@selector(handleAudioSessionInterruption:)
+ name:AVAudioSessionInterruptionNotification
+ object:nil];
+
+ } else {
+ [self enable:NULL];
+ [self keepAwake];
+ }
+}
+
+#pragma mark -
+#pragma mark Interface methods
+
+/**
+ * Enable the mode to stay awake
+ * when switching to background for the next time.
+ */
+- (void) enable:(CDVInvokedUrlCommand *)command
+{
+ enabled = YES;
+}
+
+/**
+ * Disable the background mode
+ * and stop being active in background.
+ */
+- (void) disable:(CDVInvokedUrlCommand *)command
+{
+ enabled = NO;
+
+ [self stopKeepingAwake];
+}
+
+#pragma mark -
+#pragma mark Core methods
+
+/**
+ * Keep the app awake.
+ */
+- (void) keepAwake {
+ if (enabled) {
+ [audioPlayer play];
+ [self fireEvent:kAPPBackgroundEventActivate withParams:NULL];
+ }
+}
+
+/**
+ * Let the app going to sleep.
+ */
+- (void) stopKeepingAwake {
+
+ if (TARGET_IPHONE_SIMULATOR) {
+ NSLog(@"BackgroundMode: On simulator apps never pause in background!");
+ }
+
+ if (audioPlayer.isPlaying) {
+ [self fireEvent:kAPPBackgroundEventDeactivate withParams:NULL];
+ }
+
+ [audioPlayer pause];
+}
+
+/**
+ * Configure the audio player.
+ */
+- (void) configureAudioPlayer {
+ NSString* path = [[NSBundle mainBundle] pathForResource:@"appbeep"
+ ofType:@"wav"];
+
+ NSURL* url = [NSURL fileURLWithPath:path];
+
+
+ audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url
+ error:NULL];
+
+ // Silent
+ audioPlayer.volume = 0;
+ // Infinite
+ audioPlayer.numberOfLoops = -1;
+};
+
+/**
+ * Configure the audio session.
+ */
+- (void) configureAudioSession {
+ AVAudioSession* session = [AVAudioSession
+ sharedInstance];
+
+ // Play music even in background and dont stop playing music
+ // even another app starts playing sound
+ [session setCategory:AVAudioSessionCategoryPlayback
+ withOptions:AVAudioSessionCategoryOptionMixWithOthers
+ error:NULL];
+
+ [session setActive:YES error:NULL];
+};
+
+#pragma mark -
+#pragma mark Helper methods
+
+/**
+ * Restart playing sound when interrupted by phone calls.
+ */
+- (void) handleAudioSessionInterruption:(NSNotification*)notification {
+ [self fireEvent:kAPPBackgroundEventDeactivate withParams:NULL];
+ [self keepAwake];
+}
+
+/**
+ * Method to fire an event with some parameters in the browser.
+ */
+- (void) fireEvent:(NSString*)event withParams:(NSString*)params
+{
+ NSString* active = [event isEqualToString:kAPPBackgroundEventActivate] ? @"true" : @"false";
+
+ NSString* flag = [NSString stringWithFormat:@"%@._isActive=%@;",
+ kAPPBackgroundJsNamespace, active];
+
+ NSString* fn = [NSString stringWithFormat:@"setTimeout('%@.on%@(%@)',0);",
+ kAPPBackgroundJsNamespace, event, params];
+
+ NSString* js = [flag stringByAppendingString:fn];
+
+ [self.commandDelegate evalJs:js];
+}
+
+@end
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/wp8/BackgroundMode.cs b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/wp8/BackgroundMode.cs
new file mode 100644
index 0000000..81d3df8
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/src/wp8/BackgroundMode.cs
@@ -0,0 +1,199 @@
+/*
+ Copyright 2013-2014 appPlant UG
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+*/
+
+using WPCordovaClassLib.Cordova.Commands;
+using Windows.Devices.Geolocation;
+using Microsoft.Phone.Shell;
+using System;
+using WPCordovaClassLib.Cordova;
+
+namespace Cordova.Extension.Commands
+{
+ ///
+ /// Ermöglicht, dass eine Anwendung im Hintergrund läuft ohne pausiert zu werden
+ ///
+ public class BackgroundMode : BaseCommand
+ {
+ ///
+ /// Event types for callbacks
+ ///
+ enum Event {
+ ACTIVATE, DEACTIVATE, FAILURE
+ }
+
+ #region Instance variables
+
+ ///
+ /// Flag indicates if the plugin is enabled or disabled
+ ///
+ private bool IsDisabled = true;
+
+ ///
+ /// Geolocator to monitor location changes
+ ///
+ private static Geolocator Geolocator { get; set; }
+
+ #endregion
+
+ #region Interface methods
+
+ ///
+ /// Enable the mode to stay awake when switching
+ /// to background for the next time.
+ ///
+ public void enable (string args)
+ {
+ IsDisabled = false;
+ }
+
+ ///
+ /// Disable the background mode and stop
+ /// being active in background.
+ ///
+ public void disable (string args)
+ {
+ IsDisabled = true;
+
+ Deactivate();
+ }
+
+ #endregion
+
+ #region Core methods
+
+ ///
+ /// Keep the app awake by tracking
+ /// for position changes.
+ ///
+ private void Activate()
+ {
+ if (IsDisabled || Geolocator != null)
+ return;
+
+ if (!IsServiceAvailable())
+ {
+ FireEvent(Event.FAILURE, null);
+ return;
+ }
+
+ Geolocator = new Geolocator();
+
+ Geolocator.DesiredAccuracy = PositionAccuracy.Default;
+ Geolocator.MovementThreshold = 100000;
+ Geolocator.PositionChanged += geolocator_PositionChanged;
+
+ FireEvent(Event.ACTIVATE, null);
+ }
+
+ ///
+ /// Let the app going to sleep.
+ ///
+ private void Deactivate ()
+ {
+ if (Geolocator == null)
+ return;
+
+ FireEvent(Event.DEACTIVATE, null);
+
+ Geolocator.PositionChanged -= geolocator_PositionChanged;
+ Geolocator = null;
+ }
+
+ #endregion
+
+ #region Helper methods
+
+ ///
+ /// Determine if location service is available and enabled.
+ ///
+ private bool IsServiceAvailable()
+ {
+ Geolocator geolocator = (Geolocator == null) ? new Geolocator() : Geolocator;
+
+ PositionStatus status = geolocator.LocationStatus;
+
+ if (status == PositionStatus.Disabled)
+ return false;
+
+ if (status == PositionStatus.NotAvailable)
+ return false;
+
+ return true;
+ }
+
+ ///
+ /// Fires the given event.
+ ///
+ private void FireEvent(Event Event, string Param)
+ {
+ string EventName;
+
+ switch (Event) {
+ case Event.ACTIVATE:
+ EventName = "activate"; break;
+ case Event.DEACTIVATE:
+ EventName = "deactivate"; break;
+ default:
+ EventName = "failure"; break;
+ }
+
+ string js = String.Format("cordova.plugins.backgroundMode.on{0}({1})", EventName, Param);
+
+ PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, js);
+
+ pluginResult.KeepCallback = true;
+
+ DispatchCommandResult(pluginResult);
+ }
+
+ #endregion
+
+ #region Delegate methods
+
+ private void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
+ {
+ // Nothing to do here
+ }
+
+ #endregion
+
+ #region Lifecycle methods
+
+ ///
+ /// Occurs when the application is being deactivated.
+ ///
+ public override void OnPause(object sender, DeactivatedEventArgs e)
+ {
+ Activate();
+ }
+
+ ///
+ /// Occurs when the application is being made active after previously being put
+ /// into a dormant state or tombstoned.
+ ///
+ public override void OnResume(object sender, ActivatedEventArgs e)
+ {
+ Deactivate();
+ }
+
+ #endregion
+ }
+}
diff --git a/cordova/plugins/de.appplant.cordova.plugin.background-mode/www/background-mode.js b/cordova/plugins/de.appplant.cordova.plugin.background-mode/www/background-mode.js
new file mode 100644
index 0000000..d4a2836
--- /dev/null
+++ b/cordova/plugins/de.appplant.cordova.plugin.background-mode/www/background-mode.js
@@ -0,0 +1,194 @@
+/*
+ Copyright 2013-2014 appPlant UG
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+*/
+
+var exec = require('cordova/exec'),
+ channel = require('cordova/channel');
+
+
+// Override back button action to prevent being killed
+document.addEventListener('backbutton', function () {}, false);
+
+// Called before 'deviceready' listener will be called
+channel.onCordovaReady.subscribe(function () {
+ // Device plugin is ready now
+ channel.onCordovaInfoReady.subscribe(function () {
+ // Set the defaults
+ exports.setDefaults({});
+ });
+
+ // Only enable WP8 by default
+ if (['WinCE', 'Win32NT'].indexOf(device.platform) > -1) {
+ exports.enable();
+ }
+});
+
+
+/**
+ * @private
+ *
+ * Flag indicated if the mode is enabled.
+ */
+exports._isEnabled = false;
+
+/**
+ * @private
+ *
+ * Flag indicated if the mode is active.
+ */
+exports._isActive = false;
+
+/**
+ * @private
+ *
+ * Default values of all available options.
+ */
+exports._defaults = {
+ title: 'App is running in background',
+ text: 'Doing heavy tasks.',
+ ticker: 'App is running in background',
+ resume: true,
+ silent: false
+};
+
+
+/**
+ * Activates the background mode. When activated the application
+ * will be prevented from going to sleep while in background
+ * for the next time.
+ */
+exports.enable = function () {
+ this._isEnabled = true;
+ cordova.exec(null, null, 'BackgroundMode', 'enable', []);
+};
+
+/**
+ * Deactivates the background mode. When deactivated the application
+ * will not stay awake while in background.
+ */
+exports.disable = function () {
+ this._isEnabled = false;
+ cordova.exec(null, null, 'BackgroundMode', 'disable', []);
+};
+
+/**
+ * List of all available options with their default value.
+ *
+ * @return {Object}
+ */
+exports.getDefaults = function () {
+ return this._defaults;
+};
+
+/**
+ * Overwrite default settings
+ *
+ * @param {Object} overrides
+ * Dict of options which shall be overridden
+ */
+exports.setDefaults = function (overrides) {
+ var defaults = this.getDefaults();
+
+ for (var key in defaults) {
+ if (overrides.hasOwnProperty(key)) {
+ defaults[key] = overrides[key];
+ }
+ }
+
+ if (device.platform == 'Android') {
+ cordova.exec(null, null, 'BackgroundMode', 'configure', [defaults, false]);
+ }
+};
+
+/**
+ * Configures the notification settings for Android.
+ * Will be merged with the defaults.
+ *
+ * @param {Object} options
+ * Dict with key/value pairs
+ */
+exports.configure = function (options) {
+ var settings = this.mergeWithDefaults(options);
+
+ if (device.platform == 'Android') {
+ cordova.exec(null, null, 'BackgroundMode', 'configure', [settings, true]);
+ }
+};
+
+/**
+ * If the mode is enabled or disabled.
+ *
+ * @return {Boolean}
+ */
+exports.isEnabled = function () {
+ return this._isEnabled;
+};
+
+/**
+ * If the mode is active.
+ *
+ * @return {Boolean}
+ */
+exports.isActive = function () {
+ return this._isActive;
+};
+
+/**
+ * Called when the background mode has been activated.
+ */
+exports.onactivate = function () {};
+
+/**
+ * Called when the background mode has been deaktivated.
+ */
+exports.ondeactivate = function () {};
+
+/**
+ * Called when the background mode could not been activated.
+ *
+ * @param {Integer} errorCode
+ * Error code which describes the error
+ */
+exports.onfailure = function () {};
+
+/**
+ * @private
+ *
+ * Merge settings with default values.
+ *
+ * @param {Object} options
+ * The custom options
+ *
+ * @return {Object}
+ * Default values merged
+ * with custom values
+ */
+exports.mergeWithDefaults = function (options) {
+ var defaults = this.getDefaults();
+
+ for (var key in defaults) {
+ if (!options.hasOwnProperty(key)) {
+ options[key] = defaults[key];
+ continue;
+ }
+ }
+
+ return options;
+};