private boolean processKeyDown(int keyCode, KeyEvent event, boolean isPreIme) {
    if (DEBUG) {
      Log.d(
          LOGTAG,
          "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ", " + isPreIme + ")");
    }

    clampSelection();

    switch (keyCode) {
      case KeyEvent.KEYCODE_MENU:
      case KeyEvent.KEYCODE_BACK:
      case KeyEvent.KEYCODE_VOLUME_UP:
      case KeyEvent.KEYCODE_VOLUME_DOWN:
      case KeyEvent.KEYCODE_SEARCH:
        return false;
      case KeyEvent.KEYCODE_DEL:
        // See comments in GeckoInputConnection.onKeyDel
        if (onKeyDel()) {
          return true;
        }
        break;
      case KeyEvent.KEYCODE_ENTER:
        if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0
            && mIMEActionHint.equalsIgnoreCase("next"))
          event = new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB);
        break;
      default:
        break;
    }

    if (isPreIme
        && mIMEState != IME_STATE_DISABLED
        && (event.getMetaState() & KeyEvent.META_ALT_ON) != 0)
      // Let active IME process pre-IME key events
      return false;

    View view = GeckoApp.mAppContext.getLayerController().getView();
    KeyListener keyListener = TextKeyListener.getInstance();

    // KeyListener returns true if it handled the event for us.
    if (mIMEState == IME_STATE_DISABLED
        || keyCode == KeyEvent.KEYCODE_ENTER
        || keyCode == KeyEvent.KEYCODE_DEL
        || keyCode == KeyEvent.KEYCODE_TAB
        || (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0
        || !keyListener.onKeyDown(view, mEditable, keyCode, event)) {
      // Make sure selection in Gecko is up-to-date
      final Editable content = getEditable();
      int a = Selection.getSelectionStart(content);
      int b = Selection.getSelectionEnd(content);
      GeckoAppShell.sendEventToGecko(
          GeckoEvent.createIMEEvent(GeckoEvent.IME_SET_SELECTION, a, b - a));

      GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event));
    }
    return true;
  }
  private boolean processKeyUp(int keyCode, KeyEvent event, boolean isPreIme) {
    if (DEBUG) {
      Log.d(
          LOGTAG,
          "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ", " + isPreIme + ")");
    }

    switch (keyCode) {
      case KeyEvent.KEYCODE_BACK:
      case KeyEvent.KEYCODE_SEARCH:
      case KeyEvent.KEYCODE_MENU:
        return false;
      default:
        break;
    }

    if (isPreIme
        && mIMEState != IME_STATE_DISABLED
        && (event.getMetaState() & KeyEvent.META_ALT_ON) != 0)
      // Let active IME process pre-IME key events
      return false;

    View view = GeckoApp.mAppContext.getLayerController().getView();
    KeyListener keyListener = TextKeyListener.getInstance();

    if (mIMEState == IME_STATE_DISABLED
        || keyCode == KeyEvent.KEYCODE_ENTER
        || keyCode == KeyEvent.KEYCODE_DEL
        || (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0
        || !keyListener.onKeyUp(view, mEditable, keyCode, event)) {
      GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event));
    }

    return true;
  }
Example #3
0
  /*
   * DoorHanger.OnButtonClickListener implementation
   */
  @Override
  public void onButtonClick(DoorHanger dh, String tag) {
    JSONObject response = new JSONObject();
    try {
      response.put("callback", tag);

      CheckBox checkBox = dh.getCheckBox();
      // If the checkbox is being used, pass its value
      if (checkBox != null) {
        response.put("checked", checkBox.isChecked());
      }

      List<PromptInput> doorHangerInputs = dh.getInputs();
      if (doorHangerInputs != null) {
        JSONObject inputs = new JSONObject();
        for (PromptInput input : doorHangerInputs) {
          inputs.put(input.getId(), input.getValue());
        }
        response.put("inputs", inputs);
      }
    } catch (JSONException e) {
      Log.e(LOGTAG, "Error creating onClick response", e);
    }

    GeckoEvent e = GeckoEvent.createBroadcastEvent("Doorhanger:Reply", response.toString());
    GeckoAppShell.sendEventToGecko(e);
    removeDoorHanger(dh);
    updatePopup();
  }
  @Override
  public boolean setSelection(int start, int end) {
    GeckoAppShell.sendEventToGecko(
        GeckoEvent.createIMEEvent(GeckoEvent.IME_SET_SELECTION, start, end - start));

    return super.setSelection(start, end);
  }
  /** Send current network state and connection type as a GeckoEvent, to whomever is listening. */
  private void sendNetworkStateToListeners() {
    final Context applicationContext = GeckoAppShell.getApplicationContext();
    final GeckoEvent networkEvent =
        GeckoEvent.createNetworkEvent(
            currentConnectionType.value,
            currentConnectionType == ConnectionType.WIFI,
            wifiDhcpGatewayAddress(applicationContext),
            currentConnectionSubtype.value);
    final GeckoEvent networkLinkChangeValueEvent =
        GeckoEvent.createNetworkLinkChangeEvent(currentNetworkStatus.value);
    final GeckoEvent networkLinkChangeNotificationEvent =
        GeckoEvent.createNetworkLinkChangeEvent(LINK_DATA_CHANGED);

    GeckoAppShell.sendEventToGecko(networkEvent);
    GeckoAppShell.sendEventToGecko(networkLinkChangeValueEvent);
    GeckoAppShell.sendEventToGecko(networkLinkChangeNotificationEvent);
  }
Example #6
0
 private void connectToGecko() {
   GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoRunning);
   Tab selectedTab = Tabs.getInstance().getSelectedTab();
   if (selectedTab != null)
     Tabs.getInstance().notifyListeners(selectedTab, Tabs.TabEvents.SELECTED);
   geckoConnected();
   GeckoAppShell.setLayerClient(getLayerClientObject());
   GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Viewport:Flush", null));
 }
Example #7
0
 @Override
 public void onClick(View v) {
   switch (v.getId()) {
     case R.id.find_prev:
       GeckoAppShell.sendEventToGecko(
           GeckoEvent.createBroadcastEvent("FindInPage:Prev", mFindText.getText().toString()));
       getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
       break;
     case R.id.find_next:
       GeckoAppShell.sendEventToGecko(
           GeckoEvent.createBroadcastEvent("FindInPage:Next", mFindText.getText().toString()));
       getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
       break;
     case R.id.find_close:
       hide();
       break;
   }
 }
Example #8
0
  @Override
  public void requestZoomedViewRender() {
    if (stopUpdateView) {
      return;
    }
    // remove pending runnable
    ThreadUtils.removeCallbacksFromUiThread(requestRenderRunnable);

    // "requestZoomedViewRender" can be called very often by Gecko (endDrawing in LayerRender)
    // without
    // any thing changed in the zoomed area (useless calls from the "zoomed area" point of view).
    // "requestZoomedViewRender" can take time to re-render the zoomed view, it depends of the
    // complexity
    // of the html on this area.
    // To avoid to slow down the application, the 2 following cases are tested:

    // 1- Last render is still running, plan another render later.
    if (isRendering()) {
      // post a new runnable DELAY_BEFORE_NEXT_RENDER_REQUEST_MS later
      // We need to post with a delay to be sure that the last call to requestZoomedViewRender will
      // be done.
      // For a static html page WITHOUT any animation/video, there is a last call to endDrawing and
      // we need to make
      // the zoomed render on this last call.
      ThreadUtils.postDelayedToUiThread(requestRenderRunnable, DELAY_BEFORE_NEXT_RENDER_REQUEST_MS);
      return;
    }

    // 2- Current render occurs too early, plan another render later.
    if (renderFrequencyTooHigh()) {
      // post a new runnable DELAY_BEFORE_NEXT_RENDER_REQUEST_MS later
      // We need to post with a delay to be sure that the last call to requestZoomedViewRender will
      // be done.
      // For a page WITH animation/video, the animation/video can be stopped, and we need to make
      // the zoomed render on this last call.
      ThreadUtils.postDelayedToUiThread(requestRenderRunnable, DELAY_BEFORE_NEXT_RENDER_REQUEST_MS);
      return;
    }

    startTimeReRender = System.nanoTime();
    // Allocate the buffer if it's the first call.
    // Change the buffer size if it's not the right size.
    updateBufferSize();

    int tabId = Tabs.getInstance().getSelectedTab().getId();

    ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
    PointF origin = metrics.getOrigin();

    final int xPos = (int) origin.x + lastPosition.x;
    final int yPos = (int) origin.y + lastPosition.y;

    GeckoEvent e =
        GeckoEvent.createZoomedViewEvent(
            tabId, xPos, yPos, viewWidth, viewHeight, zoomFactor * metrics.zoomFactor, buffer);
    GeckoAppShell.sendEventToGecko(e);
  }
Example #9
0
  public AllPagesTab(Context context) {
    super(context);
    mSearchEngines = new ArrayList<SearchEngine>();

    registerEventListener("SearchEngines:Data");
    GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SearchEngines:Get", null));

    mHandler = new AllPagesHandler();
  }
Example #10
0
 /**
  * Handle a confirmation response from the user.
  *
  * @param value String value to return to the browser context.
  */
 public void confirmWithValue(String value) {
   JSONObject result = makeResult(RESULT_OK);
   try {
     result.put("textbox0", value);
   } catch (JSONException ex) {
   }
   GeckoAppShell.sendEventToGecko(
       GeckoEvent.createBroadcastEvent("Prompt:Reply", result.toString()));
 }
 public void finishDialog(String aReturn) {
   mInputs = null;
   mButtons = null;
   mDialog = null;
   mSelected = null;
   mPromptQueue.offer(aReturn);
   // poke the Gecko thread in case it's waiting for new events
   GeckoAppShell.sendEventToGecko(GeckoEvent.createNoOpEvent());
 }
Example #12
0
  @Override
  protected void onNewIntent(Intent intent) {
    if (checkLaunchState(LaunchState.GeckoExiting)) {
      // We're exiting and shouldn't try to do anything else just incase
      // we're hung for some reason we'll force the process to exit
      System.exit(0);
      return;
    }
    final String action = intent.getAction();
    if (ACTION_DEBUG.equals(action)
        && checkAndSetLaunchState(LaunchState.Launching, LaunchState.WaitForDebugger)) {

      mMainHandler.postDelayed(
          new Runnable() {
            public void run() {
              Log.i(LOG_FILE_NAME, "Launching from debug intent after 5s wait");
              setLaunchState(LaunchState.Launching);
              launch(null);
            }
          },
          1000 * 5 /* 5 seconds */);
      Log.i(LOG_FILE_NAME, "Intent : ACTION_DEBUG - waiting 5s before launching");
      return;
    }
    if (checkLaunchState(LaunchState.WaitForDebugger) || launch(intent)) return;

    if (Intent.ACTION_MAIN.equals(action)) {
      Log.i(LOG_FILE_NAME, "Intent : ACTION_MAIN");
      GeckoAppShell.sendEventToGecko(new GeckoEvent(""));
    } else if (Intent.ACTION_VIEW.equals(action)) {
      String uri = intent.getDataString();
      GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
      Log.i(LOG_FILE_NAME, "onNewIntent: " + uri);
    } else if (ACTION_WEBAPP.equals(action)) {
      String uri = intent.getStringExtra("args");
      GeckoAppShell.sendEventToGecko(new GeckoEvent(uri));
      Log.i(LOG_FILE_NAME, "Intent : WEBAPP - " + uri);
    } else if (ACTION_BOOKMARK.equals(action)) {
      String args = intent.getStringExtra("args");
      GeckoAppShell.sendEventToGecko(new GeckoEvent(args));
      Log.i(LOG_FILE_NAME, "Intent : BOOKMARK - " + args);
    }
  }
  protected void onActivityResume(GeckoActivityStatus activity) {
    if (mPausedGecko) {
      GeckoAppShell.sendEventToGecko(GeckoEvent.createAppForegroundingEvent());
      mPausedGecko = false;
    }
    GeckoConnectivityReceiver.getInstance().start();
    GeckoNetworkManager.getInstance().start();

    mInBackground = false;
  }
Example #14
0
  public void handleNotificationIntent(Intent i) {
    final Uri data = i.getData();
    if (data == null) {
      Log.e(LOGTAG, "handleNotificationEvent: empty data");
      return;
    }
    final String id = data.getQueryParameter(ID_ATTR);
    final String notificationType = data.getQueryParameter(EVENT_TYPE_ATTR);
    if (id == null || notificationType == null) {
      Log.e(LOGTAG, "handleNotificationEvent: invalid intent parameters");
      return;
    }

    // In case the user swiped out the notification, we empty the id set.
    if (CLEARED_EVENT.equals(notificationType)) {
      mClearableNotifications.remove(id);
      // If Gecko isn't running, we throw away events where the notification was cancelled.
      // i.e. Don't bug the user if they're just closing a bunch of notifications.
      if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
        return;
      }
    }

    JSONObject args = new JSONObject();

    // The handler and cookie parameters are optional
    final String handler = data.getQueryParameter(HANDLER_ATTR);
    final String cookie = i.getStringExtra(COOKIE_ATTR);

    try {
      args.put(ID_ATTR, id);
      args.put(EVENT_TYPE_ATTR, notificationType);
      args.put(HANDLER_ATTR, handler);
      args.put(COOKIE_ATTR, cookie);

      if (BUTTON_EVENT.equals(notificationType)) {
        final String actionName = data.getQueryParameter(ACTION_ID_ATTR);
        args.put(ACTION_ID_ATTR, actionName);
      }

      Log.i(LOGTAG, "Send " + args.toString());
      GeckoAppShell.sendEventToGecko(
          GeckoEvent.createBroadcastEvent("Notification:Event", args.toString()));
    } catch (JSONException e) {
      Log.e(LOGTAG, "Error building JSON notification arguments.", e);
    }

    // If the notification was clicked, we are closing it. This must be executed after
    // sending the event to js side because when the notification is canceled no event can be
    // handled.
    if (CLICK_EVENT.equals(notificationType) && !i.getBooleanExtra(ONGOING_ATTR, false)) {
      hideNotification(id, handler, cookie);
    }
  }
  private void updateNetworkType() {
    NetworkType previousNetworkType = mNetworkType;
    mNetworkType = getNetworkType();

    if (mNetworkType == previousNetworkType || !mShouldNotify) {
      return;
    }

    GeckoAppShell.sendEventToGecko(
        GeckoEvent.createNetworkEvent(
            getNetworkSpeed(mNetworkType), isNetworkUsuallyMetered(mNetworkType)));
  }
Example #16
0
 @Override
 public boolean onActionItemClicked(ActionModeCompat mode, MenuItem item) {
   try {
     final JSONObject obj = mItems.getJSONObject(item.getItemId());
     GeckoAppShell.sendEventToGecko(
         GeckoEvent.createBroadcastEvent("TextSelection:Action", obj.optString("id")));
     return true;
   } catch (Exception ex) {
     Log.i(LOGTAG, "Exception calling action", ex);
   }
   return false;
 }
Example #17
0
 /**
  * Load a URL resource into the Browser.
  *
  * @param url The URL string.
  */
 public void loadUrl(String url) {
   JSONObject args = new JSONObject();
   try {
     args.put("url", url);
     args.put("parentId", -1);
     args.put("newTab", false);
     args.put("tabID", mId);
   } catch (Exception e) {
     Log.w(LOGTAG, "Error building JSON arguments for loadUrl.", e);
   }
   GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Load", args.toString()));
 }
Example #18
0
 private void sendNotificationWasClosed(String id, String handlerKey, String cookie) {
   final JSONObject args = new JSONObject();
   try {
     args.put(ID_ATTR, id);
     args.put(HANDLER_ATTR, handlerKey);
     args.put(COOKIE_ATTR, cookie);
     args.put(EVENT_TYPE_ATTR, CLOSED_EVENT);
     Log.i(LOGTAG, "Send " + args.toString());
     GeckoAppShell.sendEventToGecko(
         GeckoEvent.createBroadcastEvent("Notification:Event", args.toString()));
   } catch (JSONException ex) {
     Log.e(LOGTAG, "sendNotificationWasClosed: error building JSON notification arguments.", ex);
   }
 }
  @Override
  public boolean performContextMenuAction(int id) {
    final Editable content = getEditable();
    if (content == null) return false;

    String text = content.toString();

    clampSelection();
    int a = Selection.getSelectionStart(content);
    int b = Selection.getSelectionEnd(content);

    switch (id) {
      case R.id.selectAll:
        setSelection(0, text.length());
        break;
      case R.id.cut:
        // Fill the clipboard
        GeckoAppShell.setClipboardText(text);
        // If selection is empty, we'll select everything
        if (a >= b)
          GeckoAppShell.sendEventToGecko(
              GeckoEvent.createIMEEvent(GeckoEvent.IME_SET_SELECTION, 0, text.length()));
        GeckoAppShell.sendEventToGecko(GeckoEvent.createIMEEvent(GeckoEvent.IME_DELETE_TEXT, 0, 0));
        break;
      case R.id.paste:
        commitText(GeckoAppShell.getClipboardText(), 1);
        break;
      case R.id.copy:
        // If there is no selection set, we must be doing "Copy All",
        // otherwise get the selection
        if (a < b) text = text.substring(a, b);
        GeckoAppShell.setClipboardText(text.substring(a, b));
        break;
    }
    return true;
  }
Example #20
0
  @Override
  public void onPause() {
    Log.i(LOG_FILE_NAME, "pause");
    GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_PAUSING));
    // The user is navigating away from this activity, but nothing
    // has come to the foreground yet; for Gecko, we may want to
    // stop repainting, for example.

    // Whatever we do here should be fast, because we're blocking
    // the next activity from showing up until we finish.

    // onPause will be followed by either onResume or onStop.
    super.onPause();

    unregisterReceiver(mConnectivityReceiver);
    GeckoNetworkManager.getInstance().stop();
    GeckoScreenOrientationListener.getInstance().stop();
  }
Example #21
0
  @Override
  public void onStop() {
    Log.i(LOG_FILE_NAME, "stop");
    // We're about to be stopped, potentially in preparation for
    // being destroyed.  We're killable after this point -- as I
    // understand it, in extreme cases the process can be terminated
    // without going through onDestroy.
    //
    // We might also get an onRestart after this; not sure what
    // that would mean for Gecko if we were to kill it here.
    // Instead, what we should do here is save prefs, session,
    // etc., and generally mark the profile as 'clean', and then
    // dirty it again if we get an onResume.

    GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_STOPPING));
    super.onStop();
    GeckoAppShell.putChildInBackground();
  }
Example #22
0
  @Override
  public void onDestroy() {
    Log.i(LOG_FILE_NAME, "destroy");

    // Tell Gecko to shutting down; we'll end up calling System.exit()
    // in onXreExit.
    if (isFinishing()) GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_SHUTDOWN));

    if (SmsManager.getInstance() != null) {
      SmsManager.getInstance().stop();
      if (isFinishing()) SmsManager.getInstance().shutdown();
    }

    GeckoNetworkManager.getInstance().stop();
    GeckoScreenOrientationListener.getInstance().stop();

    super.onDestroy();

    unregisterReceiver(mBatteryReceiver);
  }
  private boolean synthesizeKeyEvents(char inputChar) {
    if (mKeyCharacterMap == null) {
      mKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
    }

    // Synthesize VKB key events that could plausibly generate the input character.
    char[] inputChars = {inputChar};
    KeyEvent[] events = mKeyCharacterMap.getEvents(inputChars);
    if (events == null) {
      if (DEBUG) {
        Log.d(LOGTAG, "synthesizeKeyEvents: char '" + inputChar + "' has no virtual key mapping");
      }
      return false;
    }

    boolean sentKeyEvents = false;

    for (KeyEvent event : events) {
      if (!KeyEvent.isModifierKey(event.getKeyCode())) {
        if (DEBUG) {
          Log.d(
              LOGTAG,
              "synthesizeKeyEvents: char '"
                  + inputChar
                  + "' -> action="
                  + event.getAction()
                  + ", keyCode="
                  + event.getKeyCode()
                  + ", UnicodeChar='"
                  + (char) event.getUnicodeChar()
                  + "'");
        }
        GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event));
        sentKeyEvents = true;
      }
    }

    return sentKeyEvents;
  }
  protected void onActivityPause(GeckoActivityStatus activity) {
    mInBackground = true;

    if ((activity.isFinishing() == false) && (activity.isGeckoActivityOpened() == false)) {
      // Notify Gecko that we are pausing; the cache service will be
      // shutdown, closing the disk cache cleanly. If the android
      // low memory killer subsequently kills us, the disk cache will
      // be left in a consistent state, avoiding costly cleanup and
      // re-creation.
      GeckoAppShell.sendEventToGecko(GeckoEvent.createAppBackgroundingEvent());
      mPausedGecko = true;

      ThreadUtils.postToBackgroundThread(
          new Runnable() {
            @Override
            public void run() {
              BrowserDB.expireHistory(getContentResolver(), BrowserContract.ExpirePriority.NORMAL);
            }
          });
    }
    GeckoConnectivityReceiver.getInstance().stop();
    GeckoNetworkManager.getInstance().stop();
  }
  // send the Preferences:Set message to Gecko
  public static void setPreference(String pref, Object value) {
    if (pref == null || pref.length() == 0) return;

    try {
      JSONObject jsonPref = new JSONObject();
      jsonPref.put("name", pref);
      if (value instanceof Boolean) {
        jsonPref.put("type", "bool");
        jsonPref.put("value", ((Boolean) value).booleanValue());
      } else if (value instanceof Integer) {
        jsonPref.put("type", "int");
        jsonPref.put("value", ((Integer) value).intValue());
      } else {
        jsonPref.put("type", "string");
        jsonPref.put("value", String.valueOf(value));
      }

      GeckoEvent event = GeckoEvent.createBroadcastEvent("Preferences:Set", jsonPref.toString());
      GeckoAppShell.sendEventToGecko(event);
    } catch (JSONException e) {
      Log.e(LOGTAG, "JSON exception: ", e);
    }
  }
Example #26
0
  private void init(Context context, String url, boolean doInit) {
    // TODO: Fennec currently takes care of its own initialization, so this
    // flag is a hack used in Fennec to prevent GeckoView initialization.
    // This should go away once Fennec also uses GeckoView for
    // initialization.
    if (!doInit) return;

    // If running outside of a GeckoActivity (eg, from a library project),
    // load the native code and disable content providers
    boolean isGeckoActivity = false;
    try {
      isGeckoActivity = context instanceof GeckoActivity;
    } catch (NoClassDefFoundError ex) {
    }

    if (!isGeckoActivity) {
      // Set the GeckoInterface if the context is an activity and the GeckoInterface
      // has not already been set
      if (context instanceof Activity && getGeckoInterface() == null) {
        setGeckoInterface(new BaseGeckoInterface(context));
      }

      Clipboard.init(context);
      HardwareUtils.init(context);

      // If you want to use GeckoNetworkManager, start it.

      GeckoLoader.loadMozGlue();
      BrowserDB.setEnableContentProviders(false);
    }

    if (url != null) {
      GeckoThread.setUri(url);
      GeckoThread.setAction(Intent.ACTION_VIEW);
      GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(url));
    }
    GeckoAppShell.setContextGetter(this);
    if (context instanceof Activity) {
      Tabs tabs = Tabs.getInstance();
      tabs.attachToContext(context);
    }

    EventDispatcher.getInstance()
        .registerGeckoThreadListener(
            this,
            "Gecko:Ready",
            "Content:StateChange",
            "Content:LoadError",
            "Content:PageShow",
            "DOMTitleChanged",
            "Link:Favicon",
            "Prompt:Show",
            "Prompt:ShowTop");

    ThreadUtils.setUiThread(Thread.currentThread(), new Handler());
    initializeView(EventDispatcher.getInstance());

    if (GeckoThread.checkAndSetLaunchState(
        GeckoThread.LaunchState.Launching, GeckoThread.LaunchState.Launched)) {
      // This is the first launch, so finish initialization and go.
      GeckoProfile profile = GeckoProfile.get(context).forceCreate();
      BrowserDB.initialize(profile.getName());

      GeckoAppShell.setLayerView(this);
      GeckoThread.createAndStart();
    } else if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
      // If Gecko is already running, that means the Activity was
      // destroyed, so we need to re-attach Gecko to this GeckoView.
      connectToGecko();
    }
  }
Example #27
0
 /** Handle a cancellation response from the user. */
 public void cancel() {
   JSONObject result = makeResult(RESULT_CANCEL);
   GeckoAppShell.sendEventToGecko(
       GeckoEvent.createBroadcastEvent("Prompt:Reply", result.toString()));
 }
 public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
   GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event));
   return true;
 }
  private void sendTextToGecko(CharSequence text, int caretPos) {
    if (DEBUG) Log.d(LOGTAG, "IME: sendTextToGecko(\"" + text + "\")");

    // Handle composition text styles
    if (text != null && text instanceof Spanned) {
      Spanned span = (Spanned) text;
      int spanStart = 0, spanEnd = 0;
      boolean pastSelStart = false, pastSelEnd = false;

      do {
        int rangeType = GeckoEvent.IME_RANGE_CONVERTEDTEXT;
        int rangeStyles = 0, rangeForeColor = 0, rangeBackColor = 0;

        // Find next offset where there is a style transition
        spanEnd = span.nextSpanTransition(spanStart + 1, text.length(), CharacterStyle.class);

        // Empty range, continue
        if (spanEnd <= spanStart) continue;

        // Get and iterate through list of span objects within range
        CharacterStyle[] styles = span.getSpans(spanStart, spanEnd, CharacterStyle.class);

        for (CharacterStyle style : styles) {
          if (style instanceof UnderlineSpan) {
            // Text should be underlined
            rangeStyles |= GeckoEvent.IME_RANGE_UNDERLINE;
          } else if (style instanceof ForegroundColorSpan) {
            // Text should be of a different foreground color
            rangeStyles |= GeckoEvent.IME_RANGE_FORECOLOR;
            rangeForeColor = ((ForegroundColorSpan) style).getForegroundColor();
          } else if (style instanceof BackgroundColorSpan) {
            // Text should be of a different background color
            rangeStyles |= GeckoEvent.IME_RANGE_BACKCOLOR;
            rangeBackColor = ((BackgroundColorSpan) style).getBackgroundColor();
          }
        }

        // Add range to array, the actual styles are
        //  applied when IME_SET_TEXT is sent
        if (DEBUG) {
          Log.d(
              LOGTAG,
              String.format(
                  ". . . sendTextToGecko: IME_ADD_RANGE, %d, %d, %d, %d, %d, %d",
                  spanStart,
                  spanEnd - spanStart,
                  rangeType,
                  rangeStyles,
                  rangeForeColor,
                  rangeBackColor));
        }

        GeckoAppShell.sendEventToGecko(
            GeckoEvent.createIMERangeEvent(
                spanStart,
                spanEnd - spanStart,
                rangeType,
                rangeStyles,
                rangeForeColor,
                rangeBackColor));

        spanStart = spanEnd;
      } while (spanStart < text.length());
    } else {
      if (DEBUG)
        Log.d(
            LOGTAG,
            ". . . sendTextToGecko: IME_ADD_RANGE, 0, "
                + text.length()
                + ", IME_RANGE_RAWINPUT, IME_RANGE_UNDERLINE)");
      GeckoAppShell.sendEventToGecko(
          GeckoEvent.createIMERangeEvent(
              0,
              text == null ? 0 : text.length(),
              GeckoEvent.IME_RANGE_RAWINPUT,
              GeckoEvent.IME_RANGE_UNDERLINE,
              0,
              0));
    }

    // Change composition (treating selection end as where the caret is)
    if (DEBUG) {
      Log.d(
          LOGTAG,
          ". . . sendTextToGecko: IME_SET_TEXT, IME_RANGE_CARETPOSITION, \"" + text + "\")");
    }

    GeckoAppShell.sendEventToGecko(
        GeckoEvent.createIMERangeEvent(
            caretPos, 0, GeckoEvent.IME_RANGE_CARETPOSITION, 0, 0, 0, text.toString()));
  }
 private void endComposition() {
   if (DEBUG) Log.d(LOGTAG, "IME: endComposition: IME_COMPOSITION_END");
   GeckoAppShell.sendEventToGecko(GeckoEvent.createIMEEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0));
   mCompositionStart = NO_COMPOSITION_STRING;
 }