private static Certificate loadCertificate(File f) { X509Certificate cert = null; Logger.I(TAG, "Loading SSL certificate from PEM file: " + f.getAbsolutePath()); try { byte[] fileBuf = fileToBytes(f); byte[] certBytes = parseDERFromPEM(fileBuf, "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----"); cert = generateCertificateFromDER(certBytes); Logger.I(TAG, "SSL certificate loaded successfully"); } catch (IOException e) { Logger.E( TAG, "Reading certificate file failed: " + e.getClass().getSimpleName() + ": " + e.getMessage()); } catch (CertificateException e) { Logger.E( TAG, "Certificate generation failed: " + e.getClass().getSimpleName() + ": " + e.getMessage()); } return cert; }
@Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { if (RhoConf.getBool("no_ssl_verify_peer")) { Logger.D(TAG, "Skip SSL error."); handler.proceed(); } else { StringBuilder msg = new StringBuilder(); msg.append("SSL error - "); switch (error.getPrimaryError()) { case SslError.SSL_NOTYETVALID: msg.append("The certificate is not yet valid: "); break; case SslError.SSL_EXPIRED: msg.append("The certificate has expired: "); break; case SslError.SSL_IDMISMATCH: msg.append("Hostname mismatch: "); break; case SslError.SSL_UNTRUSTED: msg.append("The certificate authority is not trusted: "); break; } msg.append(error.getCertificate().toString()); Logger.W(TAG, msg.toString()); handler.cancel(); } }
@Override public void send(Map<String, Object> params, final IMethodResult result) { Intent intent = makeIntent(params); Object type = params.get(HK_INTENT_TYPE); if (BROADCAST.equals(type)) { Object permissionObj = params.get(HK_PERMISSION); String permission = null; if (permissionObj != null) { if (String.class.isInstance(permissionObj)) { permission = (String) permissionObj; } else { result.setArgError("Wrong intent permission: " + permissionObj); return; } } Logger.T(TAG, "Send broadcast: " + intent); ContextFactory.getAppContext().sendBroadcast(intent, permission); } else if (START_ACTIVITY.equals(type)) { if (result.hasCallback()) { int request; synchronized (localMethodResults) { request = RhoExtManager.getInstance().getActivityResultNextRequestCode(this); final Integer finalKey = Integer.valueOf(request); Map.Entry<Integer, IMethodResult> entry = new Map.Entry<Integer, IMethodResult>() { Integer key = finalKey; IMethodResult value = result; @Override public Integer getKey() { return key; } @Override public IMethodResult getValue() { return value; } @Override public IMethodResult setValue(IMethodResult v) { return result; } }; localMethodResults.add(entry); } RhodesActivity.safeGetInstance().startActivityForResult(intent, request); Logger.T(TAG, "Start activity for result: " + intent); } else { Logger.T(TAG, "Start activity: " + intent); ContextFactory.getUiContext().startActivity(intent); } } else if (START_SERVICE.equals(type)) { Logger.T(TAG, "Start service: " + intent); ContextFactory.getContext().startService(intent); } else { result.setArgError("Wrong intent type: " + type); } }
public static void onGeoCallback() { Logger.T(TAG, "onGeoCallback()"); if (ourIsEnable && !ourIsErrorState) { Logger.T(TAG, "onGeoCallback() run native Callback"); geoCallback(); } else { Logger.T(TAG, "onGeoCallback() SKIP"); } }
public static void onGeoCallbackError() { if (ourIsEnable && !ourIsErrorState) { Logger.T(TAG, "onGeoCallbackError() run native Callback"); ourIsErrorState = true; geoCallbackError(); ourIsErrorState = false; } else { Logger.T(TAG, "onGeoCallbackError() SKIP"); } }
public static boolean isKnownPosition() { onUpdateLocation(); try { checkState(); Logger.T(TAG, "isKnownPosition"); return ourIsKnownPosition; } catch (Exception e) { Logger.E(TAG, e); } return false; }
public static float getAccuracy() { onUpdateLocation(); try { checkState(); Logger.T(TAG, "getAccuracy"); return (float) ourAccuracy; } catch (Exception e) { Logger.E(TAG, e); } return 0; }
public static double getAltitude() { onUpdateLocation(); try { checkState(); Logger.T(TAG, "getAltitude"); return ourAltitude; } catch (Exception e) { Logger.E(TAG, e); } return 0.0; }
public static int getSatellities() { onUpdateLocation(); try { checkState(); Logger.T(TAG, "getSpeed"); return ourSatellities; } catch (Exception e) { Logger.E(TAG, e); } return 0; }
public static double getSpeed() { onUpdateLocation(); try { checkState(); Logger.T(TAG, "getSpeed"); return ourSpeed; } catch (Exception e) { Logger.E(TAG, e); } return 0.0; }
public static FileDescriptor openFd(String path) { forceFile(path); try { Logger.D(TAG, "Opening file from file system: " + absolutePath(path)); FileInputStream fs = new FileInputStream(absolutePath(path)); return fs.getFD(); } catch (Exception e) { Logger.E(TAG, "Can not open file descriptor: " + e.getMessage()); return null; } }
public static ParcelFileDescriptor openParcelFd(String path) { forceFile(path); try { Logger.D(TAG, "Opening file from file system: " + absolutePath(path)); File file = new File(path); return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); } catch (FileNotFoundException e) { Logger.E(TAG, "Can not open ParcelFileDescriptor" + e.getMessage()); return null; } }
@SuppressWarnings("deprecation") @SuppressLint("NewApi") @Override public ISize setPreviewSize(int width, int height) { Camera camera = getCamera(); Camera.Parameters parameters = camera.getParameters(); List<android.hardware.Camera.Size> sizes = camera.getParameters().getSupportedPictureSizes(); android.hardware.Camera.Size maxSize = sizes.get(0); if (getActualPropertyMap().containsKey("desiredWidth") || getActualPropertyMap().containsKey("desiredHeight")) { int desired_width = Integer.parseInt(getActualPropertyMap().get("desiredWidth")); int desired_height = Integer.parseInt(getActualPropertyMap().get("desiredHeight")); if (desired_width > 0 && desired_width <= maxSize.width && desired_height > 0 && desired_height <= maxSize.height) { Camera.Size previewSize = getOptimalPreviewSize( parameters.getSupportedPictureSizes(), desired_width, desired_height); Logger.T(TAG, "Selected size: " + previewSize.width + "x" + previewSize.height); parameters.setPreviewSize(previewSize.width, previewSize.height); } else if (desired_width > maxSize.width || desired_height > maxSize.height) { final Camera.Parameters newParam = parameters; final android.hardware.Camera.Size newMaxSize = sizes.get(0); RhodesActivity.safeGetInstance() .runOnUiThread( new Runnable() { @Override public void run() { // TODO Auto-generated method stub newParam.setPreviewSize(newMaxSize.width, newMaxSize.height); } }); } else { parameters.setPreviewSize(320, 240); } } else { Camera.Size previewSize = getOptimalPreviewSize(parameters.getSupportedPictureSizes(), width, height); Logger.T(TAG, "Selected size: " + previewSize.width + "x" + previewSize.height); parameters.setPreviewSize(previewSize.width, previewSize.height); } camera.stopPreview(); try { camera.setParameters(parameters); } catch (RuntimeException e) { e.printStackTrace(); } camera.startPreview(); return new CameraSize(camera.getParameters().getPreviewSize()); }
private static void resetCallbackThread(int period) { Logger.T(TAG, "resetCallbackThread: " + period + "s"); if (ourCallbackThread != null) { ourCallbackThread.interrupt(); ourCallbackThread = null; } if (period > 0) { final int sleep_period = period; ourCallbackThread = new Thread( new Runnable() { private boolean ourLastCommandProcessed = true; public void run() { Logger.I(TAG, "\"callback\" thread started"); for (; ; ) { if (!ourIsEnable) { break; } try { if (ourLastCommandProcessed) { ourLastCommandProcessed = false; Logger.T(TAG, "callback thread: perform callback in UI thread"); PerformOnUiThread.exec( new Runnable() { public void run() { Logger.T(TAG, "callback thread: callback in UI thread START"); onGeoCallback(); Logger.T(TAG, "callback thread: callback in UI thread FINISH"); ourLastCommandProcessed = true; } }); } else { Logger.T( TAG, "callback thread: previous command not processed - skip current callback"); } Thread.sleep(sleep_period); } catch (InterruptedException e) { Logger.T(TAG, "\"callback\" thread interrupted"); break; } } } }); ourCallbackThread.start(); } else { Logger.T(TAG, "resetCallbackThread: zero period - not make any thread"); } }
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.2; final double SCALE_TOLERANCE = 0.2; double targetRatio = (double) w / h; if (sizes == null) return null; Camera.Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; // Try to find an size match aspect ratio and size for (Camera.Size size : sizes) { Logger.T(TAG, "Size: " + size.width + "x" + size.height); double scale = (double) size.width / w; double ratio = (double) size.width / size.height; Logger.T(TAG, "Target ratio: " + targetRatio + ", ratio: " + ratio + ", scale: " + scale); if (size.width > w || size.height > h) continue; if (Math.abs(1 - scale) > SCALE_TOLERANCE) continue; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; Logger.T(TAG, "Try size: " + size.width + "x" + size.height); if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } // Cannot find the one match the aspect ratio, ignore the requirement if (optimalSize == null) { Logger.T(TAG, "There is no match for preview size!"); minDiff = Double.MAX_VALUE; for (Camera.Size size : sizes) { if (size.width > w || size.height > h) continue; Logger.T(TAG, "Try size: " + size.width + "x" + size.height); if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } if (optimalSize == null) return getCamera().getParameters().getPictureSize(); return optimalSize; }
private static GeoLocationImpl getImpl() { if (locImpl == null) { synchronized (GeoLocation.class) { if (locImpl == null) { Logger.T(TAG, "Creating GeoLocationImpl instance."); locImpl = new GeoLocationImpl(); Logger.T(TAG, "GeoLocationImpl instance has created."); // ourIsFirstUpdate = true; locImpl.start(); Logger.T(TAG, "GeoLocation has started."); } } } return locImpl; }
@Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); Logger.profStop("BROWSER_PAGE"); StringBuilder msg = new StringBuilder(failingUrl != null ? failingUrl : "null"); msg.append(" failed: "); msg.append(errorCode); msg.append(" - " + description); Logger.E(TAG, msg.toString()); RhoExtManager.getImplementationInstance() .onLoadError(view, IRhoExtension.LoadErrorReason.INTERNAL_ERROR); }
public static boolean isAvailable() { Logger.T(TAG, "isAvailable..."); try { boolean result = false; if (locImpl != null) { checkState(); result = getImpl().isAvailable(); } Logger.T(TAG, "Geo location service is " + (result ? "" : "not ") + "available"); return result; } catch (Exception e) { Logger.E(TAG, e); } return false; }
public static void stop() { Logger.T(TAG, "stop"); ourIsEnable = false; resetCallbackThread(0); try { if (locImpl == null) return; synchronized (GeoLocation.class) { if (locImpl == null) return; locImpl.stop(); locImpl = null; } } catch (Exception e) { Logger.E(TAG, e); } }
private void sendResult(String callback, Date result, byte[] opaque) { this.setFieldsEnabled(false); long res = result == null ? 0 : result.getTime() / 1000; Logger.D(TAG, "Return result: " + res); DateTimePicker.callback(callback, res, opaque, result == null); finish(); }
public boolean connect(int fd, boolean sslVerifyPeer, String hostname) { try { Logger.I(TAG, "SSL connect to " + hostname); RhoSockAddr remote = getRemoteSockAddr(fd); Socket s = new RhoSocket(fd, remote); SSLSocketFactory f = getFactory(sslVerifyPeer); StringTokenizer st = new StringTokenizer(hostname, ":"); String host = st.nextToken(); SSLSocket aSock = (SSLSocket) f.createSocket(s, host, remote.port, true); aSock.setUseClientMode(true); synchronized (this) { sock = aSock; os = sock.getOutputStream(); is = sock.getInputStream(); sockfd = fd; } return true; } catch (Exception e) { reportFail("connect", e); e.printStackTrace(); return false; } }
public static void setNotificationEx(Object options) { if ((options != null) && (options instanceof Map<?, ?>)) { Map<Object, Object> settings = (Map<Object, Object>) options; double minDistance = 10; int minTime = 1000; Object minDistObj = settings.get("minimumDistance"); Object minTimeObj = settings.get("minimumTimeInterval"); try { checkState(); } catch (Exception e) { Logger.E(TAG, e); } ourIsEnable = true; if ((minDistObj != null) && (minDistObj instanceof String)) { minDistance = Double.parseDouble(((String) minDistObj)); } if ((minTimeObj != null) && (minTimeObj instanceof String)) { minTime = Integer.parseInt(((String) minTimeObj)); } getImpl().restartEx(minDistance, minTime); } }
@Override public void setCompressionFormat(String compressionFormat, IMethodResult result) { if (!compressionFormat.equalsIgnoreCase("jpg")) { Logger.E(TAG, "Android does not support the compression format: " + compressionFormat); result.setError("Android does not support the compression format: " + compressionFormat); } }
public synchronized void onNewIntent(String type, Intent intent) { if (methodResult != null) { Logger.T(TAG, "New Intent: " + type); Map<String, Object> params = parseIntent(intent); params.put(HK_INTENT_TYPE, type); methodResult.set(params); } }
public void onTabChanged(String tabId) { try { int new_tabIndex = Integer.parseInt(tabId); onTabChangedIndex(new_tabIndex, false); } catch (NumberFormatException e) { Logger.E(TAG, e); } }
public void shutdown() { try { if (sock != null) sock.close(); } catch (IOException e) { Logger.I(TAG, "shutdown fails: IOException: " + e.getMessage()); } catch (Exception e) { reportFail("shutdown", e); } }
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Logger.I(TAG, "Loading URL: " + url); boolean res = RhodesService.getInstance().handleUrlLoading(url); if (!res) { Logger.profStart("BROWSER_PAGE"); RhoExtManager.getImplementationInstance().onBeforeNavigate(view, url); Uri localUri = LocalFileProvider.overrideUri(Uri.parse(url)); if (localUri != null) { url = Uri.decode(localUri.toString()); Logger.T(TAG, "Override URL: " + url); view.loadUrl(url); return true; } } return res; }
@Override public void startPreview(SurfaceHolder surfaceHolder) { try { openCamera(); getCamera().setPreviewDisplay(surfaceHolder); getCamera().startPreview(); } catch (Throwable e) { Logger.E(TAG, e); return; } }
public void run() { try { runnable.run(); } catch (Exception e) { Logger.E(TAG, "Operation failed: " + e.getMessage()); } finally { synchronized (runnable) { runnable.notify(); } } }
@SuppressLint("NewApi") @Override public void doTakePicture(Activity previewActivity, int rotation) { Logger.T(TAG, "doTakePicture: rotation: " + rotation); openCamera(); Camera.Parameters params = getCamera().getParameters(); params.setRotation((90 + rotation) % 360); getCamera().setParameters(params); getCamera().takePicture(null, null, new TakePictureCallback(previewActivity)); closeCamera(); }