/*
* Copyright 2010 Daniel Kurka
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.googlecode.gwtphonegap.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Timer;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.HandlerRegistration;
import com.google.web.bindery.event.shared.SimpleEventBus;
import com.googlecode.gwtphonegap.client.accelerometer.Accelerometer;
import com.googlecode.gwtphonegap.client.camera.Camera;
import com.googlecode.gwtphonegap.client.capture.Capture;
import com.googlecode.gwtphonegap.client.compass.Compass;
import com.googlecode.gwtphonegap.client.connection.Connection;
import com.googlecode.gwtphonegap.client.contacts.Contacts;
import com.googlecode.gwtphonegap.client.device.Device;
import com.googlecode.gwtphonegap.client.event.Event;
import com.googlecode.gwtphonegap.client.file.File;
import com.googlecode.gwtphonegap.client.geolocation.Geolocation;
import com.googlecode.gwtphonegap.client.globalization.Globalization;
import com.googlecode.gwtphonegap.client.inappbrowser.InAppBrowser;
import com.googlecode.gwtphonegap.client.log.PhoneGapLog;
import com.googlecode.gwtphonegap.client.log.PhoneGapLogStandardImpl;
import com.googlecode.gwtphonegap.client.media.MediaModule;
import com.googlecode.gwtphonegap.client.notification.Notification;
import com.googlecode.gwtphonegap.client.plugins.PhoneGapPlugin;
import com.googlecode.gwtphonegap.client.splashscreen.SplashScreen;
import java.util.HashMap;
import java.util.Map;
public class PhoneGapStandardImpl implements PhoneGap {
private static final int INIT_TICK = 10;
private Device device;
private Accelerometer accelerometer;
private Camera camera;
private Geolocation geolocation;
private Notification notification;
private Contacts contacts;
private File file;
private Connection connection;
private Event event;
private MediaModule mediaModule;
private Compass compass;
private Capture capture;
private SplashScreen splashScreen;
private InAppBrowser inAppBrowser;
private Map<String, PhoneGapPlugin> plugins = new HashMap<String, PhoneGapPlugin>();
private boolean hasHandlers = false;
private EventBus handlerManager = new SimpleEventBus();
private PhoneGapLogStandardImpl phoneGapLog;
private boolean deviceReady;
private Globalization globalization;
public PhoneGapStandardImpl() {
// log configures it self
getLog();
setupReadyHook();
}
public PhoneGapLog getLog() {
if (phoneGapLog == null) {
phoneGapLog = new PhoneGapLogStandardImpl();
}
return phoneGapLog;
}
@Override
public boolean isPhoneGapInitialized() {
return deviceReady;
}
@Override
public void initializePhoneGap() {
initializePhoneGap(10000);
}
@Override
public void initializePhoneGap(final int timeoutInMs) {
final long end = System.currentTimeMillis() + timeoutInMs;
if (isPhoneGapInitialized()) {
firePhoneGapAvailable();
} else {
Timer timer = new Timer() {
@Override
public void run() {
if (isPhoneGapInitialized()) {
firePhoneGapAvailable();
return;
}
if (System.currentTimeMillis() - end > 0) {
handlerManager.fireEvent(new PhoneGapTimeoutEvent());
} else {
schedule(INIT_TICK);
}
}
};
timer.schedule(INIT_TICK);
}
}
@Override
public HandlerRegistration addHandler(PhoneGapAvailableHandler handler) {
hasHandlers = true;
return handlerManager.addHandler(PhoneGapAvailableEvent.TYPE, handler);
}
@Override
public HandlerRegistration addHandler(PhoneGapTimeoutHandler handler) {
hasHandlers = true;
return handlerManager.addHandler(PhoneGapTimeoutEvent.TYPE, handler);
}
@Override
public Device getDevice() {
if (device == null) {
device = constructDevice();
}
return device;
}
@Override
public Accelerometer getAccelerometer() {
if (accelerometer == null) {
accelerometer = constructAccelerometer();
}
return accelerometer;
}
@Override
public Camera getCamera() {
if (camera == null) {
camera = constructCamera();
}
return camera;
}
@Override
public Geolocation getGeolocation() {
if (geolocation == null) {
geolocation = constructGeolocation();
}
return geolocation;
}
@Override
public Notification getNotification() {
if (notification == null) {
notification = constructNotification();
}
return notification;
}
private void firePhoneGapAvailable() {
if (!getDevice().isAvailable()) {
log("Device API is not available - logging will not work");
log("e.g.: plugman install --platform android --project ./platforms/android/ --plugin org.apache.cordova.device");
} else {
phoneGapLog.setClientId(getDevice().getUuid());
}
handlerManager.fireEvent(new PhoneGapAvailableEvent());
}
@Override
public Contacts getContacts() {
if (contacts == null) {
contacts = constructContacts();
}
return contacts;
}
@Override
public PhoneGapPlugin getPluginById(String id) {
return plugins.get(id);
}
@Override
public void loadPlugin(String id, PhoneGapPlugin instance) {
if (plugins.containsKey(id)) {
throw new IllegalStateException("id is already in use");
}
plugins.put(id, instance);
}
@Override
public File getFile() {
if (file == null) {
file = constructFile();
}
return file;
}
@Override
public Connection getConnection() {
if (connection == null) {
connection = constructConnection();
}
return connection;
}
@Override
public Event getEvent() {
hasHandlers = true;
if (event == null) {
event = constructEvent();
}
return event;
}
@Override
public native boolean exitApp() /*-{
if ($wnd.navigator.app != null) {
if ($wnd.navigator.app.exitApp != null) {
$wnd.navigator.app.exitApp();
return true;
}
}
return false;
}-*/;
@Override
public MediaModule getMedia() {
if (mediaModule == null) {
mediaModule = constructMediaModule();
}
return mediaModule;
}
@Override
public Compass getCompass() {
if (compass == null) {
compass = constructCompass();
}
return compass;
}
@Override
public Capture getCapture() {
if (capture == null) {
capture = constructCapture();
}
return capture;
}
@Override
public SplashScreen getSplashScreen() {
if (splashScreen == null) {
splashScreen = constructSplashscreen();
}
return splashScreen;
}
@Override
public boolean isPhoneGapDevice() {
return true;
}
protected Device constructDevice() {
return GWT.create(Device.class);
}
protected Accelerometer constructAccelerometer() {
return GWT.create(Accelerometer.class);
}
protected Camera constructCamera() {
return GWT.create(Camera.class);
}
protected Geolocation constructGeolocation() {
return GWT.create(Geolocation.class);
}
protected Notification constructNotification() {
return GWT.create(Notification.class);
}
protected Capture constructCapture() {
return GWT.create(Capture.class);
}
protected SplashScreen constructSplashscreen() {
return GWT.create(SplashScreen.class);
}
protected Compass constructCompass() {
return GWT.create(Compass.class);
}
protected MediaModule constructMediaModule() {
return GWT.create(MediaModule.class);
}
protected Event constructEvent() {
Event event = GWT.create(Event.class);
event.setEventBus(handlerManager);
return event;
}
protected Connection constructConnection() {
return GWT.create(Connection.class);
}
protected File constructFile() {
return GWT.create(File.class);
}
protected Contacts constructContacts() {
return GWT.create(Contacts.class);
}
protected void nativeDeviceReady() {
deviceReady = true;
}
private native void setupReadyHook() /*-{
var that = this;
var f = function() {
that.@com.googlecode.gwtphonegap.client.PhoneGapStandardImpl::nativeDeviceReady()();
};
$doc.addEventListener("deviceready", $entry(f), false);
}-*/;
@Override
public void setEventBus(EventBus eventBus) {
assert !hasHandlers : "The handlerManager can not be replaced because it has got handlers";
handlerManager = eventBus;
// We force the event construction so as the app can add events directly
// to the eventBus instead of through the phoneGap.getEvent() method;
event = constructEvent();
}
@Override
public InAppBrowser getInAppBrowser() {
if (inAppBrowser == null) {
inAppBrowser = constructInAppBrowser();
}
return inAppBrowser;
}
protected InAppBrowser constructInAppBrowser() {
return GWT.create(InAppBrowser.class);
}
@Override
public Globalization getGlobalization() {
if (globalization == null) {
globalization = constructGlobalization();
}
return globalization;
}
protected Globalization constructGlobalization() {
return GWT.create(Globalization.class);
}
protected native void log(String message) /*-{
$wnd.console.log(message);
}-*/;
}