content: /*
   * Copyright (C) 2013 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.webkit;
  
  import android.annotation.SystemApi;
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.content.Context;
  import android.content.DialogInterface;
  import android.os.Message;
  import android.util.Log;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.widget.EditText;
  import android.widget.TextView;
  
  import java.net.MalformedURLException;
  import java.net.URL;
  
  /**
   * Helper class to create JavaScript dialogs. It is used by
   * different WebView implementations.
   *
   * @hide
   */
  @SystemApi
  public class JsDialogHelper {
  
      private static final String TAG = "JsDialogHelper";
  
      // Dialog types
      public static final int ALERT   = 1;
      public static final int CONFIRM = 2;
      public static final int PROMPT  = 3;
      public static final int UNLOAD  = 4;
  
      private final String mDefaultValue;
      private final JsPromptResult mResult;
      private final String mMessage;
      private final int mType;
      private final String mUrl;
  
      public JsDialogHelper(JsPromptResult result, int type, String defaultValue, String message,
              String url) {
          mResult = result;
          mDefaultValue = defaultValue;
          mMessage = message;
          mType = type;
          mUrl = url;
      }
  
      public JsDialogHelper(JsPromptResult result, Message msg) {
          mResult = result;
          mDefaultValue = msg.getData().getString("default");
          mMessage = msg.getData().getString("message");
          mType = msg.getData().getInt("type");
          mUrl = msg.getData().getString("url");
      }
  
      public boolean invokeCallback(WebChromeClient client, WebView webView) {
          switch (mType) {
              case ALERT:
                  return client.onJsAlert(webView, mUrl, mMessage, mResult);
              case CONFIRM:
                  return client.onJsConfirm(webView, mUrl, mMessage, mResult);
              case UNLOAD:
                  return client.onJsBeforeUnload(webView, mUrl, mMessage, mResult);
              case PROMPT:
                  return client.onJsPrompt(webView, mUrl, mMessage, mDefaultValue, mResult);
              default:
                  throw new IllegalArgumentException("Unexpected type: " + mType);
          }
      }
  
      public void showDialog(Context context) {
          if (!canShowAlertDialog(context)) {
              Log.w(TAG, "Cannot create a dialog, the WebView context is not an Activity");
              mResult.cancel();
              return;
          }
  
          String title, displayMessage;
          int positiveTextId, negativeTextId;
          if (mType == UNLOAD) {
              title = context.getString(com.android.internal.R.string.js_dialog_before_unload_title);
              displayMessage = context.getString(
                      com.android.internal.R.string.js_dialog_before_unload, mMessage);
              positiveTextId = com.android.internal.R.string.js_dialog_before_unload_positive_button;
              negativeTextId = com.android.internal.R.string.js_dialog_before_unload_negative_button;
          } else {
              title = getJsDialogTitle(context);
              displayMessage = mMessage;
              positiveTextId = com.android.internal.R.string.ok;
              negativeTextId = com.android.internal.R.string.cancel;
          }
          AlertDialog.Builder builder = new AlertDialog.Builder(context);
          builder.setTitle(title);
          builder.setOnCancelListener(new CancelListener());
          if (mType != PROMPT) {
              builder.setMessage(displayMessage);
              builder.setPositiveButton(positiveTextId, new PositiveListener(null));
          } else {
              final View view = LayoutInflater.from(context).inflate(
                      com.android.internal.R.layout.js_prompt, null);
              EditText edit = ((EditText) view.findViewById(com.android.internal.R.id.value));
              edit.setText(mDefaultValue);
              builder.setPositiveButton(positiveTextId, new PositiveListener(edit));
              ((TextView) view.findViewById(com.android.internal.R.id.message)).setText(mMessage);
              builder.setView(view);
          }
          if (mType != ALERT) {
              builder.setNegativeButton(negativeTextId, new CancelListener());
          }
          builder.show();
      }
  
      private class CancelListener implements DialogInterface.OnCancelListener,
              DialogInterface.OnClickListener {
          @Override
          public void onCancel(DialogInterface dialog) {
              mResult.cancel();
          }
          @Override
          public void onClick(DialogInterface dialog, int which) {
              mResult.cancel();
          }
      }
  
      private class PositiveListener implements DialogInterface.OnClickListener {
          private final EditText mEdit;
  
          public PositiveListener(EditText edit) {
              mEdit = edit;
          }
  
          @Override
          public void onClick(DialogInterface dialog, int which) {
              if (mEdit == null) {
                  mResult.confirm();
              } else {
                  mResult.confirm(mEdit.getText().toString());
              }
          }
      }
  
      private String getJsDialogTitle(Context context) {
          String title = mUrl;
          if (URLUtil.isDataUrl(mUrl)) {
              // For data: urls, we just display 'JavaScript' similar to Chrome.
              title = context.getString(com.android.internal.R.string.js_dialog_title_default);
          } else {
              try {
                  URL alertUrl = new URL(mUrl);
                  // For example: "The page at 'http://www.mit.edu' says:"
                  title = context.getString(com.android.internal.R.string.js_dialog_title,
                          alertUrl.getProtocol() + "://" + alertUrl.getHost());
              } catch (MalformedURLException ex) {
                  // do nothing. just use the url as the title
              }
          }
          return title;
      }
  
      private static boolean canShowAlertDialog(Context context) {
          // We can only display the alert dialog if mContext is
          // an Activity context.
          // FIXME: Should we display dialogs if mContext does
          // not have the window focus (e.g. if the user is viewing
          // another Activity when the alert should be displayed) ?
          // See bug 3166409
          return context instanceof Activity;
      }
  }
  