/**
   * Display the specified URL in a custom browser screen.
   *
   * @param args JSONArry of arguments for the action.
   * @return a PluginResult
   */
  private synchronized PluginResult showWebPage(JSONArray args) {
    PluginResult result;

    if (browser == null) {
      try {
        boolean showLocationBar = true;
        String url = args.getString(0);
        JSONObject options = args.getJSONObject(1);

        // Determine whether to show or hide navigation bar.
        if (options != null) {
          showLocationBar = options.optBoolean("showLocationBar", true);
        }

        browser = new CustomBrowser(callbackId);
        if (browser.init(showLocationBar)) {
          uiApp.invokeLater(
              new Runnable() {
                public void run() {
                  uiApp.pushScreen(browser);
                }
              });

          browser.loadURL(url);

          // Must keep the callback for browser URL load and close
          // events.
          result = new PluginResult(PluginResult.Status.OK, "");
          result.setKeepCallback(true);
        } else {
          result =
              new PluginResult(
                  PluginResult.Status.ERROR, TAG + "Failed to initialize CustomBrowser.");
        }
      } catch (JSONException e) {
        return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
      }
    } else {
      result = new PluginResult(PluginResult.Status.ERROR, "ChildBrowser is already open.");
    }

    return result;
  }
  /**
   * Load an URL in the device's browser application.
   *
   * @param args JSONArry of arguments for the action.
   * @return a PluginResult
   */
  private PluginResult openExternal(JSONArray args) {
    try {
      String url = args.getString(0);

      BrowserSession session = Browser.getDefaultSession();
      session.displayPage(url);
    } catch (JSONException e) {
      return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
    }

    return new PluginResult(PluginResult.Status.OK, "");
  }
  /**
   * Beeps the device for a given number of times. By default, it will beep once. If the user
   * explicitly sets the beep count to zero, it will play the applications notification profile. The
   * application profile playback sequence is controlled by the user.
   *
   * @param args JSONArray formatted as [ count ] count: specifies the number of times to beep the
   *     device (default: 1).
   * @return A CommandResult object with the success or failure state for beeping the device.
   */
  public static PluginResult execute(JSONArray args) {
    PluginResult result = null;

    if (Alert.isAudioSupported()) {

      try {
        int repeatCount = 1;
        if (args.length() > 0 && !args.isNull(0)) {
          repeatCount = args.getInt(0);
        }

        // play tone n times
        if (repeatCount > 0) {
          playTone(repeatCount);
        }
        // FIXME: unsupported on other platforms
        // send notification event to application profile
        else {
          NotificationsManager.triggerImmediateEvent(CordovaExtension.getAppID(), 0, null, null);
        }
      } catch (JSONException e) {
        Logger.log(BeepAction.class.getName() + ": " + e);
        result = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
      } catch (Exception e) {
        Logger.log(BeepAction.class.getName() + ": " + e);
        result = new PluginResult(PluginResult.Status.IO_EXCEPTION, e.getMessage());
      }

      result = new PluginResult(PluginResult.Status.OK);
    } else {
      result =
          new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, "Audio not supported");
    }

    return result;
  }