Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
c18182dd05
commit
0fe409c7bf
243
js/ui/cordova/plugins/cordova-plugin-android-sensor-listeners/www/sensors.js
vendored
Normal file
243
js/ui/cordova/plugins/cordova-plugin-android-sensor-listeners/www/sensors.js
vendored
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
/* Sensor Listener
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* function listener(event) {
|
||||||
|
* console.log("device's rotation is " + event.values.join(","));
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* sensors.addSensorListener("ROTATION_VECTOR", "GAME", listener, function(error) {
|
||||||
|
* if (error) console.error("Could not listen to sensor");
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
var createRegistry = require('./registry');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @namespace sensors
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event emitted from sensors.
|
||||||
|
* @typedef {Object} SensorEvent
|
||||||
|
* @property {string} sensor - The type of sensor that is listened to.
|
||||||
|
* @property {string} sampling - The sampling period the sensor is listened to
|
||||||
|
* by the receiving event listener.
|
||||||
|
* @property {int} timeStamp - The time the event was emitted.
|
||||||
|
* @property {float[]} values - The sensor values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This callback is used to get responses from async calls. It complies with
|
||||||
|
* nodeJS callback style.
|
||||||
|
* @callback errorFirstCallback
|
||||||
|
* @param {*} [err] - the error or undefined if everything went fine
|
||||||
|
* @param {*} data - the response or the called function
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This listener is used to receive events from sensors.
|
||||||
|
* @callback sensorEventListener
|
||||||
|
* @param {SensorEvent} evt - the event emitted by one of the sensor
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Small utility that enables to answer to a node-style callback in a Promise-
|
||||||
|
// like fashion. Make sure the error and result arguments are properly
|
||||||
|
// distributed.
|
||||||
|
function unpromisify(nodeStyleCallback, f) {
|
||||||
|
function resolve(r) {
|
||||||
|
nodeStyleCallback && nodeStyleCallback(null, r);
|
||||||
|
}
|
||||||
|
function reject(error) {
|
||||||
|
// The error cannot be undefined.
|
||||||
|
nodeStyleCallback && nodeStyleCallback(error || new Error());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f(resolve, reject);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the event listeners.
|
||||||
|
var listenerRegistry = createRegistry();
|
||||||
|
|
||||||
|
// Status of the connection with Android.
|
||||||
|
var state = 'init';
|
||||||
|
|
||||||
|
// Store functions to be called only after the registration is successful.
|
||||||
|
var registrationQueue = [];
|
||||||
|
|
||||||
|
// Function decorator that makes sure a function is only called after the
|
||||||
|
// registration.
|
||||||
|
function afterRegistration(f) {
|
||||||
|
return function() {
|
||||||
|
if (state === 'init') {
|
||||||
|
var args = arguments;
|
||||||
|
var that = this;
|
||||||
|
registrationQueue.push(function() {
|
||||||
|
f.apply(that, args);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
f.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a subscribed sensor sent an event.
|
||||||
|
*
|
||||||
|
* @ignore
|
||||||
|
* @param {SensorEvent} event - The event.
|
||||||
|
* @return {undefined}
|
||||||
|
*/
|
||||||
|
function onSensorEvent(event) {
|
||||||
|
if (!event.sensor) {
|
||||||
|
throw new Error('onSensorEvent called with wrong event format.');
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!listenerRegistry.getListenersCaller(event.sensor, event.sampling)(event)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
'Received unexpected event from non subscribed sensor: ' + event.sensor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the event callback.
|
||||||
|
document.addEventListener('deviceready', function() {
|
||||||
|
// This handler is called when Java push data to this plugin.
|
||||||
|
// It needs to be registered as soon as possible.
|
||||||
|
var registrationCallback = function handleConfirmation(resp) {
|
||||||
|
if (resp === 'registered') {
|
||||||
|
// Once the confirmation has been received, this directly handle events.
|
||||||
|
registrationCallback = onSensorEvent;
|
||||||
|
// Update the state and call any pending pending call in the registration
|
||||||
|
// queue.
|
||||||
|
state = 'registered';
|
||||||
|
var n = registrationQueue.length;
|
||||||
|
for (var i = 0; i < n; i += 1) {
|
||||||
|
registrationQueue[i]();
|
||||||
|
}
|
||||||
|
registrationQueue = null;
|
||||||
|
} else {
|
||||||
|
state = 'error';
|
||||||
|
throw new Error(
|
||||||
|
'Expecting confirmation for the callback registration but received: ' +
|
||||||
|
resp
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cordova.exec(
|
||||||
|
function() {
|
||||||
|
registrationCallback.apply(this, arguments);
|
||||||
|
},
|
||||||
|
function(e) {
|
||||||
|
console.error(e.stack || e);
|
||||||
|
throw e;
|
||||||
|
},
|
||||||
|
'Sensors',
|
||||||
|
'registerCallback',
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a sensor listener.
|
||||||
|
* @function
|
||||||
|
* @memberof sensors
|
||||||
|
* @name addSensorListener
|
||||||
|
* @param {string} sensorType - The sensor type's constant name (as defined by
|
||||||
|
* [Android's Sensor]{@link https://developer.android.com/guide/topics/sensors/sensors_overview.html},
|
||||||
|
* but without the prefix `'TYPE_'`).
|
||||||
|
* @param {string} samplingPeriod - The sampling period's constant name (as
|
||||||
|
* accepted by [SensorManager#registerListener]{@link https://developer.android.com/reference/android/hardware/SensorManager.html#registerListener(android.hardware.SensorEventListener,%20android.hardware.Sensor,%20int)},
|
||||||
|
* but without the prefix `'SENSOR_DELAY_'`).
|
||||||
|
* @param {sensorEventListener} listener - The listener to register.
|
||||||
|
* @param {errorFirstCallback} [callback] - A node-style callback to be called
|
||||||
|
* upon success or failure of the operation.
|
||||||
|
* @return {undefined}
|
||||||
|
* @example
|
||||||
|
* function listener(event) {
|
||||||
|
* console.log("device's rotation is " + event.values.join(","));
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* sensors.addSensorListener('ROTATION_VECTOR', 'GAME', listener, function(error) {
|
||||||
|
* if (error) console.error('Could not listen to sensor');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
module.exports.addSensorListener = afterRegistration(function(
|
||||||
|
sensorType,
|
||||||
|
samplingPeriod,
|
||||||
|
listener,
|
||||||
|
callback
|
||||||
|
) {
|
||||||
|
unpromisify(callback, function(resolve, reject) {
|
||||||
|
if (listenerRegistry.addListener(sensorType, samplingPeriod, listener)) {
|
||||||
|
// `listenerRegistry.addListener` returns true if there was no listener
|
||||||
|
// of this type when the listener has been added. In this case, we
|
||||||
|
// subscribe to the sensor notifications.
|
||||||
|
cordova.exec(
|
||||||
|
resolve,
|
||||||
|
function() {
|
||||||
|
listenerRegistry.removeListener(sensorType, samplingPeriod, listener);
|
||||||
|
reject.apply(this, arguments);
|
||||||
|
},
|
||||||
|
'Sensors',
|
||||||
|
'subscribe',
|
||||||
|
[sensorType, samplingPeriod]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// If there is other listeners registered for this type, we immediately
|
||||||
|
// resolve;
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a sensor listener.
|
||||||
|
* @function
|
||||||
|
* @memberof sensors
|
||||||
|
* @name removeSensorListener
|
||||||
|
* @param {string} sensorType - The type of the sensor as registered when
|
||||||
|
* the listener was added (see {@link sensors.addSensorListener}).
|
||||||
|
* @param {string} samplingPeriod - The sampling period as registered when
|
||||||
|
* the listener was added (see {@link sensors.addSensorListener}).
|
||||||
|
* @param {sensorEventListener} listener - The listener to remove.
|
||||||
|
* @param {errorFirstCallback} [callback] - A node-style callback to be called
|
||||||
|
* upon success or failure of the operation.
|
||||||
|
* @return {undefined}
|
||||||
|
* @example
|
||||||
|
* sensors.removeSensorListener('ROTATION_VECTOR', 'GAME', listener, function(error) {
|
||||||
|
* if (error) console.error('Could not stop listening to sensor');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
module.exports.removeSensorListener = afterRegistration(function(
|
||||||
|
sensorType,
|
||||||
|
samplingPeriod,
|
||||||
|
listener,
|
||||||
|
callback
|
||||||
|
) {
|
||||||
|
unpromisify(callback, function(resolve, reject) {
|
||||||
|
if (
|
||||||
|
listenerRegistry.containsListener(sensorType, samplingPeriod, listener)
|
||||||
|
) {
|
||||||
|
cordova.exec(
|
||||||
|
function(result) {
|
||||||
|
// Do not remove the listener before receiving the confirmation as we
|
||||||
|
// may still receive events in the meantime.
|
||||||
|
listenerRegistry.removeListener(sensorType, samplingPeriod, listener);
|
||||||
|
resolve(result);
|
||||||
|
},
|
||||||
|
reject,
|
||||||
|
'Sensors',
|
||||||
|
'unsubscribe',
|
||||||
|
[sensorType, samplingPeriod]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user