public void abort() { if (readyState > READY_STATE_UNSENT && readyState < READY_STATE_DONE) { if (client != null) { if (DBG) { Log.d(LCAT, "Calling shutdown on clientConnectionManager"); } aborted = true; if (handler != null) { handler.client = null; if (handler.is != null) { try { if (handler.entity.isStreaming()) { handler.entity.consumeContent(); } handler.is.close(); } catch (IOException e) { Log.i(LCAT, "Force closing HTTP content input stream", e); } finally { handler.is = null; } } } if (client != null) { client.getConnectionManager().shutdown(); client = null; } } } }
public void removeEventListener(String eventName, int listenerId) { if (eventName != null) { HashMap<Integer, KrollListener> listeners = eventListeners.get(eventName); if (listeners != null) { KrollListener listener = listeners.get(listenerId); if (listeners.remove(listenerId) == null) { if (DBG) { Log.w(TAG, "listenerId " + listenerId + " not for eventName '" + eventName + "'"); } } else { dispatchOnEventChange(false, eventName, listeners.size(), listener.weakProxy.get()); if (DBG) { Log.i( TAG, "listener with id " + listenerId + " with eventName '" + eventName + "' was removed."); } } } } else { throw new IllegalStateException("removeEventListener expects a non-null eventName"); } }
public void sendError(String error) { Log.i(LCAT, "Sending error " + error); TiDict event = new TiDict(); event.put("error", error); event.put("source", proxy); fireCallback(ON_ERROR, new Object[] {event}); }
@Override public boolean shouldOverrideUrlLoading(final WebView view, String url) { if (DBG) { Log.d(LCAT, "url=" + url); } if (URLUtil.isAssetUrl(url) || URLUtil.isContentUrl(url) || URLUtil.isFileUrl(url)) { // go through the proxy to ensure we're on the UI thread webView.getProxy().setProperty("url", url, true); return true; } else if (url.startsWith(WebView.SCHEME_TEL)) { Log.i(LCAT, "Launching dialer for " + url); Intent dialer = Intent.createChooser(new Intent(Intent.ACTION_DIAL, Uri.parse(url)), "Choose Dialer"); webView.getProxy().getTiContext().getActivity().startActivity(dialer); return true; } else if (url.startsWith(WebView.SCHEME_MAILTO)) { Log.i(LCAT, "Launching mailer for " + url); Intent mailer = Intent.createChooser(new Intent(Intent.ACTION_SENDTO, Uri.parse(url)), "Send Message"); webView.getProxy().getTiContext().getActivity().startActivity(mailer); return true; } else if (url.startsWith(WebView.SCHEME_GEO)) { Log.i(LCAT, "Launching app for " + url); /*geo:latitude,longitude geo:latitude,longitude?z=zoom geo:0,0?q=my+street+address geo:0,0?q=business+near+city */ Intent geoviewer = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse(url)), "Choose Viewer"); webView.getProxy().getTiContext().getActivity().startActivity(geoviewer); return true; } else { String extension = MimeTypeMap.getFileExtensionFromUrl(url); String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); if (mimeType != null) { return shouldHandleMimeType(mimeType, url); } if (DBG) { Log.e(LCAT, "NEED to Handle " + url); } return super.shouldOverrideUrlLoading(view, url); } }
@Override protected void handleOpen(TiDict options) { if (DBG) { Log.i(LCAT, "handleOpen"); } Messenger messenger = new Messenger(getUIHandler()); view = new TiUIWindow(this, options, messenger, MSG_FINISH_OPEN); }
public TiApplication() { Log.checkpoint(LCAT, "checkpoint, app created."); _instance = this; needsEnrollEvent = false; // test is after DB is available needsStartEvent = true; loadBuildProperties(); Log.i(LCAT, "Titanium " + buildVersion + " (" + buildTimestamp + " " + buildHash + ")"); }
public synchronized void postAnalyticsEvent(TiAnalyticsEvent event) { if (!collectAnalytics()) { if (DBG) { Log.i(LCAT, "Analytics are disabled, ignoring postAnalyticsEvent"); } return; } if (DBG) { StringBuilder sb = new StringBuilder(); sb.append("Analytics Event: type=") .append(event.getEventType()) .append("\n event=") .append(event.getEventEvent()) .append("\n timestamp=") .append(event.getEventTimestamp()) .append("\n mid=") .append(event.getEventMid()) .append("\n sid=") .append(event.getEventSid()) .append("\n aguid=") .append(event.getEventAppGuid()) .append("\n isJSON=") .append(event.mustExpandPayload()) .append("\n payload=") .append(event.getEventPayload()); Log.d(LCAT, sb.toString()); } if (event.getEventType() == TiAnalyticsEventFactory.EVENT_APP_ENROLL) { if (needsEnrollEvent) { analyticsModel.addEvent(event); needsEnrollEvent = false; sendAnalytics(); analyticsModel.markEnrolled(); } } else if (event.getEventType() == TiAnalyticsEventFactory.EVENT_APP_START) { if (needsStartEvent) { analyticsModel.addEvent(event); needsStartEvent = false; sendAnalytics(); lastAnalyticsTriggered = System.currentTimeMillis(); } return; } else if (event.getEventType() == TiAnalyticsEventFactory.EVENT_APP_END) { needsStartEvent = true; analyticsModel.addEvent(event); sendAnalytics(); } else { analyticsModel.addEvent(event); long now = System.currentTimeMillis(); if (now - lastAnalyticsTriggered >= STATS_WAIT) { sendAnalytics(); lastAnalyticsTriggered = now; } } }
protected TiDict eventToTiDict(SensorEvent event, long ts) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; TiDict heading = new TiDict(); heading.put("type", EVENT_HEADING); heading.put("timestamp", ts); heading.put("x", x); heading.put("y", y); heading.put("z", z); heading.put("magneticHeading", x); heading.put("accuracy", event.accuracy); if (DBG) { switch (event.accuracy) { case SensorManager.SENSOR_STATUS_UNRELIABLE: Log.i(LCAT, "Compass accuracy unreliable"); break; case SensorManager.SENSOR_STATUS_ACCURACY_LOW: Log.i(LCAT, "Compass accuracy low"); break; case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM: Log.i(LCAT, "Compass accuracy medium"); break; case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: Log.i(LCAT, "Compass accuracy high"); break; default: Log.w(LCAT, "Unknown compass accuracy value: " + event.accuracy); } } if (geomagneticField != null) { float trueHeading = x - geomagneticField.getDeclination(); if (trueHeading < 0) { trueHeading = 360 - trueHeading; } heading.put("trueHeading", trueHeading); } TiDict data = new TiDict(); data.put("heading", heading); return data; }
public void sendError(final String error, final String syncId) { Log.i(LCAT, "Sending error " + error); final TitaniumWebView webView = softWebView.get(); if (webView != null) { final String cb = onErrorCallback; if (cb != null) { webView.evalJS(cb, "\"" + error + "\"", syncId); } } }
@Override public void onPause(Activity activity) { super.onPause(activity); if (batteryStateReceiver != null) { if (DBG) { Log.i(LCAT, "Unregistering battery changed receiver."); } getTiContext().getActivity().unregisterReceiver(batteryStateReceiver); } }
@Override public void onResume(Activity activity) { super.onResume(activity); if (batteryStateReceiver != null) { if (DBG) { Log.i(LCAT, "Reregistering battery changed receiver"); } registerBatteryReceiver(batteryStateReceiver); } }
public void run() { repeatIndex = 0; animating.set(true); firedLoad = false; topLoop: while (isRepeating()) { long time = System.currentTimeMillis(); for (int j = getStart(); isNotFinalFrame(j); j += getCounter()) { if (bitmapQueue.size() == 5 && !firedLoad) { fireLoad("images"); firedLoad = true; } if (paused && !Thread.currentThread().isInterrupted()) { try { Log.i(LCAT, "Pausing"); synchronized (loader) { loader.wait(); } Log.i(LCAT, "Waking from pause."); } catch (InterruptedException e) { Log.w(LCAT, "Interrupted from paused state."); } } if (!animating.get()) { break topLoop; } Object image = images[j]; Bitmap b = createBitmap(image); try { bitmapQueue.put(new BitmapWithIndex(b, j)); } catch (InterruptedException e) { e.printStackTrace(); } repeatIndex++; } if (DBG) { Log.d(LCAT, "TIME TO LOAD FRAMES: " + (System.currentTimeMillis() - time) + "ms"); } } animating.set(false); }
@Override protected void handleClose(TiDict options) { if (DBG) { Log.i(LCAT, "handleClose"); } fireEvent("close", null); if (view != null) { ((TiUIWindow) view).close(); } opened = false; }
public void setRootActivity(TiRootActivity rootActivity) { // TODO consider weakRef this.rootActivity = rootActivity; this.windowHandler = rootActivity; // calculate the display density DisplayMetrics dm = new DisplayMetrics(); rootActivity.getWindowManager().getDefaultDisplay().getMetrics(dm); switch (dm.densityDpi) { case DisplayMetrics.DENSITY_HIGH: { density = "high"; break; } case DisplayMetrics.DENSITY_MEDIUM: { density = "medium"; break; } case DisplayMetrics.DENSITY_LOW: { density = "low"; break; } } if (collectAnalytics()) { analyticsIntent = new Intent(this, TiAnalyticsService.class); analyticsModel = new TiAnalyticsModel(this); needsEnrollEvent = analyticsModel.needsEnrollEvent(); if (needsEnrollEvent()) { String deployType = systemProperties.getString("ti.deploytype", "unknown"); postAnalyticsEvent(TiAnalyticsEventFactory.createAppEnrollEvent(this, deployType)); } if (needsStartEvent()) { String deployType = systemProperties.getString("ti.deploytype", "unknown"); postAnalyticsEvent(TiAnalyticsEventFactory.createAppStartEvent(this, deployType)); } } else { needsEnrollEvent = false; needsStartEvent = false; Log.i(LCAT, "Analytics have been disabled"); } }
public void handleKeyboardType(int type, boolean autocorrect) { // Switched the keyboard handler to use the inputType rather than the rawInputType // This is kinda brute-force but more effective for most use-cases switch (type) { case KEYBOARD_ASCII: tv.setKeyListener(TextKeyListener.getInstance(autocorrect, Capitalize.NONE)); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); // tv.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); break; case KEYBOARD_NUMBERS_PUNCTUATION: tv.setInputType(InputType.TYPE_CLASS_NUMBER); // tv.setKeyListener(DigitsKeyListener.getInstance()); break; case KEYBOARD_URL: Log.i(LCAT, "Setting keyboard type URL-3"); // tv.setKeyListener(TextKeyListener.getInstance(autocorrect, Capitalize.NONE)); tv.setImeOptions(EditorInfo.IME_ACTION_GO); // tv.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI); break; case KEYBOARD_NUMBER_PAD: tv.setKeyListener(DigitsKeyListener.getInstance(true, true)); // tv.setRawInputType(InputType.TYPE_CLASS_NUMBER); tv.setInputType(InputType.TYPE_CLASS_NUMBER); break; case KEYBOARD_PHONE_PAD: tv.setKeyListener(DialerKeyListener.getInstance()); // tv.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_CLASS_PHONE); tv.setInputType(InputType.TYPE_CLASS_PHONE); break; case KEYBOARD_EMAIL_ADDRESS: // tv.setKeyListener(TextKeyListener.getInstance(autocorrect, Capitalize.NONE)); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); break; case KEYBOARD_DEFAULT: tv.setKeyListener(TextKeyListener.getInstance(autocorrect, Capitalize.NONE)); // tv.setRawInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); break; case KEYBOARD_PASSWORD: tv.setKeyListener(TextKeyListener.getInstance(false, Capitalize.NONE)); // tv.setRawInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); break; } }
public void open(String method, String url) { if (DBG) { Log.d(LCAT, "open request method=" + method + " url=" + url); } this.method = method; String cleanUrl = url; if (url.startsWith("http")) { int beginQ = url.indexOf('?'); if (beginQ > 7 && url.length() > beginQ) { String left = url.substring(0, beginQ); String right = url.substring(beginQ + 1); // first decoding below, in case it's partially encoded already. cleanUrl = Uri.encode(Uri.decode(left), ":/") + "?" + Uri.encode(Uri.decode(right), "&=#"); } else { cleanUrl = Uri.encode(Uri.decode(url), ":/#"); } } uri = Uri.parse(cleanUrl); host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme()); if (uri.getUserInfo() != null) { credentials = new UsernamePasswordCredentials(uri.getUserInfo()); } setReadyState(READY_STATE_OPENED); setRequestHeader("User-Agent", (String) proxy.getDynamicValue("userAgent")); // Causes Auth to Fail with twitter and other size apparently block X- as well // Ticket #729, ignore twitter for now if (!uri.getHost().contains("twitter.com")) { setRequestHeader("X-Requested-With", "XMLHttpRequest"); } else { Log.i(LCAT, "Twitter: not sending X-Requested-With header"); } }
protected Object toNative(Object value, Class<?> target) { Object o = null; if (value instanceof String) { o = Context.jsToJava(value, target); } else if (value instanceof Double || value instanceof Integer) { o = Context.jsToJava(value, target); } else if (value instanceof Boolean) { o = Context.jsToJava(value, target); } else if (value instanceof Function) { if (DBG) { Log.i(LCAT, "Is a Function"); } o = new KrollCallback(weakKrollContext.get(), this, (Function) value); } else if (value == null) { o = null; } else if (value instanceof Scriptable) { Scriptable svalue = (Scriptable) value; if (isArrayLike(svalue)) { o = toArray(svalue); } else if (value instanceof KrollObject) { o = ((KrollObject) value).target; } else if (svalue.getClassName().equals("Date")) { double time = (Double) ScriptableObject.callMethod(svalue, "getTime", new Object[0]); o = new Date((long) time); } else { TiDict args = new TiDict(); o = args; Scriptable so = (Scriptable) value; for (Object key : so.getIds()) { Object v = so.get((String) key, so); v = toNative(v, Object.class); // if (v instanceof Scriptable && isArrayLike((Scriptable) v)) { // v = toArray((Scriptable) v); // } if (DBG) { Log.i(LCAT, "Key: " + key + " value: " + v + " type: " + v.getClass().getName()); } args.put((String) key, v); } // Log.w(LCAT, "Unhandled type conversion of Scriptable: value: " + value.toString() + " // type: " + value.getClass().getName()); } } else { if (value.getClass().isArray()) { Object[] values = (Object[]) value; Object[] newValues = new Object[values.length]; for (int i = 0; i < values.length; i++) { newValues[i] = toNative(values[i], Object.class); } o = newValues; } else { Log.w( LCAT, "Unhandled type conversion: value: " + value.toString() + " type: " + value.getClass().getName()); } } return o; }
public void propertyChanged(String key, Object oldValue, Object newValue, KrollProxy proxy) { if (key.equals(TiC.PROPERTY_LEFT)) { if (newValue != null) { layoutParams.optionLeft = TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_LEFT); } else { layoutParams.optionLeft = null; } layoutNativeView(); } else if (key.equals(TiC.PROPERTY_TOP)) { if (newValue != null) { layoutParams.optionTop = TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_TOP); } else { layoutParams.optionTop = null; } layoutNativeView(); } else if (key.equals(TiC.PROPERTY_CENTER)) { TiConvert.updateLayoutCenter(newValue, layoutParams); layoutNativeView(); } else if (key.equals(TiC.PROPERTY_RIGHT)) { if (newValue != null) { layoutParams.optionRight = TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_RIGHT); } else { layoutParams.optionRight = null; } layoutNativeView(); } else if (key.equals(TiC.PROPERTY_BOTTOM)) { if (newValue != null) { layoutParams.optionBottom = TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_BOTTOM); } else { layoutParams.optionBottom = null; } layoutNativeView(); } else if (key.equals(TiC.PROPERTY_SIZE)) { if (newValue instanceof KrollDict) { KrollDict d = (KrollDict) newValue; propertyChanged(TiC.PROPERTY_WIDTH, oldValue, d.get(TiC.PROPERTY_WIDTH), proxy); propertyChanged(TiC.PROPERTY_HEIGHT, oldValue, d.get(TiC.PROPERTY_HEIGHT), proxy); } else if (newValue != null) { Log.w( LCAT, "Unsupported property type (" + (newValue.getClass().getSimpleName()) + ") for key: " + key + ". Must be an object/dictionary"); } } else if (key.equals(TiC.PROPERTY_HEIGHT)) { if (newValue != null) { if (!newValue.equals(TiC.SIZE_AUTO)) { layoutParams.optionHeight = TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_HEIGHT); layoutParams.autoHeight = false; } else { layoutParams.optionHeight = null; layoutParams.autoHeight = true; } } else { layoutParams.optionHeight = null; } layoutNativeView(); } else if (key.equals(TiC.PROPERTY_WIDTH)) { if (newValue != null) { if (!newValue.equals(TiC.SIZE_AUTO)) { layoutParams.optionWidth = TiConvert.toTiDimension(TiConvert.toString(newValue), TiDimension.TYPE_WIDTH); layoutParams.autoWidth = false; } else { layoutParams.optionWidth = null; layoutParams.autoWidth = true; } } else { layoutParams.optionWidth = null; } layoutNativeView(); } else if (key.equals(TiC.PROPERTY_ZINDEX)) { if (newValue != null) { layoutParams.optionZIndex = TiConvert.toInt(newValue); } else { layoutParams.optionZIndex = 0; } layoutNativeView(true); } else if (key.equals(TiC.PROPERTY_FOCUSABLE)) { boolean focusable = TiConvert.toBoolean(proxy.getProperty(TiC.PROPERTY_FOCUSABLE)); nativeView.setFocusable(focusable); if (focusable) { registerForKeyClick(nativeView); } else { // nativeView.setOnClickListener(null); // ? mistake? I assume OnKeyListener was meant nativeView.setOnKeyListener(null); } } else if (key.equals(TiC.PROPERTY_TOUCH_ENABLED)) { doSetClickable(TiConvert.toBoolean(newValue)); } else if (key.equals(TiC.PROPERTY_VISIBLE)) { nativeView.setVisibility(TiConvert.toBoolean(newValue) ? View.VISIBLE : View.INVISIBLE); } else if (key.equals(TiC.PROPERTY_ENABLED)) { nativeView.setEnabled(TiConvert.toBoolean(newValue)); } else if (key.startsWith(TiC.PROPERTY_BACKGROUND_PADDING)) { Log.i(LCAT, key + " not yet implemented."); } else if (key.equals(TiC.PROPERTY_OPACITY) || key.startsWith(TiC.PROPERTY_BACKGROUND_PREFIX) || key.startsWith(TiC.PROPERTY_BORDER_PREFIX)) { // Update first before querying. proxy.setProperty(key, newValue, false); KrollDict d = proxy.getProperties(); boolean hasImage = hasImage(d); boolean hasColorState = hasColorState(d); boolean hasBorder = hasBorder(d); boolean requiresCustomBackground = hasImage || hasColorState || hasBorder; if (!requiresCustomBackground) { if (background != null) { background.releaseDelegate(); background.setCallback(null); background = null; } if (d.containsKeyAndNotNull(TiC.PROPERTY_BACKGROUND_COLOR)) { Integer bgColor = TiConvert.toColor(d, TiC.PROPERTY_BACKGROUND_COLOR); if (nativeView != null) { nativeView.setBackgroundColor(bgColor); nativeView.postInvalidate(); } } else { if (key.equals(TiC.PROPERTY_OPACITY)) { setOpacity(TiConvert.toFloat(newValue)); } if (nativeView != null) { nativeView.setBackgroundDrawable(null); nativeView.postInvalidate(); } } } else { boolean newBackground = background == null; if (newBackground) { background = new TiBackgroundDrawable(); } Integer bgColor = null; if (!hasColorState) { if (d.get(TiC.PROPERTY_BACKGROUND_COLOR) != null) { bgColor = TiConvert.toColor(d, TiC.PROPERTY_BACKGROUND_COLOR); if (newBackground || (key.equals(TiC.PROPERTY_OPACITY) || key.equals(TiC.PROPERTY_BACKGROUND_COLOR))) { background.setBackgroundColor(bgColor); } } } if (hasImage || hasColorState) { if (newBackground || key.startsWith(TiC.PROPERTY_BACKGROUND_PREFIX)) { handleBackgroundImage(d); } } if (hasBorder) { if (newBackground) { initializeBorder(d, bgColor); } else if (key.startsWith(TiC.PROPERTY_BORDER_PREFIX)) { handleBorderProperty(key, newValue); } } applyCustomBackground(); } if (nativeView != null) { nativeView.postInvalidate(); } } else if (key.equals(TiC.PROPERTY_SOFT_KEYBOARD_ON_FOCUS)) { Log.w( LCAT, "Focus state changed to " + TiConvert.toString(newValue) + " not honored until next focus event."); } else if (key.equals(TiC.PROPERTY_TRANSFORM)) { if (nativeView != null) { applyTransform((Ti2DMatrix) newValue); } } else if (key.equals(TiC.PROPERTY_KEEP_SCREEN_ON)) { if (nativeView != null) { nativeView.setKeepScreenOn(TiConvert.toBoolean(newValue)); } } else { TiViewProxy viewProxy = getProxy(); if (viewProxy != null && viewProxy.isLocalizedTextId(key)) { viewProxy.setLocalizedText(key, TiConvert.toString(newValue)); } else { if (DBG) { Log.d(LCAT, "Unhandled property key: " + key); } } } }