diff --git a/.classpath b/framework/.classpath similarity index 100% rename from .classpath rename to framework/.classpath diff --git a/.project b/framework/.project similarity index 100% rename from .project rename to framework/.project diff --git a/AndroidManifest.xml b/framework/AndroidManifest.xml similarity index 100% rename from AndroidManifest.xml rename to framework/AndroidManifest.xml diff --git a/README b/framework/README similarity index 100% rename from README rename to framework/README diff --git a/assets/www/index.html b/framework/assets/www/index.html similarity index 100% rename from assets/www/index.html rename to framework/assets/www/index.html diff --git a/assets/www/master.css b/framework/assets/www/master.css similarity index 100% rename from assets/www/master.css rename to framework/assets/www/master.css diff --git a/framework/assets/www/phonegap.js b/framework/assets/www/phonegap.js new file mode 100644 index 00000000..e9fcbd94 --- /dev/null +++ b/framework/assets/www/phonegap.js @@ -0,0 +1,1272 @@ +if (typeof(DeviceInfo) != 'object') + DeviceInfo = {}; + +/** + * This represents the PhoneGap API itself, and provides a global namespace for accessing + * information about the state of PhoneGap. + * @class + */ +PhoneGap = { + queue: { + ready: true, + commands: [], + timer: null + }, + _constructors: [] +}; + +/** + * Boolean flag indicating if the PhoneGap API is available and initialized. + */ +PhoneGap.available = DeviceInfo.uuid != undefined; + +/** + * Add an initialization function to a queue that ensures it will run and initialize + * application constructors only once PhoneGap has been initialized. + * @param {Function} func The function callback you want run once PhoneGap is initialized + */ +PhoneGap.addConstructor = function(func) { + var state = document.readyState; + if (state != 'loaded' && state != 'complete') + PhoneGap._constructors.push(func); + else + func(); +}; +(function() { + var timer = setInterval(function() { + var state = document.readyState; + if (state != 'loaded' && state != 'complete') + return; + clearInterval(timer); + while (PhoneGap._constructors.length > 0) { + var constructor = PhoneGap._constructors.shift(); + try { + constructor(); + } catch(e) { + if (typeof(debug['log']) == 'function') + debug.log("Failed to run constructor: " + debug.processMessage(e)); + else + alert("Failed to run constructor: " + e.message); + } + } + }, 1); +})(); + + +/** + * Execute a PhoneGap command in a queued fashion, to ensure commands do not + * execute with any race conditions, and only run when PhoneGap is ready to + * recieve them. + * @param {String} command Command to be run in PhoneGap, e.g. "ClassName.method" + * @param {String[]} [args] Zero or more arguments to pass to the method + */ +PhoneGap.exec = function() { + PhoneGap.queue.commands.push(arguments); + if (PhoneGap.queue.timer == null) + PhoneGap.queue.timer = setInterval(PhoneGap.run_command, 10); +}; +/** + * Internal function used to dispatch the request to PhoneGap. This needs to be implemented per-platform to + * ensure that methods are called on the phone in a way appropriate for that device. + * @private + */ +PhoneGap.run_command = function() { +}; + +/** + * This class contains acceleration information + * @constructor + * @param {Number} x The force applied by the device in the x-axis. + * @param {Number} y The force applied by the device in the y-axis. + * @param {Number} z The force applied by the device in the z-axis. + */ +function Acceleration(x, y, z) { + /** + * The force applied by the device in the x-axis. + */ + this.x = x; + /** + * The force applied by the device in the y-axis. + */ + this.y = y; + /** + * The force applied by the device in the z-axis. + */ + this.z = z; + /** + * The time that the acceleration was obtained. + */ + this.timestamp = new Date().getTime(); +} + +/** + * This class specifies the options for requesting acceleration data. + * @constructor + */ +function AccelerationOptions() { + /** + * The timeout after which if acceleration data cannot be obtained the errorCallback + * is called. + */ + this.timeout = 10000; +} +/** + * This class provides access to device accelerometer data. + * @constructor + */ +function Accelerometer() { + /** + * The last known acceleration. + */ + this.lastAcceleration = null; +} + +/** + * Asynchronously aquires the current acceleration. + * @param {Function} successCallback The function to call when the acceleration + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the acceleration data. + * @param {AccelerationOptions} options The options for getting the accelerometer data + * such as timeout. + */ +Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) { + // If the acceleration is available then call success + // If the acceleration is not available then call error + + // Created for iPhone, Iphone passes back _accel obj litteral + if (typeof successCallback == "function") { + var accel = new Acceleration(_accel.x,_accel.y,_accel.z); + Accelerometer.lastAcceleration = accel; + successCallback(accel); + } +} + +/** + * Asynchronously aquires the acceleration repeatedly at a given interval. + * @param {Function} successCallback The function to call each time the acceleration + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the acceleration data. + * @param {AccelerationOptions} options The options for getting the accelerometer data + * such as timeout. + */ + +Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) { + this.getCurrentAcceleration(successCallback, errorCallback, options); + // TODO: add the interval id to a list so we can clear all watches + var frequency = (options != undefined)? options.frequency : 10000; + return setInterval(function() { + navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options); + }, frequency); +} + +/** + * Clears the specified accelerometer watch. + * @param {String} watchId The ID of the watch returned from #watchAcceleration. + */ +Accelerometer.prototype.clearWatch = function(watchId) { + clearInterval(watchId); +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer(); +}); +/** + * This class provides access to the device camera. + * @constructor + */ +function Camera() { + +} + +/** + * + * @param {Function} successCallback + * @param {Function} errorCallback + * @param {Object} options + */ +Camera.prototype.getPicture = function(successCallback, errorCallback, options) { + +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.camera == "undefined") navigator.camera = new Camera(); +}); +/** + * This class provides access to the device contacts. + * @constructor + */ + +function Contact(jsonObject) { + this.firstName = ""; + this.lastName = ""; + this.name = ""; + this.phones = {}; + this.emails = {}; + this.address = ""; +} + +Contact.prototype.displayName = function() +{ + // TODO: can be tuned according to prefs + return this.name; +} + +function ContactManager() { + // Dummy object to hold array of contacts + this.contacts = []; + this.timestamp = new Date().getTime(); +} + +ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) { + // Interface +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.ContactManager == "undefined") navigator.ContactManager = new ContactManager(); +}); +/** + * This class provides access to the debugging console. + * @constructor + */ +function DebugConsole() { +} + +/** + * Utility function for rendering and indenting strings, or serializing + * objects to a string capable of being printed to the console. + * @param {Object|String} message The string or object to convert to an indented string + * @private + */ +DebugConsole.prototype.processMessage = function(message) { + if (typeof(message) != 'object') { + return message; + } else { + /** + * @function + * @ignore + */ + function indent(str) { + return str.replace(/^/mg, " "); + } + /** + * @function + * @ignore + */ + function makeStructured(obj) { + var str = ""; + for (var i in obj) { + try { + if (typeof(obj[i]) == 'object') { + str += i + ":\n" + indent(makeStructured(obj[i])) + "\n"; + } else { + str += i + " = " + indent(String(obj[i])).replace(/^ /, "") + "\n"; + } + } catch(e) { + str += i + " = EXCEPTION: " + e.message + "\n"; + } + } + return str; + } + return "Object:\n" + makeStructured(message); + } +}; + +/** + * Print a normal log message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.log = function(message) { +}; + +/** + * Print a warning message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.warn = function(message) { +}; + +/** + * Print an error message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.error = function(message) { +}; + +PhoneGap.addConstructor(function() { + window.debug = new DebugConsole(); +}); +/** + * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the + * phone, etc. + * @constructor + */ +function Device() { + this.available = PhoneGap.available; + this.platform = null; + this.version = null; + this.name = null; + this.gap = null; + this.uuid = null; + try { + if (window.DroidGap) { + this.available = true; + this.uuid = window.DroidGap.getUuid(); + this.version = window.DroidGap.getOSVersion(); + this.gapVersion = window.DroidGap.getVersion(); + this.platform = window.DroidGap.getPlatform(); + this.name = window.DroidGap.getProductName(); + } else { + this.platform = DeviceInfo.platform; + this.version = DeviceInfo.version; + this.name = DeviceInfo.name; + this.gap = DeviceInfo.gap; + this.uuid = DeviceInfo.uuid; + } + } catch(e) { + this.available = false; + } +} + +PhoneGap.addConstructor(function() { + navigator.device = window.device = new Device(); + var event = document.createEvent("Events"); + event.initEvent('deviceReady', false, false); + document.dispatchEvent(event); +}); +/** + * This class provides generic read and write access to the mobile device file system. + */ +function File() { + /** + * The data of a file. + */ + this.data = ""; + /** + * The name of the file. + */ + this.name = ""; +} + +/** + * Reads a file from the mobile device. This function is asyncronous. + * @param {String} fileName The name (including the path) to the file on the mobile device. + * The file name will likely be device dependent. + * @param {Function} successCallback The function to call when the file is successfully read. + * @param {Function} errorCallback The function to call when there is an error reading the file from the device. + */ +File.prototype.read = function(fileName, successCallback, errorCallback) { + +} + +/** + * Writes a file to the mobile device. + * @param {File} file The file to write to the device. + */ +File.prototype.write = function(file) { + +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.file == "undefined") navigator.file = new File(); +}); +/** + * This class provides access to device GPS data. + * @constructor + */ +function Geolocation() { + /** + * The last known GPS position. + */ + this.lastPosition = null; + this.lastError = null; + this.callbacks = { + onLocationChanged: [], + onError: [] + }; +}; + +/** + * Asynchronously aquires the current position. + * @param {Function} successCallback The function to call when the position + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the position data. + * @param {PositionOptions} options The options for getting the position data + * such as timeout. + */ +Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) { + var referenceTime = 0; + if (this.lastPosition) + referenceTime = this.lastPosition.timeout; + else + this.start(options); + + var timeout = 20000; + var interval = 500; + if (typeof(options) == 'object' && options.interval) + interval = options.interval; + + if (typeof(successCallback) != 'function') + successCallback = function() {}; + if (typeof(errorCallback) != 'function') + errorCallback = function() {}; + + var dis = this; + var delay = 0; + var timer = setInterval(function() { + delay += interval; + + if (typeof(dis.lastPosition) == 'object' && dis.lastPosition.timestamp > referenceTime) { + successCallback(dis.lastPosition); + clearInterval(timer); + } else if (delay >= timeout) { + errorCallback(); + clearInterval(timer); + } + }, interval); +}; + +/** + * Asynchronously aquires the position repeatedly at a given interval. + * @param {Function} successCallback The function to call each time the position + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the position data. + * @param {PositionOptions} options The options for getting the position data + * such as timeout and the frequency of the watch. + */ +Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) { + // Invoke the appropriate callback with a new Position object every time the implementation + // determines that the position of the hosting device has changed. + + this.getCurrentPosition(successCallback, errorCallback, options); + var frequency = 10000; + if (typeof(options) == 'object' && options.frequency) + frequency = options.frequency; + + var that = this; + return setInterval(function() { + that.getCurrentPosition(successCallback, errorCallback, options); + }, frequency); +}; + + +/** + * Clears the specified position watch. + * @param {String} watchId The ID of the watch returned from #watchPosition. + */ +Geolocation.prototype.clearWatch = function(watchId) { + clearInterval(watchId); +}; + +/** + * Called by the geolocation framework when the current location is found. + * @param {PositionOptions} position The current position. + */ +Geolocation.prototype.setLocation = function(position) { + this.lastPosition = position; + for (var i = 0; i < this.callbacks.onLocationChanged.length; i++) { + var f = this.callbacks.onLocationChanged.shift(); + f(position); + } +}; + +/** + * Called by the geolocation framework when an error occurs while looking up the current position. + * @param {String} message The text of the error message. + */ +Geolocation.prototype.setError = function(message) { + this.lastError = message; + for (var i = 0; i < this.callbacks.onError.length; i++) { + var f = this.callbacks.onError.shift(); + f(message); + } +}; + +PhoneGap.addConstructor(function() { + if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation(); +}); +/** + * This class provides access to native mapping applications on the device. + */ +function Map() { + +} + +/** + * Shows a native map on the device with pins at the given positions. + * @param {Array} positions + */ +Map.prototype.show = function(positions) { + +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.map == "undefined") navigator.map = new Map(); +}); +/** + * This class provides access to the device media, interfaces to both sound and video + * @constructor + */ +function Media(src, successCallback, errorCallback) { + this.src = src; + this.successCallback = successCallback; + this.errorCallback = errorCallback; +} + +Media.prototype.record = function() { +} + +Media.prototype.play = function() { +} + +Media.prototype.pause = function() { +} + +Media.prototype.stop = function() { +} + + +/** + * This class contains information about any Media errors. + * @constructor + */ +function MediaError() { + this.code = null, + this.message = ""; +} + +MediaError.MEDIA_ERR_ABORTED = 1; +MediaError.MEDIA_ERR_NETWORK = 2; +MediaError.MEDIA_ERR_DECODE = 3; +MediaError.MEDIA_ERR_NONE_SUPPORTED = 4; + + +//if (typeof navigator.audio == "undefined") navigator.audio = new Media(src); +/** + * This class contains information about any NetworkStatus. + * @constructor + */ +function NetworkStatus() { + this.code = null; + this.message = ""; +} + +NetworkStatus.NOT_REACHABLE = 0; +NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK = 1; +NetworkStatus.REACHABLE_VIA_WIFI_NETWORK = 2; + +/** + * This class provides access to device Network data (reachability). + * @constructor + */ +function Network() { + /** + * The last known Network status. + * { hostName: string, ipAddress: string, + remoteHostStatus: int(0/1/2), internetConnectionStatus: int(0/1/2), localWiFiConnectionStatus: int (0/2) } + */ + this.lastReachability = null; +}; + +/** + * + * @param {Function} successCallback + * @param {Function} errorCallback + * @param {Object} options (isIpAddress:boolean) + */ +Network.prototype.isReachable = function(hostName, successCallback, options) { +} + +/** + * Called by the geolocation framework when the reachability status has changed. + * @param {Reachibility} reachability The current reachability status. + */ +Network.prototype.updateReachability = function(reachability) { + this.lastReachability = reachability; +}; + +PhoneGap.addConstructor(function() { + if (typeof navigator.network == "undefined") navigator.network = new Network(); +}); +/** + * This class provides access to notifications on the device. + */ +function Notification() { + +} + +/** + * Open a native alert dialog, with a customizable title and button text. + * @param {String} message Message to print in the body of the alert + * @param {String} [title="Alert"] Title of the alert dialog (default: Alert) + * @param {String} [buttonLabel="OK"] Label of the close button (default: OK) + */ +Notification.prototype.alert = function(message, title, buttonLabel) { + // Default is to use a browser alert; this will use "index.html" as the title though + alert(message); +}; + +/** + * Start spinning the activity indicator on the statusbar + */ +Notification.prototype.activityStart = function() { +}; + +/** + * Stop spinning the activity indicator on the statusbar, if it's currently spinning + */ +Notification.prototype.activityStop = function() { +}; + +/** + * Causes the device to blink a status LED. + * @param {Integer} count The number of blinks. + * @param {String} colour The colour of the light. + */ +Notification.prototype.blink = function(count, colour) { + +}; + +/** + * Causes the device to vibrate. + * @param {Integer} mills The number of milliseconds to vibrate for. + */ +Notification.prototype.vibrate = function(mills) { + +}; + +/** + * Causes the device to beep. + * @param {Integer} count The number of beeps. + * @param {Integer} volume The volume of the beep. + */ +Notification.prototype.beep = function(count, volume) { + +}; + +// TODO: of course on Blackberry and Android there notifications in the UI as well + +PhoneGap.addConstructor(function() { + if (typeof navigator.notification == "undefined") navigator.notification = new Notification(); +}); + +/** + * This class provides access to the device orientation. + * @constructor + */ +function Orientation() { + /** + * The current orientation, or null if the orientation hasn't changed yet. + */ + this.currentOrientation = null; +} + +/** + * Set the current orientation of the phone. This is called from the device automatically. + * + * When the orientation is changed, the DOMEvent \c orientationChanged is dispatched against + * the document element. The event has the property \c orientation which can be used to retrieve + * the device's current orientation, in addition to the \c Orientation.currentOrientation class property. + * + * @param {Number} orientation The orientation to be set + */ +Orientation.prototype.setOrientation = function(orientation) { + Orientation.currentOrientation = orientation; + var e = document.createEvent('Events'); + e.initEvent('orientationChanged', 'false', 'false'); + e.orientation = orientation; + document.dispatchEvent(e); +}; + +/** + * Asynchronously aquires the current orientation. + * @param {Function} successCallback The function to call when the orientation + * is known. + * @param {Function} errorCallback The function to call when there is an error + * getting the orientation. + */ +Orientation.prototype.getCurrentOrientation = function(successCallback, errorCallback) { + // If the position is available then call success + // If the position is not available then call error +}; + +/** + * Asynchronously aquires the orientation repeatedly at a given interval. + * @param {Function} successCallback The function to call each time the orientation + * data is available. + * @param {Function} errorCallback The function to call when there is an error + * getting the orientation data. + */ +Orientation.prototype.watchOrientation = function(successCallback, errorCallback) { + // Invoke the appropriate callback with a new Position object every time the implementation + // determines that the position of the hosting device has changed. + this.getCurrentPosition(successCallback, errorCallback); + return setInterval(function() { + navigator.orientation.getCurrentOrientation(successCallback, errorCallback); + }, 10000); +}; + +/** + * Clears the specified orientation watch. + * @param {String} watchId The ID of the watch returned from #watchOrientation. + */ +Orientation.prototype.clearWatch = function(watchId) { + clearInterval(watchId); +}; + +PhoneGap.addConstructor(function() { + if (typeof navigator.orientation == "undefined") navigator.orientation = new Orientation(); +}); +/** + * This class contains position information. + * @param {Object} lat + * @param {Object} lng + * @param {Object} acc + * @param {Object} alt + * @param {Object} altacc + * @param {Object} head + * @param {Object} vel + * @constructor + */ +function Position(coords, timestamp) { + this.coords = coords; + this.timestamp = new Date().getTime(); +} + +function Coordinates(lat, lng, alt, acc, head, vel) { + /** + * The latitude of the position. + */ + this.latitude = lat; + /** + * The longitude of the position, + */ + this.longitude = lng; + /** + * The accuracy of the position. + */ + this.accuracy = acc; + /** + * The altitude of the position. + */ + this.altitude = alt; + /** + * The direction the device is moving at the position. + */ + this.heading = head; + /** + * The velocity with which the device is moving at the position. + */ + this.speed = vel; +} + +/** + * This class specifies the options for requesting position data. + * @constructor + */ +function PositionOptions() { + /** + * Specifies the desired position accuracy. + */ + this.enableHighAccuracy = true; + /** + * The timeout after which if position data cannot be obtained the errorCallback + * is called. + */ + this.timeout = 10000; +} + +/** + * This class contains information about any GSP errors. + * @constructor + */ +function PositionError() { + this.code = null; + this.message = ""; +} + +PositionError.UNKNOWN_ERROR = 0; +PositionError.PERMISSION_DENIED = 1; +PositionError.POSITION_UNAVAILABLE = 2; +PositionError.TIMEOUT = 3; +/** + * This class provides access to the device SMS functionality. + * @constructor + */ +function Sms() { + +} + +/** + * Sends an SMS message. + * @param {Integer} number The phone number to send the message to. + * @param {String} message The contents of the SMS message to send. + * @param {Function} successCallback The function to call when the SMS message is sent. + * @param {Function} errorCallback The function to call when there is an error sending the SMS message. + * @param {PositionOptions} options The options for accessing the GPS location such as timeout and accuracy. + */ +Sms.prototype.send = function(number, message, successCallback, errorCallback, options) { + +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.sms == "undefined") navigator.sms = new Sms(); +}); +/** + * This class provides access to the telephony features of the device. + * @constructor + */ +function Telephony() { + +} + +/** + * Calls the specifed number. + * @param {Integer} number The number to be called. + */ +Telephony.prototype.call = function(number) { + +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.telephony == "undefined") navigator.telephony = new Telephony(); +}); +/** + * This class exposes mobile phone interface controls to JavaScript, such as + * native tab and tool bars, etc. + * @constructor + */ +function UIControls() { + this.tabBarTag = 0; + this.tabBarCallbacks = {}; +} + +/** + * Create a native tab bar that can have tab buttons added to it which can respond to events. + */ +UIControls.prototype.createTabBar = function() {}; + +/** + * Show a tab bar. The tab bar has to be created first. + * @param {Object} [options] Options indicating how the tab bar should be shown: + * - \c height integer indicating the height of the tab bar (default: \c 49) + * - \c position specifies whether the tab bar will be placed at the \c top or \c bottom of the screen (default: \c bottom) + */ +UIControls.prototype.showTabBar = function(options) {}; + +/** + * Hide a tab bar. The tab bar has to be created first. + */ +UIControls.prototype.hideTabBar = function(animate) {}; + +/** + * Create a new tab bar item for use on a previously created tab bar. Use ::showTabBarItems to show the new item on the tab bar. + * + * If the supplied image name is one of the labels listed below, then this method will construct a tab button + * using the standard system buttons. Note that if you use one of the system images, that the \c title you supply will be ignored. + * + * Tab Buttons + * - tabButton:More + * - tabButton:Favorites + * - tabButton:Featured + * - tabButton:TopRated + * - tabButton:Recents + * - tabButton:Contacts + * - tabButton:History + * - tabButton:Bookmarks + * - tabButton:Search + * - tabButton:Downloads + * - tabButton:MostRecent + * - tabButton:MostViewed + * @param {String} name internal name to refer to this tab by + * @param {String} [title] title text to show on the tab, or null if no text should be shown + * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown + * @param {Object} [options] Options for customizing the individual tab item + * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden + */ +UIControls.prototype.createTabBarItem = function(name, label, image, options) {}; + +/** + * Update an existing tab bar item to change its badge value. + * @param {String} name internal name used to represent this item when it was created + * @param {Object} options Options for customizing the individual tab item + * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden + */ +UIControls.prototype.updateTabBarItem = function(name, options) {}; + +/** + * Show previously created items on the tab bar + * @param {String} arguments... the item names to be shown + * @param {Object} [options] dictionary of options, notable options including: + * - \c animate indicates that the items should animate onto the tab bar + * @see createTabBarItem + * @see createTabBar + */ +UIControls.prototype.showTabBarItems = function(tabs, options) {}; + +/** + * Manually select an individual tab bar item, or nil for deselecting a currently selected tab bar item. + * @param {String} tabName the name of the tab to select, or null if all tabs should be deselected + * @see createTabBarItem + * @see showTabBarItems + */ +UIControls.prototype.selectTabBarItem = function(tab) {}; + +/** + * Function called when a tab bar item has been selected. + * @param {Number} tag the tag number for the item that has been selected + */ +UIControls.prototype.tabBarItemSelected = function(tag) { + if (typeof(this.tabBarCallbacks[tag]) == 'function') + this.tabBarCallbacks[tag](); +}; + +/** + * Create a toolbar. + */ +UIControls.prototype.createToolBar = function() {}; + +/** + * Function called when a tab bar item has been selected. + * @param {String} title the title to set within the toolbar + */ +UIControls.prototype.setToolBarTitle = function(title) {}; + +PhoneGap.addConstructor(function() { + window.uicontrols = new UIControls(); +}); +/* +* Since we can't guarantee that we will have the most recent, we just try our best! +* +* Also, the API doesn't specify which version is the best version of the API +*/ + +Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) +{ + var position = Geo.getCurrentLocation(); + this.global_success = successCallback; + this.fail = errorCallback; +} + + +// Run the global callback +Geolocation.prototype.gotCurrentPosition = function(lat, lng, alt, altacc, head, vel, stamp) +{ + if (lat == "undefined" || lng == "undefined") + { + this.fail(); + } + else + { + coords = new Coordinates(lat, lng, alt, altacc, head, vel); + loc = new Position(coords, stamp); + this.global_success(loc); + } +} + +/* +* This turns on the GeoLocator class, which has two listeners. +* The listeners have their own timeouts, and run independently of this process +* In this case, we return the key to the watch hash +*/ + +Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) +{ + var frequency = (options != undefined)? options.frequency : 10000; + + if (!this.listeners) + { + this.listeners = []; + } + + var key = this.listeners.push( {"success" : successCallback, "fail" : failCallback }) - 1; + + // TO-DO: Get the names of the method and pass them as strings to the Java. + return Geolocation.start(frequency, key); +} + +/* + * Retrieve and stop this listener from listening to the GPS + * + */ +Geolocation.prototype.success = function(key, lat, lng, alt, altacc, head, vel, stamp) +{ + var coords = new Coordinates(lat, lng, alt, altacc, head, vel); + var loc = new Position(coords, stamp); + this.listeners[key].success(loc); +} + +Geolocation.prototype.fail = function(key) +{ + this.listeners[key].fail(); +} + +Geolocation.prototype.clearWatch = function(watchId) +{ + Geo.stop(watchId); +} +Notification.prototype.vibrate = function(mills) +{ + DroidGap.vibrate(mills); +} + +/* + * On the Android, we don't beep, we notify you with your + * notification! We shouldn't keep hammering on this, and should + * review what we want beep to do. + */ + +Notification.prototype.beep = function(count, volume) +{ + DroidGap.beep(count); +} +// Need to define these for android +_accel = {} +_accel.x = 0; +_accel.y = 0; +_accel.z = 0; + +function gotAccel(x, y, z) +{ + _accel.x = x; + _accel.y = y; + _accel.z = z; +} + +/** + * This class provides access to device accelerometer data. + * @constructor + */ +function Accelerometer() { + /** + * The last known acceleration. + */ + this.lastAcceleration = null; +} + +/** + * Asynchronously aquires the current acceleration. + * @param {Function} successCallback The function to call when the acceleration + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the acceleration data. + * @param {AccelerationOptions} options The options for getting the accelerometer data + * such as timeout. + */ +Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) { + // If the acceleration is available then call success + // If the acceleration is not available then call error + + // Created for iPhone, Iphone passes back _accel obj litteral + if (typeof successCallback == "function") { + var accel = new Acceleration(_accel.x,_accel.y,_accel.z); + Accelerometer.lastAcceleration = accel; + successCallback(accel); + } +} + +/** + * Asynchronously aquires the acceleration repeatedly at a given interval. + * @param {Function} successCallback The function to call each time the acceleration + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the acceleration data. + * @param {AccelerationOptions} options The options for getting the accelerometer data + * such as timeout. + */ + +Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) { + // TODO: add the interval id to a list so we can clear all watches + var frequency = (options != undefined)? options.frequency : 10000; + + Accel.start(frequency); + return setInterval(function() { + navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options); + }, frequency); +} + +/** + * Clears the specified accelerometer watch. + * @param {String} watchId The ID of the watch returned from #watchAcceleration. + */ +Accelerometer.prototype.clearWatch = function(watchId) { + Accel.stop(); + clearInterval(watchId); +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer(); +}); +/** + * This class provides access to the device camera. + * @constructor + */ +function Camera() { + +} + +/** + * + * @param {Function} successCallback + * @param {Function} errorCallback + * @param {Object} options + */ +Camera.prototype.getPicture = function(successCallback, errorCallback, options) { + + this.winCallback = successCallback; + this.failCallback = errorCallback; + if (options.quality) + { + GapCam.takePicture(options.quality); + } + else + { + GapCam.takePicture(80); + } +} + +Camera.prototype.win = function(picture) +{ + this.winCallback(picture); +} + +Camera.prototype.fail = function(err) +{ + this.failCallback(err); +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.camera == "undefined") navigator.camera = new Camera(); +}); +ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) { + this.win = successCallback; + this.fail = errorCallback; + ContactHook.getContactsAndSendBack(); +} + +ContactManager.prototype.droidAddContact = function(name, phone, email) +{ + var contact = new Contact(); + contact.name = name; + contact.phones.primary = phone; + contact.emails.primary = email; + this.contacts.push(contact); +} + +ContactManager.prototype.droidDone = function() +{ + win(this.contacts); +} + +/** + * This class provides access to the device media, interfaces to both sound and video + * @constructor + */ + +Media.prototype.play = function() { + DroidGap.startPlayingAudio(this.src); +} + +Media.prototype.stop = function() { + DroidGap.stopPlayingAudio(); +} + +Media.prototype.startRecord = function() { + DroidGap.startRecordingAudio(this.src); +} + +Media.prototype.stopRecordingAudio = function() { + DroidGap.stopRecordingAudio(); +} + + + +File.prototype.read = function(fileName, successCallback, errorCallback) { + this.failCallback = errorCallback; + this.winCallback = successCallback; + + return FileUtil.read(fileName); +} + +File.prototype.hasRead = function(data) +{ + if(data.substr("FAIL")) + this.failCallback(data); + else + this.winCallback(data); +} + +/** + * Writes a file to the mobile device. + * @param {File} file The file to write to the device. + */ +File.prototype.write = function(file, str, mode, successCallback, failCallback) { + this.winCallback = successCallback; + this.failCallback = failCallback; + var call = FileUtil.write(file, str, mode); +} + +File.prototype.testFileExists = function(file, successCallback, failCallback) +{ + var exists = FileUtil.testFileExists(file); + if(exists) + successCallback(); + else + failCallback(); + return exists; +} + +File.prototype.testDirectoryExists = function(file, successCallback, failCallback) +{ + var exists = FileUtil.testDirectoryExists(file); + if(exists) + successCallback(); + else + failCallback(); + return exists; +} + +File.prototype.createDirectory = function(dir, successCallback, failCallback) +{ + var good = FileUtils.createDirectory(dir); + good ? successCallback() : failCallback(); +} + +File.prototype.deleteDirectory = function(dir, successCallback, failCallback) +{ + var good = FileUtils.deleteDirectory(dir); + good ? successCallback() : failCallback(); +} + +File.prototype.deleteFile = function(dir, successCallback, failCallback) +{ + var good = FileUtils.deleteFile(dir); + good ? successCallback() : failCallback(); +} + +File.prototype.getFreeDiskSpace = function(successCallback, failCallback) +{ + var diskSpace = FileUtils.getFreeDiskSpace(); + if(diskSpace > 0) + successCallback(); + else + failCallback(); + return diskSpace; +} +Network.prototype.isReachable = function(uri, win, options) +{ + var status = new NetworkStatus(); + if(NetworkManager.isReachable(uri)) + { + if (NetworkManager.isWifiActive) + status.code = 2; + else + status.code = 1; + } + else + status.code = 0; + win(status); +} diff --git a/framework/bin/PhoneGap.apk b/framework/bin/PhoneGap.apk new file mode 100644 index 00000000..dea84357 Binary files /dev/null and b/framework/bin/PhoneGap.apk differ diff --git a/framework/bin/classes.dex b/framework/bin/classes.dex new file mode 100644 index 00000000..9b652298 Binary files /dev/null and b/framework/bin/classes.dex differ diff --git a/framework/bin/com/phonegap/AccelListener.class b/framework/bin/com/phonegap/AccelListener.class new file mode 100644 index 00000000..72b22748 Binary files /dev/null and b/framework/bin/com/phonegap/AccelListener.class differ diff --git a/framework/bin/com/phonegap/AccelTuple.class b/framework/bin/com/phonegap/AccelTuple.class new file mode 100644 index 00000000..34578361 Binary files /dev/null and b/framework/bin/com/phonegap/AccelTuple.class differ diff --git a/framework/bin/com/phonegap/AudioHandler$1.class b/framework/bin/com/phonegap/AudioHandler$1.class new file mode 100644 index 00000000..974aa36d Binary files /dev/null and b/framework/bin/com/phonegap/AudioHandler$1.class differ diff --git a/framework/bin/com/phonegap/AudioHandler.class b/framework/bin/com/phonegap/AudioHandler.class new file mode 100644 index 00000000..d5f3b07a Binary files /dev/null and b/framework/bin/com/phonegap/AudioHandler.class differ diff --git a/framework/bin/com/phonegap/CameraLauncher.class b/framework/bin/com/phonegap/CameraLauncher.class new file mode 100644 index 00000000..a7da68e8 Binary files /dev/null and b/framework/bin/com/phonegap/CameraLauncher.class differ diff --git a/framework/bin/com/phonegap/CameraPreview$1.class b/framework/bin/com/phonegap/CameraPreview$1.class new file mode 100644 index 00000000..3f5bc081 Binary files /dev/null and b/framework/bin/com/phonegap/CameraPreview$1.class differ diff --git a/framework/bin/com/phonegap/CameraPreview$2.class b/framework/bin/com/phonegap/CameraPreview$2.class new file mode 100644 index 00000000..442d7e65 Binary files /dev/null and b/framework/bin/com/phonegap/CameraPreview$2.class differ diff --git a/framework/bin/com/phonegap/CameraPreview$3.class b/framework/bin/com/phonegap/CameraPreview$3.class new file mode 100644 index 00000000..5c245f92 Binary files /dev/null and b/framework/bin/com/phonegap/CameraPreview$3.class differ diff --git a/framework/bin/com/phonegap/CameraPreview.class b/framework/bin/com/phonegap/CameraPreview.class new file mode 100644 index 00000000..2bace213 Binary files /dev/null and b/framework/bin/com/phonegap/CameraPreview.class differ diff --git a/framework/bin/com/phonegap/CompassListener.class b/framework/bin/com/phonegap/CompassListener.class new file mode 100644 index 00000000..627909c4 Binary files /dev/null and b/framework/bin/com/phonegap/CompassListener.class differ diff --git a/framework/bin/com/phonegap/ContactManager$ContactTriplet.class b/framework/bin/com/phonegap/ContactManager$ContactTriplet.class new file mode 100644 index 00000000..7142cbda Binary files /dev/null and b/framework/bin/com/phonegap/ContactManager$ContactTriplet.class differ diff --git a/framework/bin/com/phonegap/ContactManager.class b/framework/bin/com/phonegap/ContactManager.class new file mode 100644 index 00000000..44d5752f Binary files /dev/null and b/framework/bin/com/phonegap/ContactManager.class differ diff --git a/framework/bin/com/phonegap/DirectoryManager.class b/framework/bin/com/phonegap/DirectoryManager.class new file mode 100644 index 00000000..d4f6aeb4 Binary files /dev/null and b/framework/bin/com/phonegap/DirectoryManager.class differ diff --git a/framework/bin/com/phonegap/DroidGap$GapClient.class b/framework/bin/com/phonegap/DroidGap$GapClient.class new file mode 100644 index 00000000..4898bc10 Binary files /dev/null and b/framework/bin/com/phonegap/DroidGap$GapClient.class differ diff --git a/framework/bin/com/phonegap/DroidGap.class b/framework/bin/com/phonegap/DroidGap.class new file mode 100644 index 00000000..deeadb68 Binary files /dev/null and b/framework/bin/com/phonegap/DroidGap.class differ diff --git a/framework/bin/com/phonegap/FileUtils.class b/framework/bin/com/phonegap/FileUtils.class new file mode 100644 index 00000000..8372afb3 Binary files /dev/null and b/framework/bin/com/phonegap/FileUtils.class differ diff --git a/framework/bin/com/phonegap/GeoBroker.class b/framework/bin/com/phonegap/GeoBroker.class new file mode 100644 index 00000000..a3c19b0f Binary files /dev/null and b/framework/bin/com/phonegap/GeoBroker.class differ diff --git a/framework/bin/com/phonegap/GeoListener.class b/framework/bin/com/phonegap/GeoListener.class new file mode 100644 index 00000000..9eeea961 Binary files /dev/null and b/framework/bin/com/phonegap/GeoListener.class differ diff --git a/framework/bin/com/phonegap/GeoTuple.class b/framework/bin/com/phonegap/GeoTuple.class new file mode 100644 index 00000000..c1d38218 Binary files /dev/null and b/framework/bin/com/phonegap/GeoTuple.class differ diff --git a/framework/bin/com/phonegap/GpsListener.class b/framework/bin/com/phonegap/GpsListener.class new file mode 100644 index 00000000..65b0ca49 Binary files /dev/null and b/framework/bin/com/phonegap/GpsListener.class differ diff --git a/framework/bin/com/phonegap/HttpHandler.class b/framework/bin/com/phonegap/HttpHandler.class new file mode 100644 index 00000000..f01a1209 Binary files /dev/null and b/framework/bin/com/phonegap/HttpHandler.class differ diff --git a/framework/bin/com/phonegap/NetworkListener.class b/framework/bin/com/phonegap/NetworkListener.class new file mode 100644 index 00000000..db1ffa06 Binary files /dev/null and b/framework/bin/com/phonegap/NetworkListener.class differ diff --git a/framework/bin/com/phonegap/NetworkManager.class b/framework/bin/com/phonegap/NetworkManager.class new file mode 100644 index 00000000..7bc9e3f8 Binary files /dev/null and b/framework/bin/com/phonegap/NetworkManager.class differ diff --git a/framework/bin/com/phonegap/Orientation.class b/framework/bin/com/phonegap/Orientation.class new file mode 100644 index 00000000..777baf5a Binary files /dev/null and b/framework/bin/com/phonegap/Orientation.class differ diff --git a/framework/bin/com/phonegap/PhoneGap.class b/framework/bin/com/phonegap/PhoneGap.class new file mode 100644 index 00000000..c236a509 Binary files /dev/null and b/framework/bin/com/phonegap/PhoneGap.class differ diff --git a/framework/bin/com/phonegap/PhoneGapView.class b/framework/bin/com/phonegap/PhoneGapView.class new file mode 100644 index 00000000..e1d68509 Binary files /dev/null and b/framework/bin/com/phonegap/PhoneGapView.class differ diff --git a/framework/bin/com/phonegap/R$attr.class b/framework/bin/com/phonegap/R$attr.class new file mode 100644 index 00000000..4c7a0de0 Binary files /dev/null and b/framework/bin/com/phonegap/R$attr.class differ diff --git a/framework/bin/com/phonegap/R$drawable.class b/framework/bin/com/phonegap/R$drawable.class new file mode 100644 index 00000000..86d03fa0 Binary files /dev/null and b/framework/bin/com/phonegap/R$drawable.class differ diff --git a/framework/bin/com/phonegap/R$id.class b/framework/bin/com/phonegap/R$id.class new file mode 100644 index 00000000..61b98c3e Binary files /dev/null and b/framework/bin/com/phonegap/R$id.class differ diff --git a/framework/bin/com/phonegap/R$layout.class b/framework/bin/com/phonegap/R$layout.class new file mode 100644 index 00000000..ed894106 Binary files /dev/null and b/framework/bin/com/phonegap/R$layout.class differ diff --git a/framework/bin/com/phonegap/R$raw.class b/framework/bin/com/phonegap/R$raw.class new file mode 100644 index 00000000..b33be07c Binary files /dev/null and b/framework/bin/com/phonegap/R$raw.class differ diff --git a/framework/bin/com/phonegap/R$string.class b/framework/bin/com/phonegap/R$string.class new file mode 100644 index 00000000..f5e288ab Binary files /dev/null and b/framework/bin/com/phonegap/R$string.class differ diff --git a/framework/bin/com/phonegap/R.class b/framework/bin/com/phonegap/R.class new file mode 100644 index 00000000..5ee95ed7 Binary files /dev/null and b/framework/bin/com/phonegap/R.class differ diff --git a/framework/bin/com/phonegap/SmsListener.class b/framework/bin/com/phonegap/SmsListener.class new file mode 100644 index 00000000..69f9266b Binary files /dev/null and b/framework/bin/com/phonegap/SmsListener.class differ diff --git a/framework/bin/com/phonegap/TempListener.class b/framework/bin/com/phonegap/TempListener.class new file mode 100644 index 00000000..4225754f Binary files /dev/null and b/framework/bin/com/phonegap/TempListener.class differ diff --git a/framework/bin/com/phonegap/VideoPreview.class b/framework/bin/com/phonegap/VideoPreview.class new file mode 100644 index 00000000..4caf80b9 Binary files /dev/null and b/framework/bin/com/phonegap/VideoPreview.class differ diff --git a/framework/bin/resources.ap_ b/framework/bin/resources.ap_ new file mode 100644 index 00000000..745e4940 Binary files /dev/null and b/framework/bin/resources.ap_ differ diff --git a/build.xml b/framework/build.xml similarity index 100% rename from build.xml rename to framework/build.xml diff --git a/default.properties b/framework/default.properties similarity index 100% rename from default.properties rename to framework/default.properties diff --git a/export-phonegap.jardesc b/framework/export-phonegap.jardesc similarity index 100% rename from export-phonegap.jardesc rename to framework/export-phonegap.jardesc diff --git a/framework/gen/com/phonegap/R.java b/framework/gen/com/phonegap/R.java new file mode 100644 index 00000000..db7185cc --- /dev/null +++ b/framework/gen/com/phonegap/R.java @@ -0,0 +1,35 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package com.phonegap; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int icon=0x7f020000; + } + public static final class id { + public static final int appView=0x7f060000; + public static final int go=0x7f060002; + public static final int surface=0x7f060001; + } + public static final class layout { + public static final int main=0x7f030000; + public static final int preview=0x7f030001; + } + public static final class raw { + public static final int bird=0x7f040000; + public static final int off=0x7f040001; + public static final int on=0x7f040002; + } + public static final class string { + public static final int app_name=0x7f050000; + public static final int go=0x7f050002; + public static final int url=0x7f050001; + } +} diff --git a/libs/commons-codec-1.3.jar b/framework/libs/commons-codec-1.3.jar similarity index 100% rename from libs/commons-codec-1.3.jar rename to framework/libs/commons-codec-1.3.jar diff --git a/local.properties b/framework/local.properties similarity index 100% rename from local.properties rename to framework/local.properties diff --git a/res/drawable/icon.png b/framework/res/drawable/icon.png similarity index 100% rename from res/drawable/icon.png rename to framework/res/drawable/icon.png diff --git a/res/layout/main.xml b/framework/res/layout/main.xml similarity index 100% rename from res/layout/main.xml rename to framework/res/layout/main.xml diff --git a/res/layout/preview.xml b/framework/res/layout/preview.xml similarity index 100% rename from res/layout/preview.xml rename to framework/res/layout/preview.xml diff --git a/res/raw/bird.mp3 b/framework/res/raw/bird.mp3 similarity index 100% rename from res/raw/bird.mp3 rename to framework/res/raw/bird.mp3 diff --git a/res/raw/off.mp3 b/framework/res/raw/off.mp3 similarity index 100% rename from res/raw/off.mp3 rename to framework/res/raw/off.mp3 diff --git a/res/raw/on.mp3 b/framework/res/raw/on.mp3 similarity index 100% rename from res/raw/on.mp3 rename to framework/res/raw/on.mp3 diff --git a/res/values/strings.xml b/framework/res/values/strings.xml similarity index 100% rename from res/values/strings.xml rename to framework/res/values/strings.xml diff --git a/src/com/phonegap/AccelListener.java b/framework/src/com/phonegap/AccelListener.java similarity index 100% rename from src/com/phonegap/AccelListener.java rename to framework/src/com/phonegap/AccelListener.java diff --git a/src/com/phonegap/AccelTuple.java b/framework/src/com/phonegap/AccelTuple.java similarity index 100% rename from src/com/phonegap/AccelTuple.java rename to framework/src/com/phonegap/AccelTuple.java diff --git a/src/com/phonegap/AudioHandler.java b/framework/src/com/phonegap/AudioHandler.java similarity index 100% rename from src/com/phonegap/AudioHandler.java rename to framework/src/com/phonegap/AudioHandler.java diff --git a/src/com/phonegap/CameraLauncher.java b/framework/src/com/phonegap/CameraLauncher.java similarity index 100% rename from src/com/phonegap/CameraLauncher.java rename to framework/src/com/phonegap/CameraLauncher.java diff --git a/src/com/phonegap/CameraPreview.java b/framework/src/com/phonegap/CameraPreview.java similarity index 100% rename from src/com/phonegap/CameraPreview.java rename to framework/src/com/phonegap/CameraPreview.java diff --git a/src/com/phonegap/CompassListener.java b/framework/src/com/phonegap/CompassListener.java similarity index 100% rename from src/com/phonegap/CompassListener.java rename to framework/src/com/phonegap/CompassListener.java diff --git a/src/com/phonegap/ContactManager.java b/framework/src/com/phonegap/ContactManager.java similarity index 100% rename from src/com/phonegap/ContactManager.java rename to framework/src/com/phonegap/ContactManager.java diff --git a/src/com/phonegap/DirectoryManager.java b/framework/src/com/phonegap/DirectoryManager.java similarity index 100% rename from src/com/phonegap/DirectoryManager.java rename to framework/src/com/phonegap/DirectoryManager.java diff --git a/src/com/phonegap/DroidGap.java b/framework/src/com/phonegap/DroidGap.java similarity index 100% rename from src/com/phonegap/DroidGap.java rename to framework/src/com/phonegap/DroidGap.java diff --git a/src/com/phonegap/FileUtils.java b/framework/src/com/phonegap/FileUtils.java similarity index 100% rename from src/com/phonegap/FileUtils.java rename to framework/src/com/phonegap/FileUtils.java diff --git a/src/com/phonegap/GeoBroker.java b/framework/src/com/phonegap/GeoBroker.java similarity index 100% rename from src/com/phonegap/GeoBroker.java rename to framework/src/com/phonegap/GeoBroker.java diff --git a/src/com/phonegap/GeoListener.java b/framework/src/com/phonegap/GeoListener.java similarity index 100% rename from src/com/phonegap/GeoListener.java rename to framework/src/com/phonegap/GeoListener.java diff --git a/src/com/phonegap/GeoTuple.java b/framework/src/com/phonegap/GeoTuple.java similarity index 100% rename from src/com/phonegap/GeoTuple.java rename to framework/src/com/phonegap/GeoTuple.java diff --git a/src/com/phonegap/GpsListener.java b/framework/src/com/phonegap/GpsListener.java similarity index 100% rename from src/com/phonegap/GpsListener.java rename to framework/src/com/phonegap/GpsListener.java diff --git a/src/com/phonegap/HttpHandler.java b/framework/src/com/phonegap/HttpHandler.java similarity index 100% rename from src/com/phonegap/HttpHandler.java rename to framework/src/com/phonegap/HttpHandler.java diff --git a/src/com/phonegap/NetworkListener.java b/framework/src/com/phonegap/NetworkListener.java similarity index 100% rename from src/com/phonegap/NetworkListener.java rename to framework/src/com/phonegap/NetworkListener.java diff --git a/src/com/phonegap/NetworkManager.java b/framework/src/com/phonegap/NetworkManager.java similarity index 100% rename from src/com/phonegap/NetworkManager.java rename to framework/src/com/phonegap/NetworkManager.java diff --git a/src/com/phonegap/Orientation.java b/framework/src/com/phonegap/Orientation.java similarity index 100% rename from src/com/phonegap/Orientation.java rename to framework/src/com/phonegap/Orientation.java diff --git a/src/com/phonegap/PhoneGap.java b/framework/src/com/phonegap/PhoneGap.java similarity index 100% rename from src/com/phonegap/PhoneGap.java rename to framework/src/com/phonegap/PhoneGap.java diff --git a/framework/src/com/phonegap/PhoneGapView.java b/framework/src/com/phonegap/PhoneGapView.java new file mode 100644 index 00000000..9fd6e785 --- /dev/null +++ b/framework/src/com/phonegap/PhoneGapView.java @@ -0,0 +1,74 @@ +package com.phonegap; + + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.webkit.WebView; + + +public class PhoneGapView extends WebView { + + private Activity mCtx; + private PhoneGap gap; + private GeoBroker geo; + private AccelListener accel; + private ContactManager mContacts; + private FileUtils fs; + private NetworkManager netMan; + private CameraLauncher launcher; + + public PhoneGapView(Activity action){ + super((Context) action); + mCtx = action; + } + + public void loadUrl(String url) + { + super.loadUrl(url); + bindBrowser(); + } + + private void bindBrowser() + { + gap = new PhoneGap(mCtx, this); + geo = new GeoBroker(this, mCtx); + accel = new AccelListener(mCtx, this); + mContacts = new ContactManager(mCtx, this); + fs = new FileUtils(this); + netMan = new NetworkManager(mCtx, this); + + // This creates the new javascript interfaces for PhoneGap + this.addJavascriptInterface(gap, "DroidGap"); + this.addJavascriptInterface(geo, "Geo"); + this.addJavascriptInterface(accel, "Accel"); + this.addJavascriptInterface(mContacts, "ContactHook"); + this.addJavascriptInterface(fs, "FileUtil"); + this.addJavascriptInterface(netMan, "NetworkManager"); + } + + // This is required to start the camera activity! It has to come from the previous activity + public void startCamera(int quality) + { + Intent i = new Intent(mCtx, CameraPreview.class); + i.setAction("android.intent.action.PICK"); + i.putExtra("quality", quality); + mCtx.startActivityForResult(i, 0); + } + + protected void processResult(int requestCode, int resultCode, Intent intent) + { + String data; + if (resultCode == mCtx.RESULT_OK) + { + data = intent.getStringExtra("picture"); + // Send the graphic back to the class that needs it + launcher.processPicture(data); + } + else + { + launcher.failPicture("Did not complete!"); + } + } + +} diff --git a/src/com/phonegap/SmsListener.java b/framework/src/com/phonegap/SmsListener.java similarity index 100% rename from src/com/phonegap/SmsListener.java rename to framework/src/com/phonegap/SmsListener.java diff --git a/src/com/phonegap/TempListener.java b/framework/src/com/phonegap/TempListener.java similarity index 100% rename from src/com/phonegap/TempListener.java rename to framework/src/com/phonegap/TempListener.java diff --git a/src/com/phonegap/VideoPreview.java b/framework/src/com/phonegap/VideoPreview.java similarity index 100% rename from src/com/phonegap/VideoPreview.java rename to framework/src/com/phonegap/VideoPreview.java diff --git a/js/accelerometer.js b/js/accelerometer.js new file mode 100644 index 00000000..4d89ced1 --- /dev/null +++ b/js/accelerometer.js @@ -0,0 +1,77 @@ +// Need to define these for android +_accel = {} +_accel.x = 0; +_accel.y = 0; +_accel.z = 0; + +function gotAccel(x, y, z) +{ + _accel.x = x; + _accel.y = y; + _accel.z = z; +} + +/** + * This class provides access to device accelerometer data. + * @constructor + */ +function Accelerometer() { + /** + * The last known acceleration. + */ + this.lastAcceleration = null; +} + +/** + * Asynchronously aquires the current acceleration. + * @param {Function} successCallback The function to call when the acceleration + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the acceleration data. + * @param {AccelerationOptions} options The options for getting the accelerometer data + * such as timeout. + */ +Accelerometer.prototype.getCurrentAcceleration = function(successCallback, errorCallback, options) { + // If the acceleration is available then call success + // If the acceleration is not available then call error + + // Created for iPhone, Iphone passes back _accel obj litteral + if (typeof successCallback == "function") { + var accel = new Acceleration(_accel.x,_accel.y,_accel.z); + Accelerometer.lastAcceleration = accel; + successCallback(accel); + } +} + +/** + * Asynchronously aquires the acceleration repeatedly at a given interval. + * @param {Function} successCallback The function to call each time the acceleration + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the acceleration data. + * @param {AccelerationOptions} options The options for getting the accelerometer data + * such as timeout. + */ + +Accelerometer.prototype.watchAcceleration = function(successCallback, errorCallback, options) { + // TODO: add the interval id to a list so we can clear all watches + var frequency = (options != undefined)? options.frequency : 10000; + + Accel.start(frequency); + return setInterval(function() { + navigator.accelerometer.getCurrentAcceleration(successCallback, errorCallback, options); + }, frequency); +} + +/** + * Clears the specified accelerometer watch. + * @param {String} watchId The ID of the watch returned from #watchAcceleration. + */ +Accelerometer.prototype.clearWatch = function(watchId) { + Accel.stop(); + clearInterval(watchId); +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.accelerometer == "undefined") navigator.accelerometer = new Accelerometer(); +}); diff --git a/js/addressbook.js b/js/addressbook.js new file mode 100644 index 00000000..1c54a5a7 --- /dev/null +++ b/js/addressbook.js @@ -0,0 +1,140 @@ +/** + * This overrides existing contact code, and builds proper contacts + * @constructor + */ + +var Contact = function() { + this.givenNames = []; + this.familyName = ""; + this.phones = []; + this.category = ""; + this.companyName = ""; + this.isCompany = false; + this.email = []; + this.addresses = []; + this.uri = []; + this.prefix = ""; + this.jobTitle = ""; + this.birthday = ""; + this.phoneticName = ""; +} + +var Address = function() { + this.street = ""; + this.postalCode = ""; + this.city = ""; + this.region = ""; + this.countryCode = ""; + this.country = ""; + this.building = ""; + this.floor = ""; + this.accessCode = ""; +} + +var PhoneNumber = function() { + this.number = ""; + this.type = ""; +} + +var Email = function() { + this.address = ""; + this.type = ""; +} + +var ImHandle = function() +{ + this.address = ""; + this.type = ""; + this.network = ""; +} + +var Uri = function() { + this.addr = ""; + this.rel = ""; +} + + +var AddressBook = function() { + this.name = ""; + this.resultSet = []; +} + +AddressBook.prototype.addContact = function(newContact, win, fail) +{ + +} + +AddressBook.prototype.removeContact = function(target, win, fail) +{ + +} + +AddressBook.prototype.findContacts = function(filter,win, fail) +{ +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.AddressBook == "undefined") + navigator.AddressBook = new AddressBook(); }); +AddressBook.prototype.addContact = function(newContact, win, fail) +{ + +} + +AddressBook.prototype.removeContact = function(target, win, fail) +{ + +} + +AddressBook.prototype.findContacts = function(filter,win, fail) +{ + this.win = win; + this.fail = fail; + // Zero out the result set for the query + this.resultSet = []; + var name = ""; + var phone = ""; + var email = ""; + + if (filter.givenName) + name = filter.givenName; + if (filter.familyName) + name += filter.familyName; + if (filter.phone) + var phone = filter.phone; + if (filter.email) + var email = filter.email; + ContactHook.search(name, phone, email); +} + +AddressBook.prototype.droidFoundContact = function(name, npa, email) +{ + names = name.split(' '); + personContact = new Contact(); + personContact.givenNames.push(names[0]); + // This is technically wrong, but we can't distinguish right now + if(names.length > 1) + { + personContact.familyName = name[name.length -1]; + } + + telNumber = new PhoneNumber(); + telNumber.number = npa; + personContact.phones.push(telNumber); + + email_addr = new Email(); + email_addr.address = email; + + personContact.email.push(email_addr); + + this.resultSet.push(personContact); + +} + +AddressBook.prototype.droidDoneContacts = function() +{ + if(resultSet.length > 0) + this.win(resultSet); + else + this.fail(); +} diff --git a/js/camera.js b/js/camera.js new file mode 100644 index 00000000..71d5659f --- /dev/null +++ b/js/camera.js @@ -0,0 +1,41 @@ +/** + * This class provides access to the device camera. + * @constructor + */ +function Camera() { + +} + +/** + * + * @param {Function} successCallback + * @param {Function} errorCallback + * @param {Object} options + */ +Camera.prototype.getPicture = function(successCallback, errorCallback, options) { + + this.winCallback = successCallback; + this.failCallback = errorCallback; + if (options.quality) + { + GapCam.takePicture(options.quality); + } + else + { + GapCam.takePicture(80); + } +} + +Camera.prototype.win = function(picture) +{ + this.winCallback(picture); +} + +Camera.prototype.fail = function(err) +{ + this.failCallback(err); +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.camera == "undefined") navigator.camera = new Camera(); +}); diff --git a/js/compass.js b/js/compass.js new file mode 100644 index 00000000..fc90e110 --- /dev/null +++ b/js/compass.js @@ -0,0 +1,96 @@ +/** + * This class provides access to device Compass data. + * @constructor + */ +function Compass() { + /** + * The last known Compass position. + */ + this.lastHeading = null; + this.lastError = null; + this.callbacks = { + onHeadingChanged: [], + onError: [] + }; +}; + +/** + * Asynchronously aquires the current heading. + * @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. + * @param {PositionOptions} options The options for getting the heading data + * such as timeout. + */ +Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) { + if (this.lastHeading == null) { + this.start(options); + } + else + if (typeof successCallback == "function") { + successCallback(this.lastHeading); + } +}; + +/** + * Asynchronously aquires the heading repeatedly at a given interval. + * @param {Function} successCallback The function to call each time the heading + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the heading data. + * @param {HeadingOptions} options The options for getting the heading data + * such as timeout and the frequency of the watch. + */ +Compass.prototype.watchHeading= function(successCallback, errorCallback, options) { + // Invoke the appropriate callback with a new Position object every time the implementation + // determines that the position of the hosting device has changed. + + this.getCurrentHeading(successCallback, errorCallback, options); + var frequency = 100; + if (typeof(options) == 'object' && options.frequency) + frequency = options.frequency; + + var self = this; + return setInterval(function() { + self.getCurrentHeading(successCallback, errorCallback, options); + }, frequency); +}; + + +/** + * Clears the specified heading watch. + * @param {String} watchId The ID of the watch returned from #watchHeading. + */ +Compass.prototype.clearWatch = function(watchId) { + clearInterval(watchId); +}; + + +/** + * Called by the geolocation framework when the current heading is found. + * @param {HeadingOptions} position The current heading. + */ +Compass.prototype.setHeading = function(heading) { + this.lastHeading = heading; + for (var i = 0; i < this.callbacks.onHeadingChanged.length; i++) { + var f = this.callbacks.onHeadingChanged.shift(); + f(heading); + } +}; + +/** + * Called by the geolocation framework when an error occurs while looking up the current position. + * @param {String} message The text of the error message. + */ +Compass.prototype.setError = function(message) { + this.lastError = message; + for (var i = 0; i < this.callbacks.onError.length; i++) { + var f = this.callbacks.onError.shift(); + f(message); + } +}; + +PhoneGap.addConstructor(function() { + if (typeof navigator.compass == "undefined") navigator.compass = new Compass(); +}); diff --git a/js/contact.js b/js/contact.js new file mode 100644 index 00000000..0835a86f --- /dev/null +++ b/js/contact.js @@ -0,0 +1,52 @@ +/** + * This class provides access to the device contacts. + * @constructor + */ + +function Contact(jsonObject) { + this.firstName = ""; + this.lastName = ""; + this.name = ""; + this.phones = {}; + this.emails = {}; + this.address = ""; +} + +Contact.prototype.displayName = function() +{ + // TODO: can be tuned according to prefs + return this.name; +} + +function ContactManager() { + // Dummy object to hold array of contacts + this.contacts = []; + this.timestamp = new Date().getTime(); +} + +ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) { + // Interface +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.ContactManager == "undefined") navigator.ContactManager = new ContactManager(); +}); +ContactManager.prototype.getAllContacts = function(successCallback, errorCallback, options) { + this.win = successCallback; + this.fail = errorCallback; + ContactHook.getContactsAndSendBack(); +} + +ContactManager.prototype.droidAddContact = function(name, phone, email) +{ + var contact = new Contact(); + contact.name = name; + contact.phones.primary = phone; + contact.emails.primary = email; + this.contacts.push(contact); +} + +ContactManager.prototype.droidDone = function() +{ + win(this.contacts); +} diff --git a/js/device.js b/js/device.js new file mode 100644 index 00000000..6c1cc601 --- /dev/null +++ b/js/device.js @@ -0,0 +1,38 @@ +/** + * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the + * phone, etc. + * @constructor + */ +function Device() { + this.available = PhoneGap.available; + this.platform = null; + this.version = null; + this.name = null; + this.gap = null; + this.uuid = null; + try { + if (window.DroidGap) { + this.available = true; + this.uuid = window.DroidGap.getUuid(); + this.version = window.DroidGap.getOSVersion(); + this.gapVersion = window.DroidGap.getVersion(); + this.platform = window.DroidGap.getPlatform(); + this.name = window.DroidGap.getProductName(); + } else { + this.platform = DeviceInfo.platform; + this.version = DeviceInfo.version; + this.name = DeviceInfo.name; + this.gap = DeviceInfo.gap; + this.uuid = DeviceInfo.uuid; + } + } catch(e) { + this.available = false; + } +} + +PhoneGap.addConstructor(function() { + navigator.device = window.device = new Device(); + var event = document.createEvent("Events"); + event.initEvent('deviceReady', false, false); + document.dispatchEvent(event); +}); diff --git a/js/file.js b/js/file.js new file mode 100644 index 00000000..1737169a --- /dev/null +++ b/js/file.js @@ -0,0 +1,109 @@ +/** + * This class provides generic read and write access to the mobile device file system. + */ +function File() { + /** + * The data of a file. + */ + this.data = ""; + /** + * The name of the file. + */ + this.name = ""; +} + +/** + * Reads a file from the mobile device. This function is asyncronous. + * @param {String} fileName The name (including the path) to the file on the mobile device. + * The file name will likely be device dependent. + * @param {Function} successCallback The function to call when the file is successfully read. + * @param {Function} errorCallback The function to call when there is an error reading the file from the device. + */ +File.prototype.read = function(fileName, successCallback, errorCallback) { + +} + +/** + * Writes a file to the mobile device. + * @param {File} file The file to write to the device. + */ +File.prototype.write = function(file) { + +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.file == "undefined") navigator.file = new File(); +}); + +File.prototype.read = function(fileName, successCallback, errorCallback) { + this.failCallback = errorCallback; + this.winCallback = successCallback; + + return FileUtil.read(fileName); +} + +File.prototype.hasRead = function(data) +{ + if(data.substr("FAIL")) + this.failCallback(data); + else + this.winCallback(data); +} + +/** + * Writes a file to the mobile device. + * @param {File} file The file to write to the device. + */ +File.prototype.write = function(file, str, mode, successCallback, failCallback) { + this.winCallback = successCallback; + this.failCallback = failCallback; + var call = FileUtil.write(file, str, mode); +} + +File.prototype.testFileExists = function(file, successCallback, failCallback) +{ + var exists = FileUtil.testFileExists(file); + if(exists) + successCallback(); + else + failCallback(); + return exists; +} + +File.prototype.testDirectoryExists = function(file, successCallback, failCallback) +{ + var exists = FileUtil.testDirectoryExists(file); + if(exists) + successCallback(); + else + failCallback(); + return exists; +} + +File.prototype.createDirectory = function(dir, successCallback, failCallback) +{ + var good = FileUtils.createDirectory(dir); + good ? successCallback() : failCallback(); +} + +File.prototype.deleteDirectory = function(dir, successCallback, failCallback) +{ + var good = FileUtils.deleteDirectory(dir); + good ? successCallback() : failCallback(); +} + +File.prototype.deleteFile = function(dir, successCallback, failCallback) +{ + var good = FileUtils.deleteFile(dir); + good ? successCallback() : failCallback(); +} + +File.prototype.getFreeDiskSpace = function(successCallback, failCallback) +{ + var diskSpace = FileUtils.getFreeDiskSpace(); + if(diskSpace > 0) + successCallback(); + else + failCallback(); + return diskSpace; +} diff --git a/js/geolocation.js b/js/geolocation.js new file mode 100644 index 00000000..e16fccfe --- /dev/null +++ b/js/geolocation.js @@ -0,0 +1,187 @@ +/** + * This class provides access to device GPS data. + * @constructor + */ +function Geolocation() { + /** + * The last known GPS position. + */ + this.lastPosition = null; + this.lastError = null; + this.callbacks = { + onLocationChanged: [], + onError: [] + }; +}; + +/** + * Asynchronously aquires the current position. + * @param {Function} successCallback The function to call when the position + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the position data. + * @param {PositionOptions} options The options for getting the position data + * such as timeout. + */ +Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) { + var referenceTime = 0; + if (this.lastPosition) + referenceTime = this.lastPosition.timeout; + else + this.start(options); + + var timeout = 20000; + var interval = 500; + if (typeof(options) == 'object' && options.interval) + interval = options.interval; + + if (typeof(successCallback) != 'function') + successCallback = function() {}; + if (typeof(errorCallback) != 'function') + errorCallback = function() {}; + + var dis = this; + var delay = 0; + var timer = setInterval(function() { + delay += interval; + + if (typeof(dis.lastPosition) == 'object' && dis.lastPosition.timestamp > referenceTime) { + successCallback(dis.lastPosition); + clearInterval(timer); + } else if (delay >= timeout) { + errorCallback(); + clearInterval(timer); + } + }, interval); +}; + +/** + * Asynchronously aquires the position repeatedly at a given interval. + * @param {Function} successCallback The function to call each time the position + * data is available + * @param {Function} errorCallback The function to call when there is an error + * getting the position data. + * @param {PositionOptions} options The options for getting the position data + * such as timeout and the frequency of the watch. + */ +Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) { + // Invoke the appropriate callback with a new Position object every time the implementation + // determines that the position of the hosting device has changed. + + this.getCurrentPosition(successCallback, errorCallback, options); + var frequency = 10000; + if (typeof(options) == 'object' && options.frequency) + frequency = options.frequency; + + var that = this; + return setInterval(function() { + that.getCurrentPosition(successCallback, errorCallback, options); + }, frequency); +}; + + +/** + * Clears the specified position watch. + * @param {String} watchId The ID of the watch returned from #watchPosition. + */ +Geolocation.prototype.clearWatch = function(watchId) { + clearInterval(watchId); +}; + +/** + * Called by the geolocation framework when the current location is found. + * @param {PositionOptions} position The current position. + */ +Geolocation.prototype.setLocation = function(position) { + this.lastPosition = position; + for (var i = 0; i < this.callbacks.onLocationChanged.length; i++) { + var f = this.callbacks.onLocationChanged.shift(); + f(position); + } +}; + +/** + * Called by the geolocation framework when an error occurs while looking up the current position. + * @param {String} message The text of the error message. + */ +Geolocation.prototype.setError = function(message) { + this.lastError = message; + for (var i = 0; i < this.callbacks.onError.length; i++) { + var f = this.callbacks.onError.shift(); + f(message); + } +}; + +PhoneGap.addConstructor(function() { + if (typeof navigator.geolocation == "undefined") navigator.geolocation = new Geolocation(); +}); +/* +* Since we can't guarantee that we will have the most recent, we just try our best! +* +* Also, the API doesn't specify which version is the best version of the API +*/ + +Geolocation.prototype.getCurrentPosition = function(successCallback, errorCallback, options) +{ + var position = Geo.getCurrentLocation(); + this.global_success = successCallback; + this.fail = errorCallback; +} + + +// Run the global callback +Geolocation.prototype.gotCurrentPosition = function(lat, lng, alt, altacc, head, vel, stamp) +{ + if (lat == "undefined" || lng == "undefined") + { + this.fail(); + } + else + { + coords = new Coordinates(lat, lng, alt, altacc, head, vel); + loc = new Position(coords, stamp); + this.global_success(loc); + } +} + +/* +* This turns on the GeoLocator class, which has two listeners. +* The listeners have their own timeouts, and run independently of this process +* In this case, we return the key to the watch hash +*/ + +Geolocation.prototype.watchPosition = function(successCallback, errorCallback, options) +{ + var frequency = (options != undefined)? options.frequency : 10000; + + if (!this.listeners) + { + this.listeners = []; + } + + var key = this.listeners.push( {"success" : successCallback, "fail" : failCallback }) - 1; + + // TO-DO: Get the names of the method and pass them as strings to the Java. + return Geolocation.start(frequency, key); +} + +/* + * Retrieve and stop this listener from listening to the GPS + * + */ +Geolocation.prototype.success = function(key, lat, lng, alt, altacc, head, vel, stamp) +{ + var coords = new Coordinates(lat, lng, alt, altacc, head, vel); + var loc = new Position(coords, stamp); + this.listeners[key].success(loc); +} + +Geolocation.prototype.fail = function(key) +{ + this.listeners[key].fail(); +} + +Geolocation.prototype.clearWatch = function(watchId) +{ + Geo.stop(watchId); +} diff --git a/js/media.js b/js/media.js new file mode 100644 index 00000000..eaf433b6 --- /dev/null +++ b/js/media.js @@ -0,0 +1,62 @@ +/** + * This class provides access to the device media, interfaces to both sound and video + * @constructor + */ +function Media(src, successCallback, errorCallback) { + this.src = src; + this.successCallback = successCallback; + this.errorCallback = errorCallback; +} + +Media.prototype.record = function() { +} + +Media.prototype.play = function() { +} + +Media.prototype.pause = function() { +} + +Media.prototype.stop = function() { +} + + +/** + * This class contains information about any Media errors. + * @constructor + */ +function MediaError() { + this.code = null, + this.message = ""; +} + +MediaError.MEDIA_ERR_ABORTED = 1; +MediaError.MEDIA_ERR_NETWORK = 2; +MediaError.MEDIA_ERR_DECODE = 3; +MediaError.MEDIA_ERR_NONE_SUPPORTED = 4; + + +//if (typeof navigator.audio == "undefined") navigator.audio = new Media(src); + +/** + * This class provides access to the device media, interfaces to both sound and video + * @constructor + */ + +Media.prototype.play = function() { + DroidGap.startPlayingAudio(this.src); +} + +Media.prototype.stop = function() { + DroidGap.stopPlayingAudio(); +} + +Media.prototype.startRecord = function() { + DroidGap.startRecordingAudio(this.src); +} + +Media.prototype.stopRecordingAudio = function() { + DroidGap.stopRecordingAudio(); +} + + diff --git a/js/network.js b/js/network.js new file mode 100644 index 00000000..8ac10b86 --- /dev/null +++ b/js/network.js @@ -0,0 +1,60 @@ +/** + * This class contains information about any NetworkStatus. + * @constructor + */ +function NetworkStatus() { + this.code = null; + this.message = ""; +} + +NetworkStatus.NOT_REACHABLE = 0; +NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK = 1; +NetworkStatus.REACHABLE_VIA_WIFI_NETWORK = 2; + +/** + * This class provides access to device Network data (reachability). + * @constructor + */ +function Network() { + /** + * The last known Network status. + * { hostName: string, ipAddress: string, + remoteHostStatus: int(0/1/2), internetConnectionStatus: int(0/1/2), localWiFiConnectionStatus: int (0/2) } + */ + this.lastReachability = null; +}; + +/** + * + * @param {Function} successCallback + * @param {Function} errorCallback + * @param {Object} options (isIpAddress:boolean) + */ +Network.prototype.isReachable = function(hostName, successCallback, options) { +} + +/** + * Called by the geolocation framework when the reachability status has changed. + * @param {Reachibility} reachability The current reachability status. + */ +Network.prototype.updateReachability = function(reachability) { + this.lastReachability = reachability; +}; + +PhoneGap.addConstructor(function() { + if (typeof navigator.network == "undefined") navigator.network = new Network(); +}); +Network.prototype.isReachable = function(uri, win, options) +{ + var status = new NetworkStatus(); + if(NetworkManager.isReachable(uri)) + { + if (NetworkManager.isWifiActive) + status.code = 2; + else + status.code = 1; + } + else + status.code = 0; + win(status); +} diff --git a/js/notification.js b/js/notification.js new file mode 100644 index 00000000..5a7c733b --- /dev/null +++ b/js/notification.js @@ -0,0 +1,77 @@ +/** + * This class provides access to notifications on the device. + */ +function Notification() { + +} + +/** + * Open a native alert dialog, with a customizable title and button text. + * @param {String} message Message to print in the body of the alert + * @param {String} [title="Alert"] Title of the alert dialog (default: Alert) + * @param {String} [buttonLabel="OK"] Label of the close button (default: OK) + */ +Notification.prototype.alert = function(message, title, buttonLabel) { + // Default is to use a browser alert; this will use "index.html" as the title though + alert(message); +}; + +/** + * Start spinning the activity indicator on the statusbar + */ +Notification.prototype.activityStart = function() { +}; + +/** + * Stop spinning the activity indicator on the statusbar, if it's currently spinning + */ +Notification.prototype.activityStop = function() { +}; + +/** + * Causes the device to blink a status LED. + * @param {Integer} count The number of blinks. + * @param {String} colour The colour of the light. + */ +Notification.prototype.blink = function(count, colour) { + +}; + +/** + * Causes the device to vibrate. + * @param {Integer} mills The number of milliseconds to vibrate for. + */ +Notification.prototype.vibrate = function(mills) { + +}; + +/** + * Causes the device to beep. + * @param {Integer} count The number of beeps. + * @param {Integer} volume The volume of the beep. + */ +Notification.prototype.beep = function(count, volume) { + +}; + +// TODO: of course on Blackberry and Android there notifications in the UI as well + +PhoneGap.addConstructor(function() { + if (typeof navigator.notification == "undefined") navigator.notification = new Notification(); +}); + +Notification.prototype.vibrate = function(mills) +{ + DroidGap.vibrate(mills); +} + +/* + * On the Android, we don't beep, we notify you with your + * notification! We shouldn't keep hammering on this, and should + * review what we want beep to do. + */ + +Notification.prototype.beep = function(count, volume) +{ + DroidGap.beep(count); +} diff --git a/js/phonegap.js.base b/js/phonegap.js.base new file mode 100644 index 00000000..b64efcd9 --- /dev/null +++ b/js/phonegap.js.base @@ -0,0 +1,75 @@ +if (typeof(DeviceInfo) != 'object') + DeviceInfo = {}; + +/** + * This represents the PhoneGap API itself, and provides a global namespace for accessing + * information about the state of PhoneGap. + * @class + */ +PhoneGap = { + queue: { + ready: true, + commands: [], + timer: null + }, + _constructors: [] +}; + +/** + * Boolean flag indicating if the PhoneGap API is available and initialized. + */ +PhoneGap.available = DeviceInfo.uuid != undefined; + +/** + * Add an initialization function to a queue that ensures it will run and initialize + * application constructors only once PhoneGap has been initialized. + * @param {Function} func The function callback you want run once PhoneGap is initialized + */ +PhoneGap.addConstructor = function(func) { + var state = document.readyState; + if (state != 'loaded' && state != 'complete') + PhoneGap._constructors.push(func); + else + func(); +}; +(function() { + var timer = setInterval(function() { + var state = document.readyState; + if (state != 'loaded' && state != 'complete') + return; + clearInterval(timer); + while (PhoneGap._constructors.length > 0) { + var constructor = PhoneGap._constructors.shift(); + try { + constructor(); + } catch(e) { + if (typeof(debug['log']) == 'function') + debug.log("Failed to run constructor: " + debug.processMessage(e)); + else + alert("Failed to run constructor: " + e.message); + } + } + }, 1); +})(); + + +/** + * Execute a PhoneGap command in a queued fashion, to ensure commands do not + * execute with any race conditions, and only run when PhoneGap is ready to + * recieve them. + * @param {String} command Command to be run in PhoneGap, e.g. "ClassName.method" + * @param {String[]} [args] Zero or more arguments to pass to the method + */ +PhoneGap.exec = function() { + PhoneGap.queue.commands.push(arguments); + if (PhoneGap.queue.timer == null) + PhoneGap.queue.timer = setInterval(PhoneGap.run_command, 10); +}; +/** + * Internal function used to dispatch the request to PhoneGap. This needs to be implemented per-platform to + * ensure that methods are called on the phone in a way appropriate for that device. + * @private + */ +PhoneGap.run_command = function() { +}; + diff --git a/js/position.js b/js/position.js new file mode 100644 index 00000000..d6a983fe --- /dev/null +++ b/js/position.js @@ -0,0 +1,72 @@ +/** + * This class contains position information. + * @param {Object} lat + * @param {Object} lng + * @param {Object} acc + * @param {Object} alt + * @param {Object} altacc + * @param {Object} head + * @param {Object} vel + * @constructor + */ +function Position(coords, timestamp) { + this.coords = coords; + this.timestamp = new Date().getTime(); +} + +function Coordinates(lat, lng, alt, acc, head, vel) { + /** + * The latitude of the position. + */ + this.latitude = lat; + /** + * The longitude of the position, + */ + this.longitude = lng; + /** + * The accuracy of the position. + */ + this.accuracy = acc; + /** + * The altitude of the position. + */ + this.altitude = alt; + /** + * The direction the device is moving at the position. + */ + this.heading = head; + /** + * The velocity with which the device is moving at the position. + */ + this.speed = vel; +} + +/** + * This class specifies the options for requesting position data. + * @constructor + */ +function PositionOptions() { + /** + * Specifies the desired position accuracy. + */ + this.enableHighAccuracy = true; + /** + * The timeout after which if position data cannot be obtained the errorCallback + * is called. + */ + this.timeout = 10000; +} + +/** + * This class contains information about any GSP errors. + * @constructor + */ +function PositionError() { + this.code = null; + this.message = ""; +} + +PositionError.UNKNOWN_ERROR = 0; +PositionError.PERMISSION_DENIED = 1; +PositionError.POSITION_UNAVAILABLE = 2; +PositionError.TIMEOUT = 3;