UNPKG

4.92 kBJavaScriptView Raw
1/*
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20*/
21
22// The last resume event that was received that had the result of a plugin call.
23var lastResumeEvent = null;
24
25module.exports = {
26 id: 'android',
27 bootstrap: function() {
28 var channel = require('cordova/channel'),
29 cordova = require('cordova'),
30 exec = require('cordova/exec'),
31 modulemapper = require('cordova/modulemapper');
32
33 // Get the shared secret needed to use the bridge.
34 exec.init();
35
36 // TODO: Extract this as a proper plugin.
37 modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
38
39 var APP_PLUGIN_NAME = Number(cordova.platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
40
41 // Inject a listener for the backbutton on the document.
42 var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
43 backButtonChannel.onHasSubscribersChange = function() {
44 // If we just attached the first handler or detached the last handler,
45 // let native know we need to override the back button.
46 exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [this.numHandlers == 1]);
47 };
48
49 // Add hardware MENU and SEARCH button handlers
50 cordova.addDocumentEventHandler('menubutton');
51 cordova.addDocumentEventHandler('searchbutton');
52
53 function bindButtonChannel(buttonName) {
54 // generic button bind used for volumeup/volumedown buttons
55 var volumeButtonChannel = cordova.addDocumentEventHandler(buttonName + 'button');
56 volumeButtonChannel.onHasSubscribersChange = function() {
57 exec(null, null, APP_PLUGIN_NAME, "overrideButton", [buttonName, this.numHandlers == 1]);
58 };
59 }
60 // Inject a listener for the volume buttons on the document.
61 bindButtonChannel('volumeup');
62 bindButtonChannel('volumedown');
63
64 // The resume event is not "sticky", but it is possible that the event
65 // will contain the result of a plugin call. We need to ensure that the
66 // plugin result is delivered even after the event is fired (CB-10498)
67 var cordovaAddEventListener = document.addEventListener;
68
69 document.addEventListener = function(evt, handler, capture) {
70 cordovaAddEventListener(evt, handler, capture);
71
72 if (evt === 'resume' && lastResumeEvent) {
73 handler(lastResumeEvent);
74 }
75 };
76
77 // Let native code know we are all done on the JS side.
78 // Native code will then un-hide the WebView.
79 channel.onCordovaReady.subscribe(function() {
80 exec(onMessageFromNative, null, APP_PLUGIN_NAME, 'messageChannel', []);
81 exec(null, null, APP_PLUGIN_NAME, "show", []);
82 });
83 }
84};
85
86function onMessageFromNative(msg) {
87 var cordova = require('cordova');
88 var action = msg.action;
89
90 switch (action)
91 {
92 // Button events
93 case 'backbutton':
94 case 'menubutton':
95 case 'searchbutton':
96 // App life cycle events
97 case 'pause':
98 // Volume events
99 case 'volumedownbutton':
100 case 'volumeupbutton':
101 cordova.fireDocumentEvent(action);
102 break;
103 case 'resume':
104 if(arguments.length > 1 && msg.pendingResult) {
105 if(arguments.length === 2) {
106 msg.pendingResult.result = arguments[1];
107 } else {
108 // The plugin returned a multipart message
109 var res = [];
110 for(var i = 1; i < arguments.length; i++) {
111 res.push(arguments[i]);
112 }
113 msg.pendingResult.result = res;
114 }
115
116 // Save the plugin result so that it can be delivered to the js
117 // even if they miss the initial firing of the event
118 lastResumeEvent = msg;
119 }
120 cordova.fireDocumentEvent(action, msg);
121 break;
122 default:
123 throw new Error('Unknown event action ' + action);
124 }
125}