rhodes 2.3.0 → 2.3.1.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. data/CHANGELOG +6 -0
  2. data/Manifest.txt +5819 -0
  3. data/README.md +2 -2
  4. data/Rakefile +9 -5
  5. data/doc/build.txt +7 -13
  6. data/doc/configuration.txt +4 -0
  7. data/doc/connect-to-web-services.txt +0 -1
  8. data/doc/device-caps.txt +2 -2
  9. data/doc/extensions.txt +2 -0
  10. data/doc/linea.txt +699 -0
  11. data/doc/rhom.txt +2 -1
  12. data/doc/synchronization.txt +39 -2
  13. data/doc/ui.txt +1 -0
  14. data/installer/README.html +1 -1
  15. data/lib/build/jake.rb +3 -0
  16. data/lib/framework/res/esri.wm.png +0 -0
  17. data/lib/framework/rho/render.rb +2 -0
  18. data/lib/framework/rho/rho.rb +17 -10
  19. data/lib/framework/rho/rhoapplication.rb +13 -3
  20. data/lib/framework/rho/rhoevent_bb.rb +3 -1
  21. data/lib/framework/rho/rhoevent_c.rb +4 -1
  22. data/lib/framework/rhodes.rb +1 -1
  23. data/lib/framework/rhom/rhom.rb +10 -0
  24. data/lib/framework/rhom/rhom_object_factory.rb +45 -0
  25. data/lib/framework/rhom/rhom_source.rb +1 -1
  26. data/lib/framework/version.rb +1 -1
  27. data/lib/rhodes.rb +1 -1
  28. data/platform/android/Rhodes/AndroidManifest.xml +2 -2
  29. data/platform/android/Rhodes/jni/include/rhodes/RhoClassFactory.h +1 -1
  30. data/platform/android/Rhodes/jni/src/RhoClassFactory.cpp +1 -1
  31. data/platform/android/Rhodes/jni/src/callbacks.cpp +9 -11
  32. data/platform/android/Rhodes/jni/src/event.cpp +17 -9
  33. data/platform/android/Rhodes/jni/src/mapview.cpp +34 -4
  34. data/platform/android/Rhodes/jni/src/rhodes.cpp +1 -1
  35. data/platform/android/Rhodes/res/drawable/esri.png +0 -0
  36. data/platform/android/Rhodes/src/com/rhomobile/rhodes/AndroidR.java +1 -0
  37. data/platform/android/Rhodes/src/com/rhomobile/rhodes/BaseActivity.java +3 -0
  38. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesActivity.java +8 -5
  39. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesService.java +80 -9
  40. data/platform/android/Rhodes/src/com/rhomobile/rhodes/event/EventStore.java +29 -8
  41. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +4 -1
  42. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +50 -10
  43. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/MapView.java +3 -0
  44. data/platform/android/build/android.rake +45 -23
  45. data/platform/android/build/librhocommon_build.files +1 -0
  46. data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBStorage.java +6 -1
  47. data/platform/bb/Hsqldb/src/org/hsqldb/CachedDataRow.java +1 -1
  48. data/platform/bb/Hsqldb/src/org/hsqldb/CachedRow.java +3 -2
  49. data/platform/bb/Hsqldb/src/org/hsqldb/Row.java +1 -1
  50. data/platform/bb/Hsqldb/src/org/hsqldb/persist/CachedObject.java +1 -1
  51. data/platform/bb/Hsqldb/src/org/hsqldb/persist/DataFileCache.java +66 -16
  52. data/platform/bb/Hsqldb/src/org/hsqldb/persist/HsqlDatabaseProperties.java +1 -1
  53. data/platform/bb/RubyVM/src/com/rho/RhoCrypto.java +116 -0
  54. data/platform/bb/RubyVM/src/com/rho/ThreadQueue.java +39 -2
  55. data/platform/bb/RubyVM/src/com/rho/Tokenizer.java +11 -6
  56. data/platform/bb/RubyVM/src/com/rho/db/DBAdapter.java +157 -150
  57. data/platform/bb/RubyVM/src/com/rho/db/IDBStorage.java +1 -1
  58. data/platform/bb/RubyVM/src/com/rho/file/RhoFile.java +15 -0
  59. data/platform/bb/RubyVM/src/com/rho/net/AsyncHttp.java +35 -23
  60. data/platform/bb/RubyVM/src/com/rho/net/NetRequest.java +6 -9
  61. data/platform/bb/RubyVM/src/com/rho/sync/SyncEngine.java +54 -16
  62. data/platform/bb/RubyVM/src/com/rho/sync/SyncNotify.java +18 -9
  63. data/platform/bb/RubyVM/src/com/rho/sync/SyncSource.java +37 -59
  64. data/platform/bb/RubyVM/src/com/rho/sync/SyncThread.java +3 -0
  65. data/platform/bb/build/RubyVM_build.files +1 -0
  66. data/platform/bb/build/bb.rake +4 -5
  67. data/platform/bb/rhodes/platform/5.0/com/rho/RhodesApplicationPlatform.java +4 -1
  68. data/platform/bb/rhodes/platform/5.0/com/rho/db/SqliteStorage.java +8 -3
  69. data/platform/bb/rhodes/resources/esri.png +0 -0
  70. data/platform/bb/rhodes/src/com/rho/RhodesApplicationPlatform.java +2 -0
  71. data/platform/bb/rhodes/src/com/rho/db/SqliteStorage.java +8 -3
  72. data/platform/bb/rhodes/src/com/rho/rubyext/RhoCalendar.java +4 -1
  73. data/platform/bb/rhodes/src/com/rho/rubyext/System.java +2 -0
  74. data/platform/bb/rhodes/src/rhomobile/mapview/ESRIMapField.java +9 -0
  75. data/platform/iphone/Classes/Event/Event.m +12 -2
  76. data/platform/iphone/Classes/NativeBar.h +12 -11
  77. data/platform/iphone/Classes/NativeBar.m +13 -3
  78. data/platform/iphone/Classes/Rhodes.m +48 -10
  79. data/platform/iphone/Classes/SimpleMainView.h +1 -0
  80. data/platform/iphone/Classes/SimpleMainView.m +7 -1
  81. data/platform/iphone/Classes/SplitView/LeftViewController.m +3 -0
  82. data/platform/iphone/Classes/SplitView/RightViewController.m +11 -6
  83. data/platform/iphone/Classes/SplitView/SplittedMainView.m +8 -0
  84. data/platform/iphone/Classes/TabbedMainView.m +39 -3
  85. data/platform/iphone/Info.plist +1 -1
  86. data/platform/iphone/RhoLib/RhoLib.xcodeproj/project.pbxproj +4 -0
  87. data/platform/iphone/rhorunner.xcodeproj/project.pbxproj +3 -3
  88. data/platform/shared/SyncClient/SyncClient.cpp +23 -23
  89. data/platform/shared/common/IRhoClassFactory.h +6 -4
  90. data/platform/shared/common/RhoAppAdapter.h +1 -1
  91. data/platform/shared/common/RhoFile.cpp +10 -0
  92. data/platform/shared/common/RhoFile.h +1 -0
  93. data/platform/shared/common/RhoMutexLock.h +1 -1
  94. data/platform/shared/common/RhoStd.h +5 -0
  95. data/platform/shared/common/RhoThread.cpp +2 -2
  96. data/platform/shared/common/RhoThread.h +1 -2
  97. data/platform/shared/common/RhodesApp.cpp +33 -55
  98. data/platform/shared/common/RhodesApp.h +0 -5
  99. data/platform/shared/common/RhodesAppBase.cpp +1 -1
  100. data/platform/shared/common/SplashScreen.cpp +1 -2
  101. data/platform/shared/common/ThreadQueue.cpp +31 -4
  102. data/platform/shared/common/ThreadQueue.h +10 -3
  103. data/platform/shared/common/Tokenizer.cpp +12 -8
  104. data/platform/shared/common/iphone/RhoClassFactory.cpp +5 -8
  105. data/platform/shared/common/iphone/RhoClassfactory.h +1 -1
  106. data/platform/shared/common/map/ESRIMapEngine.cpp +17 -7
  107. data/platform/shared/common/map/ESRIMapEngine.h +11 -1
  108. data/platform/shared/common/map/GoogleMapEngine.cpp +3 -3
  109. data/platform/shared/common/map/GoogleMapEngine.h +2 -2
  110. data/platform/shared/common/map/MapEngine.cpp +37 -0
  111. data/platform/shared/common/map/MapEngine.h +5 -0
  112. data/platform/shared/db/DBAdapter.cpp +113 -81
  113. data/platform/shared/db/DBAdapter.h +21 -5
  114. data/platform/shared/db/DBAttrManager.cpp +2 -2
  115. data/platform/shared/db/DBResult.h +28 -0
  116. data/platform/shared/net/AsyncHttp.cpp +48 -48
  117. data/platform/shared/net/AsyncHttp.h +15 -12
  118. data/platform/shared/net/CURLNetRequest.cpp +27 -105
  119. data/platform/shared/net/CURLNetRequest.h +8 -15
  120. data/platform/shared/net/INetRequest.cpp +122 -0
  121. data/platform/shared/net/INetRequest.h +96 -23
  122. data/platform/shared/net/ssl.cpp +1 -1
  123. data/platform/shared/ruby/ext/calendar/calendar.i +2 -2
  124. data/platform/shared/ruby/ext/calendar/calendar_wrap.c +30 -3
  125. data/platform/shared/rubyext/GeoLocation.cpp +4 -5
  126. data/platform/shared/rubyext/GeoLocation.h +4 -4
  127. data/platform/shared/rubyext/RhoAppAdapter.cpp +1 -1
  128. data/platform/shared/rubyext/System.cpp +3 -0
  129. data/platform/shared/sync/ClientRegister.cpp +6 -9
  130. data/platform/shared/sync/ClientRegister.h +8 -6
  131. data/platform/shared/sync/SyncEngine.cpp +54 -30
  132. data/platform/shared/sync/SyncEngine.h +9 -11
  133. data/platform/shared/sync/SyncNotify.cpp +19 -14
  134. data/platform/shared/sync/SyncNotify.h +5 -12
  135. data/platform/shared/sync/SyncSource.cpp +53 -76
  136. data/platform/shared/sync/SyncSource.h +5 -4
  137. data/platform/shared/sync/SyncThread.cpp +5 -7
  138. data/platform/shared/sync/SyncThread.h +2 -2
  139. data/platform/wm/RhoLib/RhoLib.vcproj +43 -39
  140. data/platform/wm/build/wm.rake +19 -17
  141. data/platform/wm/rhodes/AppManager.cpp +4 -4
  142. data/platform/wm/rhodes/MainWindow.cpp +0 -1
  143. data/platform/wm/rhodes/MapView/MapViewManager.cpp +4 -0
  144. data/platform/wm/rhodes/Vibrate.cpp +2 -2
  145. data/platform/wm/rhodes/Vibrate.h +1 -1
  146. data/platform/wm/rhodes/rho/common/RhoClassFactory.cpp +7 -5
  147. data/platform/wm/rhodes/rho/common/RhoClassFactory.h +3 -3
  148. data/platform/wm/rhodes/rho/net/NetRequestImpl.cpp +24 -10
  149. data/platform/wm/rhodes/rho/net/NetRequestImpl.h +49 -25
  150. data/platform/wm/rhodes/rho/rubyext/calendar.cpp +16 -2
  151. data/platform/wm/rhodes/rhodes.vcproj +77 -85
  152. data/platform/wm/tools/detool/detool.cpp +16 -6
  153. data/rakefile.rb +9 -5
  154. data/res/build-tools/detool.exe +0 -0
  155. data/rhodes.gemspec +2 -2
  156. data/spec/phone_spec/app/spec/blobsync_spec.rb +1 -0
  157. data/spec/phone_spec/app/spec/events_spec.rb +13 -2
  158. data/spec/phone_spec/app/spec/mapview_spec.rb +2 -2
  159. data/spec/phone_spec/app/spec/nativebar_spec.rb +3 -3
  160. data/spec/phone_spec/app/spec/navbar_spec.rb +3 -3
  161. data/spec/phone_spec/app/spec/rho_spec.rb +1 -1
  162. data/spec/phone_spec/app/spec/rhom_object_spec.rb +1 -1
  163. data/spec/phone_spec/app/spec/syncengine_spec.rb +219 -0
  164. data/spec/phone_spec/build.yml +1 -0
  165. metadata +15 -8
  166. data/platform/wm/rhodes/rho/net/NetRequest.cpp +0 -89
  167. data/platform/wm/rhodes/rho/net/NetRequest.h +0 -45
@@ -91,9 +91,12 @@ public class RhodesService extends Service {
91
91
  private static final Class[] mStartForegroundSignature = new Class[] {int.class, Notification.class};
92
92
  @SuppressWarnings("rawtypes")
93
93
  private static final Class[] mStopForegroundSignature = new Class[] {boolean.class};
94
+ @SuppressWarnings("rawtypes")
95
+ private static final Class[] mSetForegroundSignature = new Class[] {boolean.class};
94
96
 
95
97
  private Method mStartForeground;
96
98
  private Method mStopForeground;
99
+ private Method mSetForeground;
97
100
 
98
101
  private NotificationManager mNM;
99
102
 
@@ -278,8 +281,11 @@ public class RhodesService extends Service {
278
281
  createRhodesApp();
279
282
 
280
283
  RhodesActivity ra = RhodesActivity.getInstance();
281
- SplashScreen splashScreen = ra.getSplashScreen();
282
- splashScreen.start();
284
+ if (ra != null) {
285
+ // Show splash screen only if we have active activity
286
+ SplashScreen splashScreen = ra.getSplashScreen();
287
+ splashScreen.start();
288
+ }
283
289
 
284
290
  initForegroundServiceApi();
285
291
 
@@ -379,10 +385,12 @@ public class RhodesService extends Service {
379
385
  try {
380
386
  mStartForeground = getClass().getMethod("startForeground", mStartForegroundSignature);
381
387
  mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature);
388
+ mSetForeground = getClass().getMethod("setForeground", mSetForegroundSignature);
382
389
  }
383
390
  catch (NoSuchMethodException e) {
384
391
  mStartForeground = null;
385
392
  mStopForeground = null;
393
+ mSetForeground = null;
386
394
  }
387
395
  }
388
396
 
@@ -399,7 +407,7 @@ public class RhodesService extends Service {
399
407
  if (DEBUG)
400
408
  Log.d(TAG, "+++ onStart");
401
409
  try {
402
- handleCommand(intent);
410
+ handleCommand(intent, startId);
403
411
  }
404
412
  catch (Exception e) {
405
413
  Logger.E(TAG, "Can't handle service command: " + e.getMessage());
@@ -411,7 +419,7 @@ public class RhodesService extends Service {
411
419
  if (DEBUG)
412
420
  Log.d(TAG, "+++ onStartCommand");
413
421
  try {
414
- handleCommand(intent);
422
+ handleCommand(intent, startId);
415
423
  }
416
424
  catch (Exception e) {
417
425
  Logger.E(TAG, "Can't handle service command: " + e.getMessage());
@@ -419,13 +427,16 @@ public class RhodesService extends Service {
419
427
  return Service.START_STICKY;
420
428
  }
421
429
 
422
- private void handleCommand(Intent intent) {
430
+ private void handleCommand(Intent intent, int startId) {
423
431
  String source = intent.getStringExtra(INTENT_SOURCE);
432
+ Logger.D(TAG, "handleCommand: startId=" + startId + ", source=" + source);
424
433
  if (source == null)
425
434
  throw new IllegalArgumentException("Service command received from empty source");
426
435
 
427
- Logger.D(TAG, "Service command received from " + source);
428
- if (source.equals(PushReceiver.INTENT_SOURCE)) {
436
+ if (source.equals(BaseActivity.INTENT_SOURCE)) {
437
+ Logger.D(TAG, "New activity was created");
438
+ }
439
+ else if (source.equals(PushReceiver.INTENT_SOURCE)) {
429
440
  int type = intent.getIntExtra(PushReceiver.INTENT_TYPE, PushReceiver.INTENT_TYPE_UNKNOWN);
430
441
  switch (type) {
431
442
  case PushReceiver.INTENT_TYPE_REGISTRATION_ID:
@@ -458,7 +469,17 @@ public class RhodesService extends Service {
458
469
  return;
459
470
  }
460
471
 
461
- setForeground(true);
472
+ if (mSetForeground != null) {
473
+ try {
474
+ mSetForeground.invoke(this, new Object[] {Boolean.valueOf(true)});
475
+ }
476
+ catch (InvocationTargetException e) {
477
+ Log.e(TAG, "Unable to invoke setForeground", e);
478
+ }
479
+ catch (IllegalAccessException e) {
480
+ Log.e(TAG, "Unable to invoke setForeground", e);
481
+ }
482
+ }
462
483
  mNM.notify(id, notification);
463
484
  }
464
485
 
@@ -477,7 +498,17 @@ public class RhodesService extends Service {
477
498
  }
478
499
 
479
500
  mNM.cancel(id);
480
- setForeground(false);
501
+ if (mSetForeground != null) {
502
+ try {
503
+ mSetForeground.invoke(this, new Object[] {Boolean.valueOf(false)});
504
+ }
505
+ catch (InvocationTargetException e) {
506
+ Log.e(TAG, "Unable to invoke setForeground", e);
507
+ }
508
+ catch (IllegalAccessException e) {
509
+ Log.e(TAG, "Unable to invoke setForeground", e);
510
+ }
511
+ }
481
512
  }
482
513
 
483
514
  public void setMainView(MainView v) {
@@ -560,6 +591,46 @@ public class RhodesService extends Service {
560
591
  }
561
592
  }
562
593
 
594
+ public static boolean pingHost(String host) {
595
+ HttpURLConnection conn = null;
596
+ boolean hostExists = false;
597
+ try {
598
+ URL url = new URL(host);
599
+ HttpURLConnection.setFollowRedirects(false);
600
+ conn = (HttpURLConnection) url.openConnection();
601
+
602
+ conn.setRequestMethod("HEAD");
603
+ conn.setAllowUserInteraction( false );
604
+ conn.setDoInput( true );
605
+ conn.setDoOutput( true );
606
+ conn.setUseCaches( false );
607
+
608
+ hostExists = (conn.getContentLength() > 0);
609
+ if(hostExists)
610
+ Logger.I(TAG, "PING network SUCCEEDED.");
611
+ else
612
+ Logger.E(TAG, "PING network FAILED.");
613
+ }
614
+ catch (Exception e) {
615
+ Logger.E(TAG, e);
616
+ }
617
+ finally {
618
+ if (conn != null)
619
+ {
620
+ try
621
+ {
622
+ conn.disconnect();
623
+ }
624
+ catch(Exception e)
625
+ {
626
+ Logger.E(TAG, e);
627
+ }
628
+ }
629
+ }
630
+
631
+ return hostExists;
632
+ }
633
+
563
634
  private static boolean hasNetwork() {
564
635
  if (!Capabilities.NETWORK_STATE_ENABLED) {
565
636
  Logger.E(TAG, "HAS_NETWORK: Capability NETWORK_STATE disabled");
@@ -12,6 +12,7 @@ import android.os.Build;
12
12
 
13
13
  import com.rhomobile.rhodes.Capabilities;
14
14
  import com.rhomobile.rhodes.Logger;
15
+ import com.rhomobile.rhodes.RhodesActivity;
15
16
  import com.rhomobile.rhodes.RhodesService;
16
17
 
17
18
  public class EventStore {
@@ -106,7 +107,7 @@ public class EventStore {
106
107
 
107
108
  eventCursor = r.query(builder.build(),
108
109
  new String[] {"event_id", EVENTS_TITLE, "begin", "end", EVENTS_LOCATION,
109
- EVENTS_NOTES, EVENTS_PRIVACY},
110
+ EVENTS_NOTES, EVENTS_PRIVACY, "deleted"},
110
111
  null, //"Calendars._id=" + id,
111
112
  null, "startDay ASC, startMinute ASC");
112
113
  }
@@ -117,7 +118,7 @@ public class EventStore {
117
118
  String end = Long.toString(endDate.getTime());
118
119
  eventCursor = r.query(EVENTS_URI,
119
120
  new String[] {"_id", EVENTS_TITLE, EVENTS_START_DATE, EVENTS_END_DATE,
120
- EVENTS_LOCATION, EVENTS_NOTES, EVENTS_PRIVACY},
121
+ EVENTS_LOCATION, EVENTS_NOTES, EVENTS_PRIVACY, "deleted"},
121
122
  where, new String[] {start, end, start, end},
122
123
  null);
123
124
  }
@@ -125,6 +126,15 @@ public class EventStore {
125
126
  throw new RuntimeException("Calendar provider not found");
126
127
  try {
127
128
  while (eventCursor.moveToNext()) {
129
+
130
+ int deleted_index = eventCursor.getColumnIndex("deleted");
131
+ if (deleted_index >= 0) {
132
+ long is_deleted = eventCursor.getLong(deleted_index);
133
+ if (is_deleted != 0) {
134
+ continue;
135
+ }
136
+ }
137
+
128
138
  String eid = eventCursor.getString(0);
129
139
  Event event = new Event(eid);
130
140
 
@@ -192,6 +202,7 @@ public class EventStore {
192
202
  Logger.D(TAG, "fetch(id): result set is empty");
193
203
  return null;
194
204
  }
205
+
195
206
  Event event = new Event(id);
196
207
  event.title = eventCursor.getString(0);
197
208
  event.startDate = new Date(eventCursor.getLong(1));
@@ -223,6 +234,7 @@ public class EventStore {
223
234
  }
224
235
 
225
236
  public static String save(Event event) {
237
+ String return_id = null;
226
238
  try {
227
239
  checkCapabilities();
228
240
 
@@ -256,39 +268,48 @@ public class EventStore {
256
268
  if (event.id == null || event.id.equalsIgnoreCase("")) {
257
269
  Logger.D(TAG, "Insert new event...");
258
270
  Uri euri = r.insert(EVENTS_URI, values);
271
+ r.notifyChange(EVENTS_URI, null);
259
272
  event.id = Long.toString(ContentUris.parseId(euri));
260
273
  Logger.D(TAG, "Event id of event is " + event.id);
274
+ return_id = event.id;
261
275
  }
262
276
  else {
277
+ return_id = event.id;
263
278
  Logger.D(TAG, "Update event...");
264
279
  Uri uri = ContentUris.withAppendedId(EVENTS_URI, Long.parseLong(event.id));
265
280
  r.update(uri, values, null, null);
281
+ r.notifyChange(EVENTS_URI, null);
266
282
  Logger.D(TAG, "Event updated");
267
283
  }
268
-
269
- return null;
270
284
  }
271
285
  catch (Exception e) {
272
286
  reportFail("save", e);
273
- String error = e.getMessage();
274
- return error == null ? "unknown" : error;
287
+ //String error = e.getMessage();
288
+ return null;//error == null ? "unknown" : error;
275
289
  }
290
+ return return_id;
276
291
  }
277
292
 
278
293
  public static String delete(String id) {
279
294
  try {
280
295
  checkCapabilities();
281
296
 
282
- Logger.D(TAG, "delete(id)");
297
+ Logger.D(TAG, "delete("+id+")");
283
298
 
284
299
  ContentResolver r = getContentResolver();
285
300
  int rows;
286
301
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {
302
+ Logger.D(TAG, " use old delete scheme");
287
303
  Uri uri = ContentUris.withAppendedId(EVENTS_URI, Long.parseLong(id));
288
304
  rows = getContentResolver().delete(uri, null, null);
289
305
  }
290
306
  else {
291
- rows = r.delete(EVENTS_URI, "_id=?", new String[] {id});
307
+ Logger.D(TAG, " use new delete scheme");
308
+ int idn = Integer.decode(id).intValue();
309
+ Uri du = Uri.withAppendedPath(EVENTS_URI, id);
310
+ rows = r.delete(du, null, null);
311
+ //rows = r.delete(EVENTS_URI, "_id=?", new String[] {id});
312
+ r.notifyChange(EVENTS_URI, null);
292
313
  }
293
314
  Logger.D(TAG, String.format("%d rows deleted", rows));
294
315
 
@@ -572,7 +572,10 @@ public class SimpleMainView implements MainView {
572
572
  public void navigate(String url, int index) {
573
573
  String cleared_url = processForNativeView(url);
574
574
  if (cleared_url.length() > 0) {
575
- webView.loadUrl(url);
575
+ // check for handle because if we call loadUrl - WebView do not check this url for handle
576
+ if (!RhodesService.getInstance().handleUrlLoading(cleared_url)) {
577
+ webView.loadUrl(cleared_url);
578
+ }
576
579
  }
577
580
  }
578
581
 
@@ -488,9 +488,20 @@ public class TabbedMainView implements MainView {
488
488
  throw new IllegalArgumentException("'label' should be String");
489
489
 
490
490
  Object actionObj = hash.get("action");
491
+
492
+ boolean use_current_view_for_tab = false;
493
+ Object use_current_view_for_tab_Obj = hash.get("use_current_view_for_tab");
494
+ if (use_current_view_for_tab_Obj != null) {
495
+ use_current_view_for_tab = ((String)use_current_view_for_tab_Obj).equalsIgnoreCase("true");
496
+ }
497
+
498
+ if (use_current_view_for_tab) {
499
+ actionObj = new String("none");
500
+ }
491
501
  if (actionObj == null || !(actionObj instanceof String))
492
502
  throw new IllegalArgumentException("'action' should be String");
493
503
 
504
+
494
505
  String label = (String)labelObj;
495
506
  String action = (String)actionObj;
496
507
  String icon = null;
@@ -557,11 +568,22 @@ public class TabbedMainView implements MainView {
557
568
  else
558
569
  spec.setIndicator(label, drawable);
559
570
 
571
+ SimpleMainView view = null;
572
+ if (use_current_view_for_tab) {
573
+ RhodesService r = RhodesService.getInstance();
574
+ MainView mainView = r.getMainView();
575
+ action = mainView.currentLocation(-1);
576
+ view = new SimpleMainView(mainView);
577
+ }
578
+ else {
579
+ view = new SimpleMainView();
580
+ }
560
581
  // Set view factory
561
- SimpleMainView view = new SimpleMainView();
562
582
 
563
583
  if (web_bkg_color_Obj != null) {
564
- view.setWebBackgroundColor(web_bkg_color);
584
+ if (!use_current_view_for_tab) {
585
+ view.setWebBackgroundColor(web_bkg_color);
586
+ }
565
587
  host.setBackgroundColor(web_bkg_color);
566
588
  }
567
589
 
@@ -570,6 +592,11 @@ public class TabbedMainView implements MainView {
570
592
  data.url = action;
571
593
  data.reload = reload;
572
594
 
595
+ if (use_current_view_for_tab) {
596
+ data.loaded = true;
597
+ tabIndex = i;
598
+ }
599
+
573
600
  data.selected_color = selected_color;
574
601
  data.selected_color_enabled = selected_color_enable;
575
602
  data.disabled = disabled;
@@ -596,23 +623,32 @@ public class TabbedMainView implements MainView {
596
623
  int sel_col = 0;
597
624
  boolean sel_col_enable = false;
598
625
 
599
- tabIndex = 0;
626
+ int cur_tabIndex = 0;
600
627
  TabData data = null;
601
628
  boolean founded_not_disabled = false;
602
629
 
603
- while ((!founded_not_disabled) && (tabIndex < tabData.size())) {
604
- data = tabData.elementAt(tabIndex);
630
+ while ((!founded_not_disabled) && (cur_tabIndex < tabData.size())) {
631
+ data = tabData.elementAt(cur_tabIndex);
605
632
  if ((data != null) && (!data.disabled)) {
606
633
  founded_not_disabled = true;
607
634
  }
608
635
  else {
609
- tabIndex++;
636
+ cur_tabIndex++;
610
637
  }
611
638
  }
612
639
  if (!founded_not_disabled) {
613
640
  Logger.E(TAG, "ERROR : All tabs is disabled !!! ");
614
641
  }
615
642
 
643
+ if ((tabIndex != cur_tabIndex) && (tabIndex != 0)) {
644
+ data = tabData.elementAt(tabIndex);
645
+ }
646
+ else {
647
+ tabIndex = cur_tabIndex;
648
+ }
649
+
650
+
651
+
616
652
  if (data != null) {
617
653
  sel_col = data.selected_color;
618
654
  sel_col_enable = data.selected_color_enabled;
@@ -658,8 +694,10 @@ public class TabbedMainView implements MainView {
658
694
 
659
695
  if (data != null) {
660
696
  try {
661
- RhodesService.loadUrl(data.url);
662
- data.loaded = true;
697
+ if (!data.loaded) {
698
+ RhodesService.loadUrl(data.url);
699
+ data.loaded = true;
700
+ }
663
701
  sel_col = data.selected_color;
664
702
  sel_col_enable = data.selected_color_enabled;
665
703
  }
@@ -691,8 +729,10 @@ public class TabbedMainView implements MainView {
691
729
  }
692
730
  }
693
731
  TabData selected_data = tabData.elementAt(tabIndex);
694
- RhodesService.loadUrl(selected_data.url);
695
- selected_data.loaded = true;
732
+ if (!selected_data.loaded) {
733
+ RhodesService.loadUrl(selected_data.url);
734
+ selected_data.loaded = true;
735
+ }
696
736
  mIsReallyOnScreen = true;
697
737
  }
698
738
  });
@@ -41,6 +41,7 @@ public class MapView extends BaseActivity implements MapTouch {
41
41
  public native void setPinImage(long nativeDevice, Bitmap pin);
42
42
  public native void setPinCalloutImage(long nativeDevice, Bitmap pin);
43
43
  public native void setPinCalloutLinkImage(long nativeDevice, Bitmap pin);
44
+ public native void setESRILogoImage(long nativeDevice, Bitmap esriLogo);
44
45
 
45
46
  public native int minZoom(long nativeDevice);
46
47
  public native int maxZoom(long nativeDevice);
@@ -122,6 +123,8 @@ public class MapView extends BaseActivity implements MapTouch {
122
123
  setPinCalloutImage(mNativeDevice, pinCallout );
123
124
  Bitmap pinCalloutLink = BitmapFactory.decodeResource(getResources(), AndroidR.drawable.callout_link);
124
125
  setPinCalloutLinkImage(mNativeDevice, pinCalloutLink );
126
+ Bitmap esriLogo = BitmapFactory.decodeResource(getResources(), AndroidR.drawable.esri);
127
+ setESRILogoImage(mNativeDevice, esriLogo);
125
128
 
126
129
 
127
130
  mTouchHandler = createTouchHandler();
@@ -7,7 +7,7 @@ USE_TRACES = false
7
7
 
8
8
  ANDROID_API_LEVEL_TO_MARKET_VERSION = {}
9
9
  ANDROID_MARKET_VERSION_TO_API_LEVEL = {}
10
- {2 => "1.1", 3 => "1.5", 4 => "1.6", 5 => "2.0", 6 => "2.0.1", 7 => "2.1", 8 => "2.2", 9 => "2.3"}.each do |k,v|
10
+ {2 => "1.1", 3 => "1.5", 4 => "1.6", 5 => "2.0", 6 => "2.0.1", 7 => "2.1", 8 => "2.2", 9 => "2.3", 10 => "2.3.3", 11 => "3.0" }.each do |k,v|
11
11
  ANDROID_API_LEVEL_TO_MARKET_VERSION[k] = v
12
12
  ANDROID_MARKET_VERSION_TO_API_LEVEL[v] = k
13
13
  end
@@ -277,6 +277,7 @@ namespace "config" do
277
277
  $vendor = $vendor.gsub(/^[^A-Za-z]/, '_').gsub(/[^A-Za-z0-9]/, '_').gsub(/_+/, '_').downcase
278
278
  $app_package_name = $app_config["android"] ? $app_config["android"]["package_name"] : nil
279
279
  $app_package_name = "com.#{$vendor}." + $appname.downcase.gsub(/[^A-Za-z_0-9]/, '') unless $app_package_name
280
+ $app_package_name.gsub!(/\.[\d]/, "._")
280
281
 
281
282
  $rhomanifest = File.join $androidpath, "Rhodes", "AndroidManifest.xml"
282
283
  $appmanifest = File.join $tmpdir, "AndroidManifest.xml"
@@ -367,6 +368,7 @@ namespace "config" do
367
368
  $adb = File.join( $androidsdkpath, "platform-tools", "adb" + $exe_ext ) unless File.exists? $adb
368
369
  $zipalign = File.join( $androidsdkpath, "tools", "zipalign" + $exe_ext )
369
370
  $androidjar = File.join($androidsdkpath, "platforms", $androidplatform, "android.jar")
371
+ $dxjar = File.join( $androidsdkpath, "platform-tools", "lib", "dx.jar")
370
372
 
371
373
  $keytool = File.join( $java, "keytool" + $exe_ext )
372
374
  $jarsigner = File.join( $java, "jarsigner" + $exe_ext )
@@ -1014,17 +1016,18 @@ namespace "build" do
1014
1016
  lines << line
1015
1017
  end
1016
1018
  end
1017
- lines << File.join($app_rjava_dir, "R.java")
1018
- lines << $app_android_r
1019
- lines << $app_native_libs_java
1020
- lines << $app_capabilities_java
1021
- lines << $app_push_java
1019
+ lines << "\"" +File.join($app_rjava_dir, "R.java")+"\""
1020
+ lines << "\"" +$app_android_r+"\""
1021
+ lines << "\"" +$app_native_libs_java+"\""
1022
+ lines << "\"" +$app_capabilities_java+"\""
1023
+ lines << "\"" +$app_push_java+"\""
1022
1024
  if File.exists? File.join($extensionsdir, "ext_build.files")
1023
1025
  puts 'ext_build.files found ! Addditional files for compilation :'
1024
1026
  File.open(File.join($extensionsdir, "ext_build.files")) do |f|
1025
1027
  while line = f.gets
1028
+ line=line.gsub("\n","\"")
1026
1029
  puts 'java file : ' + line
1027
- lines << line
1030
+ lines << "\""+line
1028
1031
  end
1029
1032
  end
1030
1033
  else
@@ -1092,10 +1095,12 @@ namespace "package" do
1092
1095
  task :android => "build:android:all" do
1093
1096
  puts "Running dx utility"
1094
1097
  args = []
1098
+ args << "-jar"
1099
+ args << $dxjar
1095
1100
  args << "--dex"
1096
1101
  args << "--output=#{$bindir}/classes.dex"
1097
1102
  args << "#{$bindir}/Rhodes.jar"
1098
- puts Jake.run($dx, args)
1103
+ puts Jake.run("java", args)
1099
1104
  unless $?.success?
1100
1105
  puts "Error running DX utility"
1101
1106
  exit 1
@@ -1371,10 +1376,14 @@ namespace "run" do
1371
1376
  start = Time.now
1372
1377
 
1373
1378
  puts "waiting for log"
1374
-
1375
- while !File.exist?(log_name)
1376
- get_app_log($appname, false, true)
1377
- sleep(1)
1379
+
1380
+ for i in 0..60
1381
+ if !File.exist?(log_name)
1382
+ get_app_log($appname, false, true)
1383
+ sleep(1)
1384
+ else
1385
+ break
1386
+ end
1378
1387
  end
1379
1388
 
1380
1389
  puts "start read log"
@@ -1413,13 +1422,11 @@ namespace "run" do
1413
1422
  end
1414
1423
 
1415
1424
  task :phone_spec do
1416
- exit 1 if Jake.run_spec_app('android','phone_spec')
1417
- exit 0
1425
+ exit Jake.run_spec_app('android','phone_spec')
1418
1426
  end
1419
1427
 
1420
1428
  task :framework_spec do
1421
- exit 1 if Jake.run_spec_app('android','framework_spec')
1422
- exit 0
1429
+ exit Jake.run_spec_app('android','framework_spec')
1423
1430
  end
1424
1431
 
1425
1432
  task :emulator => "device:android:debug" do
@@ -1456,7 +1463,7 @@ namespace "run" do
1456
1463
 
1457
1464
  if !running
1458
1465
  # Start the emulator, check on it every 5 seconds until it's running
1459
- Thread.new { system("\"#{$emulator}\" -avd #{$avdname}") }
1466
+ Thread.new { system("\"#{$emulator}\" -cpu-delay 0 -no-boot-anim -avd #{$avdname}") }
1460
1467
  puts "Waiting up to 180 seconds for emulator..."
1461
1468
  startedWaiting = Time.now
1462
1469
  adbRestarts = 1
@@ -1546,13 +1553,28 @@ namespace "uninstall" do
1546
1553
  args << flag
1547
1554
  args << "uninstall"
1548
1555
  args << $app_package_name
1549
- Jake.run($adb, args)
1550
- unless $?.success?
1551
- puts "Error uninstalling application"
1552
- exit 1
1556
+ for i in 0..20
1557
+ result = Jake.run($adb, args)
1558
+ unless $?.success?
1559
+ puts "Error uninstalling application"
1560
+ exit 1
1561
+ end
1562
+
1563
+ if result.include?("Success")
1564
+ puts "Application uninstalled successfully"
1565
+ break
1566
+ else
1567
+ if result.include?("Failure")
1568
+ puts "Application is not installed on the device"
1569
+ break
1570
+ else
1571
+ puts "Error uninstalling application"
1572
+ exit 1 if i == 20
1573
+ end
1574
+ end
1575
+ sleep(5)
1553
1576
  end
1554
-
1555
- puts "Application uninstalled successfully"
1577
+
1556
1578
  end
1557
1579
 
1558
1580
  namespace "android" do
@@ -18,6 +18,7 @@ platform/shared/net/CURLNetRequest.cpp
18
18
  platform/shared/net/HttpServer.cpp
19
19
  platform/shared/net/ssl.cpp
20
20
  platform/shared/net/URI.cpp
21
+ platform/shared/net/INetRequest.cpp
21
22
  platform/shared/rubyext/GeoLocation.cpp
22
23
  platform/shared/rubyext/RhoAppAdapter.cpp
23
24
  platform/shared/rubyext/System.cpp
@@ -7,6 +7,7 @@ import com.rho.db.IDBResult;
7
7
  import com.rho.db.IDBStorage;
8
8
  import org.hsqldb.*;
9
9
  import org.hsqldb.persist.*;
10
+ import com.rho.AppBuildConfig;
10
11
 
11
12
  public class HsqlDBStorage implements IDBStorage, Session.IDBCallback
12
13
  {
@@ -31,6 +32,7 @@ public class HsqlDBStorage implements IDBStorage, Session.IDBCallback
31
32
  m_fs.delete(strDbName + ".script");
32
33
  m_fs.delete(strDbName + ".script.new");
33
34
  m_fs.delete(strDbName + ".journal");
35
+ m_fs.delete(strDbName + ".properties");
34
36
  }
35
37
 
36
38
  private String getNameNoExt(String strPath){
@@ -50,7 +52,7 @@ public class HsqlDBStorage implements IDBStorage, Session.IDBCallback
50
52
  return m_fs.exists(strDbName + ".data");
51
53
  }
52
54
 
53
- public void open(String strPath, String strSqlScript) throws DBException
55
+ public void open(String strPath, String strSqlScript, String strEncryptionInfo) throws DBException
54
56
  {
55
57
  try{
56
58
  m_strSqlScript = strSqlScript;
@@ -59,6 +61,9 @@ public class HsqlDBStorage implements IDBStorage, Session.IDBCallback
59
61
  HsqlProperties props = new HsqlProperties();
60
62
  props.setProperty(HsqlDatabaseProperties.hsqldb_default_table_type, "cached");
61
63
 
64
+ if ( strEncryptionInfo != null && strEncryptionInfo.length() > 0 )
65
+ props.setProperty(HsqlDatabaseProperties.hsqldb_encrypted, strEncryptionInfo);
66
+
62
67
  if ( !m_fs.exists(strDbName + ".script") && m_fs.exists(strDbName + ".script.new") )
63
68
  m_fs.renameElement(strDbName + ".script.new", strDbName + ".script");
64
69
 
@@ -118,7 +118,7 @@ class CachedDataRow extends CachedRow {
118
118
  * to true when changes are made to the Nodes. (Nodes are in-memory).
119
119
  * The only time this is used is when a new Row is added to the Caches.
120
120
  */
121
- public void write(RowOutputInterface out) {
121
+ public void write(RowOutputInterface out, boolean bFullSave) {
122
122
 
123
123
  out.writeSize(storageSize);
124
124
  out.writeData(oData, tTable);
@@ -310,12 +310,13 @@ public class CachedRow extends Row {
310
310
  * @throws IOException
311
311
  * @throws HsqlException
312
312
  */
313
- public void write(RowOutputInterface out) {
313
+ public void write(RowOutputInterface out, boolean bFullSave) {
314
314
 
315
315
  try {
316
316
  writeNodes(out);
317
317
 
318
- if (hasDataChanged) {
318
+ if (bFullSave || hasDataChanged)
319
+ {
319
320
  out.writeData(oData, tTable);
320
321
  out.writeEnd();
321
322
 
@@ -243,7 +243,7 @@ public class Row implements CachedObject {
243
243
 
244
244
  public void setInMemory(boolean in) {}
245
245
 
246
- public void write(RowOutputInterface out) {}
246
+ public void write(RowOutputInterface out, boolean bFullSave) {}
247
247
 
248
248
  public void write(RowOutputInterface out, IntLookup lookup) {}
249
249
 
@@ -63,7 +63,7 @@ public interface CachedObject {
63
63
 
64
64
  void setInMemory(boolean in);
65
65
 
66
- void write(RowOutputInterface out);
66
+ void write(RowOutputInterface out, boolean bFullSave);
67
67
 
68
68
  void write(RowOutputInterface out, IntLookup lookup);
69
69
  }