platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java in rhodes-2.0.3 vs platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java in rhodes-2.1.0
- old
+ new
@@ -18,617 +18,88 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
============================================================================
*/
package com.rhomobile.rhodes;
-import java.io.File;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.Vector;
-
-import com.rhomobile.rhodes.Utils.AssetsSource;
-import com.rhomobile.rhodes.Utils.FileSource;
-import com.rhomobile.rhodes.geolocation.GeoLocation;
import com.rhomobile.rhodes.mainview.MainView;
-import com.rhomobile.rhodes.ui.AboutDialog;
-import com.rhomobile.rhodes.ui.LogOptionsDialog;
-import com.rhomobile.rhodes.ui.LogViewDialog;
-import com.rhomobile.rhodes.uri.MailUriHandler;
-import com.rhomobile.rhodes.uri.SmsUriHandler;
-import com.rhomobile.rhodes.uri.TelUriHandler;
-import com.rhomobile.rhodes.uri.UriHandler;
-import com.rhomobile.rhodes.uri.VideoUriHandler;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.Build;
import android.os.Bundle;
-import android.os.Environment;
import android.os.Handler;
-import android.telephony.TelephonyManager;
-import android.util.DisplayMetrics;
import android.util.Log;
-import android.view.Display;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.View;
import android.view.Window;
-import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
-import android.webkit.JsResult;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
import android.widget.FrameLayout;
-import android.os.Process;
-public class Rhodes extends Activity {
+public class Rhodes extends RhoActivity {
private static final String TAG = "Rhodes";
- public static final String INTENT_EXTRA_PREFIX = "com.rhomobile.rhodes.";
+ private static Rhodes instance = null;
- public static final int RHO_SPLASH_VIEW = 1;
- public static final int RHO_MAIN_VIEW = 2;
- public static final int RHO_TOOLBAR_VIEW = 3;
-
- public static int WINDOW_FLAGS = WindowManager.LayoutParams.FLAG_FULLSCREEN;
- public static int WINDOW_MASK = WindowManager.LayoutParams.FLAG_FULLSCREEN;
-
- public static int MAX_PROGRESS = 10000;
-
- public static boolean ENABLE_LOADING_INDICATION = true;
-
- private static boolean ownActivityActivated;
-
- private boolean needGeoLocationRestart = false;
-
- private long uiThreadId;
- public long getUiThreadId() {
- return uiThreadId;
+ public static Rhodes getInstance() {
+ return instance;
}
- private final Handler uiHandler = new Handler();
-
- private static int screenWidth;
- private static int screenHeight;
-
- private static float screenPpiX;
- private static float screenPpiY;
-
- private static boolean isCameraAvailable;
-
- private FrameLayout outerFrame;
- private MainView mainView;
-
- private SplashScreen splashScreen = null;
-
- private Boolean contentChanged = null;
-
- private Vector<UriHandler> uriHandlers = new Vector<UriHandler>();
-
- //private String sdCardError = "Application can not access the SD card while it's mounted. Please unmount the device and stop the adb server before launching the app.";
-
private RhoMenu appMenu = null;
- private String rootPath = null;
-
- public native void createRhodesApp(String rootPath, String sqliteJournalsPath);
- public native void startRhodesApp();
- public native void stopRhodesApp();
-
- public native void doSyncAllSources(boolean v);
-
- public native String getOptionsUrl();
- public native String getStartUrl();
- public native String getCurrentUrl();
- public native String getAppBackUrl();
-
- public native String normalizeUrl(String url);
-
- public static native void loadUrl(String url);
-
- public static native void navigateBack();
-
- public native void doRequest(String url);
-
- public native static void makeLink(String src, String dst);
-
- private native void initClassLoader(ClassLoader c);
-
- private void initRootPath() {
- Log.d(TAG, "Check if the SD card is mounted...");
- String state = Environment.getExternalStorageState();
- Log.d(TAG, "Storage state: " + state);
- boolean hasSDCard = Environment.MEDIA_MOUNTED.equals(state);
- rootPath = hasSDCard ? sdcardRootPath() : phoneMemoryRootPath();
- }
-
- public String getRootPath() {
- return rootPath;
- }
-
- private ApplicationInfo getAppInfo() {
- String pkgName = getPackageName();
- try {
- ApplicationInfo info = getPackageManager().getApplicationInfo(pkgName, 0);
- return info;
- } catch (NameNotFoundException e) {
- throw new RuntimeException("Internal error: package " + pkgName + " not found: " + e.getMessage());
- }
- }
-
- private String getSqliteJournalsPath() {
- String path = getAppInfo().dataDir + "/sqlite_stmt_journals/";
- new File(path).mkdirs();
- return path;
- }
-
- private String phoneMemoryRootPath() {
- return getAppInfo().dataDir + "/rhodata/";
- }
-
- private String sdcardRootPath() {
- String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
- String pkgName = getPackageName();
- String path = sdPath + "/rhomobile/" + pkgName + "/";
- return path;
- }
-
- public static String getBlobPath() {
- return RhodesInstance.getInstance().getRootPath() + "/db/db-files";
- }
-
- private RhoLogConf m_rhoLogConf = new RhoLogConf();
- public RhoLogConf getLogConf() {
- return m_rhoLogConf;
- }
-
- /*
- private boolean checkSDCard() {
- Log.d(TAG, "Check if the SD card is mounted...");
- String state = Environment.getExternalStorageState();
- Log.d(TAG, "Storage state: " + state);
- if(!Environment.MEDIA_MOUNTED.equals(state)) {
- new AlertDialog.Builder(this)
- .setTitle("SD card error")
- .setMessage(sdCardError)
- .setCancelable(false)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- Log.e(this.getClass().getSimpleName(), "Exit - SD card is not accessible");
- Process.killProcess(Process.myPid());
- }
- })
- .create()
- .show();
- return false;
- }
- Log.d(TAG, "SD card check passed, going on");
- return true;
- }
- */
-
- private void copyFromBundle(String file) throws IOException {
- File target = new File(getRootPath(), file);
- if (target.exists())
- return;
- FileSource as = new AssetsSource(getResources().getAssets());
- Utils.copyRecursively(as, file, target, true);
-
- /*
- int idx = file.indexOf('/');
- String dir = idx == -1 ? file : file.substring(0, idx);
-
- File sdPath = new File(sdcardRootPath(), dir);
- File phPath = new File(phoneMemoryRootPath(), dir);
- phPath.getParentFile().mkdirs();
- makeLink(sdPath.getAbsolutePath(), phPath.getAbsolutePath());
- */
- }
-
- public boolean isNameChanged() {
- try {
- FileSource as = new AssetsSource(getResources().getAssets());
- FileSource fs = new FileSource();
- return !Utils.isContentsEquals(as, "name", fs, new File(getRootPath(), "name").getPath());
- }
- catch (IOException e) {
- return true;
- }
- }
-
- public boolean isBundleChanged() {
- if (contentChanged == null) {
- try {
- String rp = getRootPath();
-
- FileSource as = new AssetsSource(getResources().getAssets());
- FileSource fs = new FileSource();
-
- if (isNameChanged())
- contentChanged = new Boolean(true);
- else
- contentChanged = new Boolean(!Utils.isContentsEquals(as, "hash", fs, new File(rp, "hash").getPath()));
- }
- catch (IOException e) {
- contentChanged = new Boolean(true);
- }
- }
- return contentChanged.booleanValue();
- }
-
- private void copyFilesFromBundle() {
- try {
- if (isBundleChanged()) {
- Logger.D(TAG, "Copying required files from bundle");
-
- boolean nameChanged = isNameChanged();
-
- String rp = getRootPath();
-
- FileSource as = new AssetsSource(getResources().getAssets());
-
- String items[] = {"apps", "lib", "db", "hash", "name"};
- for (int i = 0; i != items.length; ++i) {
- String item = items[i];
- File f = new File(rp, item);
- Logger.D(TAG, "Copy '" + item + "' to '" + f.getAbsolutePath() + "'");
- Utils.copyRecursively(as, item, f, nameChanged);
- /*
- String src = sdf.getAbsolutePath();
- String dst = phf.getAbsolutePath();
- Logger.D(TAG, "Make symlink from '" + src + "' to '" + dst + "'");
- makeLink(src, dst);
- */
- }
-
- contentChanged = new Boolean(true);
- Logger.D(TAG, "All files copied");
- }
- else
- Logger.D(TAG, "No need to copy files to SD card");
- } catch (IOException e) {
- Logger.E(TAG, e);
- return;
- }
- }
-
- private boolean handleUrlLoading(String url) {
- Enumeration<UriHandler> e = uriHandlers.elements();
- while (e.hasMoreElements()) {
- UriHandler handler = e.nextElement();
- try {
- if (handler.handle(url))
- return true;
- }
- catch (Exception ex) {
- continue;
- }
- }
-
- return false;
- }
-
- public WebView createWebView() {
- WebView w = new WebView(this);
-
- WebSettings webSettings = w.getSettings();
- webSettings.setSavePassword(false);
- webSettings.setSaveFormData(false);
- webSettings.setJavaScriptEnabled(true);
- webSettings.setJavaScriptCanOpenWindowsAutomatically(false);
- webSettings.setSupportZoom(false);
- webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
- webSettings.setSupportMultipleWindows(false);
- // webSettings.setLoadsImagesAutomatically(true);
-
- w.setVerticalScrollBarEnabled(true);
- w.setHorizontalScrollBarEnabled(true);
- w.setVerticalScrollbarOverlay(true);
- w.setHorizontalScrollbarOverlay(true);
- w.setFocusableInTouchMode(true);
-
- w.setWebViewClient(new WebViewClient() {
-
- private boolean splashHidden = false;
-
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- return handleUrlLoading(url);
- }
-
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- if (ENABLE_LOADING_INDICATION)
- getWindow().setFeatureInt(Window.FEATURE_PROGRESS, 0);
- super.onPageStarted(view, url, favicon);
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
- // Set title
- Rhodes r = RhodesInstance.getInstance();
- String title = view.getTitle();
- r.setTitle(title);
- // Hide splash screen
- if (!splashHidden && url.startsWith("http://")) {
- hideSplashScreen();
- splashHidden = true;
- }
- if (ENABLE_LOADING_INDICATION)
- getWindow().setFeatureInt(Window.FEATURE_PROGRESS, MAX_PROGRESS);
- super.onPageFinished(view, url);
- }
-
- });
-
- w.setWebChromeClient(new WebChromeClient() {
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- if (ENABLE_LOADING_INDICATION) {
- newProgress *= 100;
- if (newProgress < 0)
- newProgress = 0;
- if (newProgress > MAX_PROGRESS)
- newProgress = MAX_PROGRESS;
- getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress);
- }
- super.onProgressChanged(view, newProgress);
- }
-
- @Override
- public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
- return false;
- }
-
- @Override
- public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
- return false;
- }
- });
-
- return w;
- }
-
- public void setMainView(MainView v) {
- View main = outerFrame.findViewById(RHO_MAIN_VIEW);
- if (main != null)
- outerFrame.removeView(main);
- mainView = v;
- main = mainView.getView();
- if (outerFrame.findViewById(RHO_SPLASH_VIEW) != null)
- main.setVisibility(View.INVISIBLE);
- outerFrame.addView(main);
- }
-
- public MainView getMainView() {
- return mainView;
- }
-
- private static class PerformOnUiThread implements Runnable {
-
- private Runnable runnable;
-
- public PerformOnUiThread(Runnable r) {
- runnable = r;
- }
-
- public void run() {
- try {
- runnable.run();
- }
- catch (Exception e) {
- Logger.E("Rhodes", "PerformOnUiThread failed: " + e.getMessage());
- }
- finally {
- synchronized (runnable) {
- runnable.notify();
- }
- }
- }
- };
-
- public static void performOnUiThread(Runnable r, boolean wait) {
- try {
- Rhodes rhodes = RhodesInstance.getInstance();
- if (!wait) {
- rhodes.uiHandler.post(r);
- }
- else {
- long thrId = Thread.currentThread().getId();
- if (rhodes.getUiThreadId() == thrId) {
- // We are already in UI thread
- r.run();
- }
- else {
- // Post request to UI thread and wait when it would be done
- synchronized (r) {
- rhodes.uiHandler.post(new PerformOnUiThread(r));
- r.wait();
- }
- }
- }
- }
- catch (Exception e) {
- Logger.E("Rhodes", "performOnUiThread failed: " + e.getMessage());
- }
- }
-
- private void showSplashScreen() {
- splashScreen = new SplashScreen(this);
- splashScreen.start(outerFrame);
- }
-
- public void hideSplashScreen() {
- if (splashScreen != null) {
- splashScreen.hide(outerFrame);
- splashScreen = null;
- }
- View view = mainView.getView();
- view.setVisibility(View.VISIBLE);
- view.requestFocus();
- }
-
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Here Log should be used, not Logger. It is because Logger is not initialized yet.
Log.v(TAG, "+++ onCreate");
- Thread ct = Thread.currentThread();
- ct.setPriority(Thread.MAX_PRIORITY);
- uiThreadId = ct.getId();
-
- RhodesInstance.setInstance(this);
-
- initClassLoader(this.getClassLoader());
+ instance = this;
- initRootPath();
- try {
- copyFromBundle("apps/rhoconfig.txt");
- } catch (IOException e1) {
- Logger.E("Rhodes", e1);
- finish();
- return;
- }
- createRhodesApp(getRootPath(), getSqliteJournalsPath());
+ FrameLayout v = new FrameLayout(this);
- boolean fullScreen = true;
- if (RhoConf.isExist("full_screen"))
- fullScreen = RhoConf.getBool("full_screen");
- if (!fullScreen) {
- WINDOW_FLAGS = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
- WINDOW_MASK = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
+ RhodesService service = RhodesService.getInstance();
+ if (service == null) {
+ Log.v(TAG, "Starting rhodes service...");
+ service = new RhodesService(this, v);
}
- getWindow().setFlags(WINDOW_FLAGS, WINDOW_MASK);
+ else
+ Log.v(TAG, "Rhodes service already started...");
+
+ Thread ct = Thread.currentThread();
+ ct.setPriority(Thread.MAX_PRIORITY);
+ service.setInfo(this, ct.getId(), new Handler());
+ getWindow().setFlags(RhodesService.WINDOW_FLAGS, RhodesService.WINDOW_MASK);
+
boolean disableScreenRotation = RhoConf.getBool("disable_screen_rotation");
this.setRequestedOrientation(disableScreenRotation ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT :
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- ENABLE_LOADING_INDICATION = !RhoConf.getBool("disable_loading_indication");
- if (ENABLE_LOADING_INDICATION)
+ if (RhodesService.ENABLE_LOADING_INDICATION)
this.requestWindowFeature(Window.FEATURE_PROGRESS);
- outerFrame = new FrameLayout(this);
- this.setContentView(outerFrame, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
-
- Logger.I("Rhodes", "Loading...");
- showSplashScreen();
-
- // Increase WebView rendering priority
- WebView w = new WebView(this);
- WebSettings webSettings = w.getSettings();
- webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
-
- // Get screen width/height
- WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
- Display d = wm.getDefaultDisplay();
- screenHeight = d.getHeight();
- screenWidth = d.getWidth();
-
- DisplayMetrics metrics = new DisplayMetrics();
- d.getMetrics(metrics);
- screenPpiX = metrics.xdpi;
- screenPpiY = metrics.ydpi;
-
- // TODO: detect camera availability
- isCameraAvailable = true;
-
- // Register custom uri handlers here
- uriHandlers.addElement(new MailUriHandler(this));
- uriHandlers.addElement(new TelUriHandler(this));
- uriHandlers.addElement(new SmsUriHandler(this));
- uriHandlers.addElement(new VideoUriHandler(this));
-
- Thread init = new Thread(new Runnable() {
-
- public void run() {
- copyFilesFromBundle();
- startRhodesApp();
- }
-
- });
- init.start();
+ service.setRootWindow(v);
+ setContentView(v, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
@Override
- protected void onRestart() {
- super.onRestart();
- Logger.T(TAG, "+++ onRestart");
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- Logger.T(TAG, "+++ onStart");
- ownActivityActivated = false;
- if (needGeoLocationRestart) {
- GeoLocation.isKnownPosition();
- needGeoLocationRestart = false;
- }
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- Logger.T(TAG, "+++ onResume");
- }
-
- @Override
- protected void onPause() {
- Logger.T(TAG, "+++ onPause");
- super.onPause();
- }
-
- @Override
- protected void onStop() {
- Logger.T(TAG, "+++ onStop");
- needGeoLocationRestart = GeoLocation.isAvailable();
- GeoLocation.stop();
- if (!ownActivityActivated)
- stopSelf();
- super.onStop();
- }
-
- @Override
- protected void onDestroy() {
- Logger.T(TAG, "+++ onDestroy");
- stopSelf();
-
- super.onDestroy();
- }
-
- @Override
public void onConfigurationChanged(Configuration newConfig) {
Logger.T(TAG, "+++ onConfigurationChanged");
super.onConfigurationChanged(newConfig);
+ RhodesService.getInstance().rereadScreenProperties();
}
-
+
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
- mainView.back(mainView.activeTab());
+ RhodesService r = RhodesService.getInstance();
+ MainView v = r.getMainView();
+ v.back(v.activeTab());
return true;
- case KeyEvent.KEYCODE_HOME:
- stopSelf();
- return true;
}
return super.onKeyDown(keyCode, event);
}
@@ -642,143 +113,9 @@
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (appMenu == null)
return false;
return appMenu.onMenuItemSelected(item);
- }
-
- public static void showAboutDialog() {
- performOnUiThread(new Runnable() {
- public void run() {
- final AboutDialog aboutDialog = new AboutDialog(RhodesInstance.getInstance());
- aboutDialog.setTitle("About");
- aboutDialog.setCanceledOnTouchOutside(true);
- aboutDialog.setCancelable(true);
- aboutDialog.show();
- }
- }, false);
- }
-
- public static void showLogView() {
- performOnUiThread(new Runnable() {
- public void run() {
- final LogViewDialog logViewDialog = new LogViewDialog(RhodesInstance.getInstance());
- logViewDialog.setTitle("Log View");
- logViewDialog.setCancelable(true);
- logViewDialog.show();
- }
- }, false);
- }
-
- public static void showLogOptions() {
- performOnUiThread(new Runnable() {
- public void run() {
- final LogOptionsDialog logOptionsDialog = new LogOptionsDialog(RhodesInstance.getInstance());
- logOptionsDialog.setTitle("Logging Options");
- logOptionsDialog.setCancelable(true);
- logOptionsDialog.show();
- }
- }, false);
- }
-
- // Called from native code
- public static void deleteFilesInFolder(String folder) {
- String[] children = new File(folder).list();
- for (int i = 0; i != children.length; ++i)
- Utils.deleteRecursively(new File(folder, children[i]));
- }
-
- private static boolean hasNetwork() {
- if (!Capabilities.NETWORK_STATE_ENABLED) {
- Logger.E(TAG, "Capability NETWORK_STATE disabled");
- return false;
- }
-
- Context ctx = RhodesInstance.getInstance();
- ConnectivityManager conn = (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
- if (conn == null)
- return false;
-
- NetworkInfo[] info = conn.getAllNetworkInfo();
- if (info == null)
- return false;
-
- for (int i = 0, lim = info.length; i < lim; ++i) {
- if (info[i].getState() == NetworkInfo.State.CONNECTED)
- return true;
- }
-
- return false;
- }
-
- private static String getCurrentLocale() {
- String locale = Locale.getDefault().getLanguage();
- if (locale.length() == 0)
- locale = "en";
- return locale;
- }
-
- private static String getCurrentCountry() {
- String cl = Locale.getDefault().getCountry();
- return cl;
- }
-
- public static int getScreenWidth() {
- return screenWidth;
- }
-
- public static int getScreenHeight() {
- return screenHeight;
- }
-
- public static Object getProperty(String name) {
- if (name.equalsIgnoreCase("platform"))
- return "ANDROID";
- else if (name.equalsIgnoreCase("locale"))
- return getCurrentLocale();
- else if (name.equalsIgnoreCase("country"))
- return getCurrentCountry();
- else if (name.equalsIgnoreCase("screen_width"))
- return new Integer(getScreenWidth());
- else if (name.equalsIgnoreCase("screen_height"))
- return new Integer(getScreenHeight());
- else if (name.equalsIgnoreCase("has_camera"))
- return new Boolean(isCameraAvailable);
- else if (name.equalsIgnoreCase("has_network"))
- return hasNetwork();
- else if (name.equalsIgnoreCase("ppi_x"))
- return new Float(screenPpiX);
- else if (name.equalsIgnoreCase("ppi_y"))
- return new Float(screenPpiY);
- else if (name.equalsIgnoreCase("phone_number")) {
- TelephonyManager manager = (TelephonyManager)RhodesInstance.getInstance().
- getSystemService(Context.TELEPHONY_SERVICE);
- String number = manager.getLine1Number();
- return number;
- }
- else if (name.equalsIgnoreCase("device_name")) {
- return Build.DEVICE;
- }
- else if (name.equalsIgnoreCase("os_version")) {
- return Build.VERSION.RELEASE;
- }
-
- return null;
- }
-
- public static void exit() {
- RhodesInstance.getInstance().stopSelf();
- }
-
- private void stopSelf() {
- //stopRhodesApp();
- Process.killProcess(Process.myPid());
- }
-
- @Override
- public void startActivity(Intent intent) {
- ownActivityActivated = true;
- super.startActivity(intent);
}
static {
NativeLibraries.load();
}