platform/bb/rhodes/src/rhomobile/RhodesApplication.java in rhodes-1.4.2 vs platform/bb/rhodes/src/rhomobile/RhodesApplication.java in rhodes-1.5.0
- old
+ new
@@ -22,48 +22,50 @@
import net.rim.device.api.browser.field.UrlRequestedEvent;
import net.rim.device.api.io.http.HttpHeaders;
import net.rim.device.api.system.Alert;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.ApplicationManager;
+import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Characters;
+import net.rim.device.api.system.Display;
+import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.system.KeyListener;
import net.rim.device.api.system.SystemListener;
//import javax.microedition.io.file.FileSystemListener;
import net.rim.device.api.system.TrackwheelListener;
import net.rim.device.api.ui.*;
+import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.Status;
+import net.rim.device.api.ui.container.FullScreen;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
//import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.Manager;
+import net.rim.device.api.math.Fixed32;
import javax.microedition.media.*;
+//import net.rim.device.api.system.EventInjector.KeyCodeEvent;
-import com.rho.Mutex;
-import com.rho.RhoClassFactory;
-import com.rho.RhoConf;
-import com.rho.RhoEmptyLogger;
-import com.rho.RhoEmptyProfiler;
-import com.rho.RhoLogger;
-import com.rho.RhoMainScreen;
-import com.rho.RhoProfiler;
-import com.rho.RhoRuby;
-import com.rho.RhoThread;
-import com.rho.SimpleFile;
-import com.rho.Version;
+import com.rho.*;
//import com.rho.db.DBAdapter;
-import com.rho.location.GeoLocation;
+import com.rho.rubyext.GeoLocation;
+import com.rho.net.NetResponse;
import com.rho.net.RhoConnection;
import com.rho.net.URI;
import com.rho.sync.SyncThread;
import com.rho.sync.ISyncStatusListener;
import com.rho.Jsr75File;
+import com.rho.RhodesApp;
+import com.xruby.runtime.lang.RubyProgram;
+import com.rho.net.NetResponse;
+import net.rim.device.api.xml.parsers.SAXParser;
+
/**
*
*/
final public class RhodesApplication extends UiApplication implements RenderingApplication, SystemListener, ISyncStatusListener//, FileSystemListener
{
@@ -94,10 +96,11 @@
LOG.INFO_OUT( "rootChanged. arg0 :" + arg0 + "arg1: " + arg1);
if ( arg0 == FileSystemListener.ROOT_ADDED && arg1 != null &&
arg1.equals("SDCard/") )
m_bSDCardAdded = true;
}*/
+ //boolean m_bSkipKeyPress = false;
class CKeyListener implements KeyListener{
public boolean keyChar(char key, int status, int time) {
if( key == Characters.ENTER ) {
@@ -105,16 +108,18 @@
openLink();
return true;
}
return false;
}
-
public boolean keyDown(int keycode, int time) {
int nKey = Keypad.key(keycode);
if ( nKey == Keypad.KEY_ESCAPE )
{
- back();
+ /*if ( m_bSkipKeyPress )
+ m_bSkipKeyPress = false;
+ else*/
+ back();
return true;
}
return false;
}
@@ -148,11 +153,11 @@
navigateUrl(curUrl);*/
// }
//}
-
+/*
private String processAjaxCall(String request) {
if (!request.startsWith(RHODES_AJAX_PROTOCOL))
return null;
String command = request.substring(RHODES_AJAX_PROTOCOL.length()).trim();
Hashtable params = new Hashtable();
@@ -182,11 +187,11 @@
LOG.INFO(message);
return null;
}
return null;
- }
+ }*/
boolean isExternalUrl(String strUrl)
{
return strUrl.startsWith("http://") || strUrl.startsWith("https://");
}
@@ -194,16 +199,12 @@
String canonicalizeURL( String url ){
if ( url == null || url.length() == 0 )
return "";
url.replace('\\', '/');
- if ( !url.startsWith(_httpRoot) && !isExternalUrl(url) ){
- if ( url.charAt(0) == '/' )
- url = _httpRoot.substring(0, _httpRoot.length()-1) + url;
- else
- url = _httpRoot + url;
- }
+ if ( !url.startsWith(_httpRoot) && !isExternalUrl(url) )
+ url = FilePath.join(_httpRoot,url);
return url;
}
void navigateUrl(String url){
@@ -232,17 +233,45 @@
public void postUrl(String url, String body, HttpHeaders headers) {
postUrl(url, body, headers, null);
}
- public void postUrl(String url, String body, HttpHeaders headers, Callback callback){
+ public void postUrl(String url, String body, HttpHeaders headers, Runnable callback){
PrimaryResourceFetchThread thread = new PrimaryResourceFetchThread(
canonicalizeURL(url), headers, body.getBytes(), null, callback);
thread.setInternalRequest(true);
thread.start();
}
+ public static class NetCallback
+ {
+ public NetResponse m_response;
+
+ public void waitForResponse()
+ {
+ synchronized(this)
+ {
+ try{ this.wait(); }catch(InterruptedException exc){}
+ }
+ }
+
+ public void setResponse(NetResponse resp)
+ {
+ synchronized(this)
+ {
+ m_response = resp;
+ this.notify();
+ }
+ }
+ }
+ public void postUrlWithCallback(String url, String body, HttpHeaders headers, NetCallback netCallback){
+ PrimaryResourceFetchThread thread = new PrimaryResourceFetchThread(
+ canonicalizeURL(url), headers, body.getBytes(), null);
+ thread.setNetCallback(netCallback);
+ thread.start();
+ }
+
void saveCurrentLocation(String url) {
if (RhoConf.getInstance().getBool("KeepTrackOfLastVisitedPage")) {
RhoConf.getInstance().setString("LastVisitedPage",url);
RhoConf.getInstance().saveToFile();
LOG.TRACE("Saved LastVisitedPage: " + url);
@@ -302,11 +331,11 @@
if ( !strUrl.startsWith(_httpRoot) && !isExternalUrl(strUrl) )
strUrl = _httpRoot + (strUrl.startsWith("/") ? strUrl.substring(1) : strUrl);
int nPos = -1;
- for( int i = _history.size()-1; i >= 0; i-- ){
+ for( int i = 0; i < _history.size(); i++ ){
if ( strUrl.equalsIgnoreCase((String)_history.elementAt(i)) ){
nPos = i;
break;
}
/*String strUrl1 = strUrl + "/index";
@@ -489,17 +518,21 @@
private Vector _history;
private final String _httpRoot = "http://localhost:8080/";
- private boolean _isFullBrowser = false;
+ private static boolean _isFullBrowser = false;
private static PushListeningThread _pushListeningThread = null;
private static RhodesApplication _instance;
public static RhodesApplication getInstance(){ return _instance; }
+ private static RhodesApp RHODESAPP(){ return RhodesApp.getInstance(); }
+
+ public static boolean isFullBrowser(){ return _isFullBrowser; }
+
/***************************************************************************
* Main.
**************************************************************************/
public static void main(String[] args)
{
@@ -588,67 +621,80 @@
private static boolean m_bRubyInit = false;
public void activate()
{
//DO NOT DO ANYTHING before doStartupWork
doStartupWork();
+ showSplashScreen();
LOG.TRACE("Rhodes start activate ***--------------------------***");
- if ( !m_bRubyInit )
- {
- synchronized (m_eventRubyInit) {
- try{
- m_eventRubyInit.wait();
- }catch(Exception e)
- {
- LOG.ERROR("wait failed", e);
- }
- }
- }
+ UiApplication.getUiApplication().invokeLater(new Runnable() {
+
+ public void run() {
+ if ( !m_bRubyInit )
+ {
+ synchronized (m_eventRubyInit) {
+ try{
+ m_eventRubyInit.wait();
+ }catch(Exception e)
+ {
+ LOG.ERROR("wait failed", e);
+ }
+ }
+ }
+
+ if ( !RhoRuby.rho_ruby_isValid() )
+ {
+ LOG.ERROR("Cannot initialize Rho framework. Application will exit.");
+ Dialog.alert("Cannot initialize Rho framework. Application will exit. Log will send to log server.");
+
+ RhoConf.sendLog();
+
+ System.exit(1);
+ }
+
+ runActivateHooks();
+
+ RhoRuby.rho_ruby_activateApp();
+
+ if(!restoreLocation()) {
+ navigateHome();
+ }
+
+ LOG.TRACE("Rhodes end activate ***--------------------------***");
+ }
+
+ });
- if ( !RhoRuby.rho_ruby_isValid() )
- {
- LOG.ERROR("Cannot initialize Ruby framework. Application will exit.");
- Dialog.alert("Cannot initialize Ruby framework. Application will exit. Log will send to log server.");
-
- RhoConf.sendLog();
-
- System.exit(1);
- }
-
- runActivateHooks();
-
- RhoRuby.rho_ruby_activateApp();
-
- if(!restoreLocation()) {
- navigateHome();
- }
-
- LOG.TRACE("Rhodes end activate ***--------------------------***");
-
super.activate();
}
- void initRuby()
+ void initRuby()throws Exception
{
- RhoRuby.RhoRubyStart("");
- SyncThread sync = null;
- try{
- sync = SyncThread.Create( new RhoClassFactory() );
-
- }catch(Exception exc){
- LOG.ERROR("Create sync failed.", exc);
- }
- if (sync != null) {
- sync.setStatusListener(this);
- }
-
- RhoRuby.RhoRubyInitApp();
-
- m_bRubyInit = true;
- synchronized (m_eventRubyInit) {
- m_eventRubyInit.notifyAll();
- }
+ try
+ {
+ RhoRuby.RhoRubyStart("");
+
+ SyncThread sync = null;
+
+ try{
+ sync = SyncThread.Create( new RhoClassFactory() );
+
+ }catch(Exception exc){
+ LOG.ERROR("Create sync failed.", exc);
+ }
+ if (sync != null) {
+ sync.setStatusListener(this);
+ }
+
+ RhoRuby.RhoRubyInitApp();
+ }finally
+ {
+ m_bRubyInit = true;
+ synchronized (m_eventRubyInit) {
+ m_eventRubyInit.notifyAll();
+ }
+ }
}
public void deactivate() {
LOG.TRACE("Rhodes deactivate ***--------------------------***");
@@ -676,10 +722,15 @@
//} else
invokeLater( new Runnable() {
public void run() {
if (_syncStatusPopup != null) {
_syncStatusPopup.showStatus(_lastStatusMessage);
+ }else
+ {
+ SyncStatusPopup popup = new SyncStatusPopup(_lastStatusMessage);
+ RhodesApplication.getInstance().setSyncStatusPopup(popup);
+ pushScreen(popup);
}
}
});
}
@@ -984,10 +1035,68 @@
public MenuItem getSavedGetLinkItem() {
return savedGetLinkItem;
}
}
+ public void showSplashScreen()
+ {
+ SplashScreen splash = RHODESAPP().getSplashScreen();
+
+ InputStream is = null;
+ try {
+ RubyProgram obj = new xruby.version.main();
+ String pngname = "/apps/app/loading.png";
+ is = obj.getClass().getResourceAsStream(pngname);
+ if ( is != null )
+ {
+ int size = is.available();
+ byte[] data = new byte[size];
+ for (int offset = 0; offset < size;) {
+ int n = is.read(data, offset, size - offset);
+ if (n < 0)
+ break;
+ offset += n;
+ }
+ EncodedImage img = EncodedImage.createEncodedImage(data, 0, size);
+ long nFlags = 0;
+ if (splash.isFlag(SplashScreen.HCENTER) )
+ nFlags |= Field.FIELD_HCENTER;
+ if (splash.isFlag(SplashScreen.VCENTER) )
+ nFlags |= Field.FIELD_VCENTER;
+
+ int scaleX = 1, scaleY = 1;
+ int currentWidthFixed32 = Fixed32.toFP(img.getWidth());
+ int currentHeightFixed32 = Fixed32.toFP(img.getHeight());
+ int screenWidthFixed32 = Fixed32.toFP(Display.getWidth());
+ int screenHeightFixed32 = Fixed32.toFP(Display.getHeight());
+
+ if (splash.isFlag(SplashScreen.VZOOM) )
+ scaleY = Fixed32.div(currentHeightFixed32, screenHeightFixed32);
+ if (splash.isFlag(SplashScreen.HZOOM) )
+ scaleX = Fixed32.div(currentWidthFixed32, screenWidthFixed32);
+
+ EncodedImage img2 = img;
+ if ( scaleX != 1 || scaleY != 1)
+ img2 = img.scaleImage32(scaleX, scaleY);
+ Bitmap bitmap = img2.getBitmap();
+
+ splash.start();
+ BitmapField imageField = new BitmapField(bitmap, nFlags);
+ _mainScreen.deleteAll();
+ _mainScreen.add(imageField);
+ }
+ }
+ catch (Exception e) {
+ LOG.ERROR("Can't show splash screen", e);
+ }finally
+ {
+ if ( is != null )
+ try{is.close();}catch(IOException exc){}
+ is = null;
+ }
+ }
+
public void showLogScreen()
{
LogScreen screen = new LogScreen();
//Push this screen to display it to the user.
UiApplication.getUiApplication().pushScreen(screen);
@@ -1029,10 +1138,12 @@
RhoLogger.InitRhoLog();
LOG.INFO(" STARTING RHODES: ***----------------------------------*** " );
+ RhodesApp.Create(RhoConf.getInstance().getRhoRootPath());
+
CKeyListener list = new CKeyListener();
CTrackwheelListener wheel = new CTrackwheelListener();
this._history = new Vector();
//SyncEngine.setNotificationImpl( new SyncNotificationsImpl() );
@@ -1047,29 +1158,37 @@
_renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.JAVASCRIPT_ENABLED, true);
_renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.JAVASCRIPT_LOCATION_ENABLED, true);
_renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.ENABLE_CSS, true);
_renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.DEFAULT_CHARSET_VALUE, "utf-8");
_renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.OVERWRITE_CHARSET_MODE, true);
+ _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.ALLOW_POPUPS, true);
+ _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.USE_BACKGROUND_IMAGES, true);
+// _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.VALUE_THRESHOLD, 100000);
+
+
// _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.USE_BACKGROUND_IMAGES, true);
// _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.SHOW_IMAGE_PLACEHOLDERS, false);
// _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.ENABLE_WML, false);
// _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.ENABLE_EMBEDDED_RICH_CONTENT, false);
// _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.ENABLE_IMAGE_EDITING, false);
// _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, RenderingOptions.NO_SEARCH_MENU_MODE, true);
-
- if ( RhoConf.getInstance().getBool("use_bb_full_browser") )
+ if ( RhoConf.getInstance().getString("use_bb_full_browser").equalsIgnoreCase("touch") )
+ _isFullBrowser = _mainScreen.isTouchScreen();
+ else if ( RhoConf.getInstance().getBool("use_bb_full_browser") )
{
Version.SoftVersion ver = Version.getSoftVersion();
if ( ver.nMajor > 4 || ( ver.nMajor == 4 && ver.nMinor >= 6 ) )
- {
- //this is the undocumented option to tell the browser to use the 4.6 Rendering Engine
- _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, 17000, true);
_isFullBrowser = true;
- }
}
+
+ if (_isFullBrowser)
+ {
+ //this is the undocumented option to tell the browser to use the 4.6 Rendering Engine
+ _renderingSession.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, 17000, true);
+ }
// _pushListeningThread = new PushListeningThread();
// _pushListeningThread.start();
try {
@@ -1174,35 +1293,33 @@
try {
browserContent = _renderingSession.getBrowserContent(connection, this, e);
if (browserContent != null) {
-
+ browserContent.finishLoading();
+
Field field = browserContent.getDisplayableContent();
if (field != null) {
+
+ RHODESAPP().getSplashScreen().hide();
+
synchronized (Application.getEventLock()) {
_mainScreen.deleteAll();
_mainScreen.add(field);
+/*
+ _mainScreen.doPaint();
+ if ( e == null )
+ {//This should awake screen in case of long network response
+ KeyCodeEvent inject1 = new KeyCodeEvent( KeyCodeEvent.KEY_DOWN, (char)Keypad.KEY_ESCAPE, 0);
+ KeyCodeEvent inject2 = new KeyCodeEvent( KeyCodeEvent.KEY_UP, (char)Keypad.KEY_ESCAPE, 0);
+ inject1.post();
+ inject2.post();
+ m_bSkipKeyPress = true;
+ }*/
}
}
-
- if ( _isFullBrowser )
- browserContent.finishLoading();
- else
- {
- if ( URI.isLocalHost(connection.getURL()) )
- {
- synchronized (Application.getEventLock())
- //synchronized (getAppEventLock())
- {
- browserContent.finishLoading();
- }
- }else
- browserContent.finishLoading();
- }
}
-
} catch (RenderingException re) {
} finally {
SecondaryResourceFetchThread.doneAddingImages();
}
@@ -1306,18 +1423,18 @@
// TODO: close the application
break;
case Event.EVENT_SET_HEADER :
case Event.EVENT_SET_HTTP_COOKIE : {
- String cookie = ((SetHttpCookieEvent)event).getCookie();
+ /*String cookie = ((SetHttpCookieEvent)event).getCookie();
String response = processAjaxCall(cookie);
if (response != null)
synchronized (pendingResponses) {
pendingResponses.addElement(response);
}
response = null;
- cookie = null;
+ cookie = null;*/
break;
}
case Event.EVENT_HISTORY : // no history support
case Event.EVENT_EXECUTING_SCRIPT : // no progress bar is supported
case Event.EVENT_FULL_WINDOW : // no full window support
@@ -1393,11 +1510,11 @@
HttpConnection connection = Utilities.makeConnection(url, resource.getRequestHeaders(), null);
return connection;
} else
{
- if ( URI.isLocalHost(url) )
+ if ( URI.isLocalHost(url) || URI.isLocalData(url))
{
HttpConnection connection = Utilities.makeConnection(url, resource.getRequestHeaders(), null);
return connection;
}else
{
@@ -1442,20 +1559,23 @@
//wait(80);
try{
_application.initRuby();
- _pushListeningThread = new PushListeningThread();
- _pushListeningThread.start();
}catch(Exception e)
{
- LOG.ERROR("HttpServerThread failed.", e);
+ LOG.ERROR("initRuby failed.", e);
+ return;
}catch(Throwable exc)
{
- LOG.ERROR("HttpServerThread crashed.", exc);
+ LOG.ERROR("initRuby crashed.", exc);
+ return;
}
-
+
+ _pushListeningThread = new PushListeningThread();
+ _pushListeningThread.start();
+
while( !m_bExit )
{
while(!m_stackCommands.isEmpty())
{
PrimaryResourceFetchThread oCmd = null;
@@ -1494,48 +1614,55 @@
};
private static HttpServerThread m_oFetchThread;
private static RhodesApplication _application;
- private static Callback _callback;
+ private static Runnable _callback;
private Event _event;
private byte[] _postData;
private HttpHeaders _requestHeaders;
private String _url;
private boolean m_bInternalRequest = false;
private boolean m_bActivateApp = false;
+ NetCallback m_netCallback;
public void setInternalRequest(boolean b)
{
m_bInternalRequest = b;
}
public PrimaryResourceFetchThread(String url, HttpHeaders requestHeaders, byte[] postData,
- Event event) {
-
+ Event event)
+ {
_url = url;
_requestHeaders = requestHeaders;
_postData = postData;
_event = event;
//_callback = null;
}
public PrimaryResourceFetchThread(String url, HttpHeaders requestHeaders, byte[] postData,
- Event event, Callback callback) {
-
+ Event event, Runnable callback)
+ {
_url = url;
_requestHeaders = requestHeaders;
_postData = postData;
_event = event;
if ( callback != null )
_callback = callback;
}
+ public void setNetCallback(NetCallback netCallback)
+ {
+ m_netCallback = netCallback;
+ m_bInternalRequest = true;
+ }
+
public PrimaryResourceFetchThread(boolean bActivateApp) {
m_bActivateApp = bActivateApp;
}
static void Create(RhodesApplication app)
@@ -1571,10 +1698,21 @@
HttpConnection connection = Utilities.makeConnection(_url, _requestHeaders, _postData);
if ( m_bInternalRequest )
{
try{
- connection.getResponseCode();
+
+ int nRespCode = connection.getResponseCode();
+
+ if ( m_netCallback != null )
+ {
+ InputStream is = connection.openInputStream();
+ byte[] buffer = new byte[is.available()];
+ is.read(buffer);
+
+ String strRespBody = new String(buffer);
+ m_netCallback.setResponse( new NetResponse(strRespBody, nRespCode) );
+ }
}catch(IOException exc)
{
LOG.ERROR("Callback failed: " + _url, exc);
}
}