1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.browser;
17
18import android.app.AlertDialog;
19import android.content.Context;
20import android.content.DialogInterface;
21import android.view.KeyEvent;
22import android.view.LayoutInflater;
23import android.view.View;
24import android.view.WindowManager;
25import android.view.inputmethod.EditorInfo;
26import android.widget.TextView;
27import android.widget.TextView.OnEditorActionListener;
28
29/**
30 * HTTP authentication dialog.
31 */
32public class HttpAuthenticationDialog {
33
34    private final Context mContext;
35
36    private final String mHost;
37    private final String mRealm;
38
39    private AlertDialog mDialog;
40    private TextView mUsernameView;
41    private TextView mPasswordView;
42
43    private OkListener mOkListener;
44    private CancelListener mCancelListener;
45
46    /**
47     * Creates an HTTP authentication dialog.
48     */
49    public HttpAuthenticationDialog(Context context, String host, String realm) {
50        mContext = context;
51        mHost = host;
52        mRealm = realm;
53        createDialog();
54    }
55
56    private String getUsername() {
57        return mUsernameView.getText().toString();
58    }
59
60    private String getPassword() {
61        return mPasswordView.getText().toString();
62    }
63
64    /**
65     * Sets the listener that will be notified when the user submits the credentials.
66     */
67    public void setOkListener(OkListener okListener) {
68        mOkListener = okListener;
69    }
70
71    /**
72     * Sets the listener that will be notified when the user cancels the authentication
73     * dialog.
74     */
75    public void setCancelListener(CancelListener cancelListener) {
76        mCancelListener = cancelListener;
77    }
78
79    /**
80     * Shows the dialog.
81     */
82    public void show() {
83        mDialog.show();
84        mUsernameView.requestFocus();
85    }
86
87    /**
88     * Hides, recreates, and shows the dialog. This can be used to handle configuration changes.
89     */
90    public void reshow() {
91        String username = getUsername();
92        String password = getPassword();
93        int focusId = mDialog.getCurrentFocus().getId();
94        mDialog.dismiss();
95        createDialog();
96        mDialog.show();
97        if (username != null) {
98            mUsernameView.setText(username);
99        }
100        if (password != null) {
101            mPasswordView.setText(password);
102        }
103        if (focusId != 0) {
104            mDialog.findViewById(focusId).requestFocus();
105        } else {
106            mUsernameView.requestFocus();
107        }
108    }
109
110    private void createDialog() {
111        LayoutInflater factory = LayoutInflater.from(mContext);
112        View v = factory.inflate(R.layout.http_authentication, null);
113        mUsernameView = (TextView) v.findViewById(R.id.username_edit);
114        mPasswordView = (TextView) v.findViewById(R.id.password_edit);
115        mPasswordView.setOnEditorActionListener(new OnEditorActionListener() {
116            @Override
117            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
118                if (actionId == EditorInfo.IME_ACTION_DONE) {
119                    mDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
120                    return true;
121                }
122                return false;
123            }
124        });
125
126        String title = mContext.getText(R.string.sign_in_to).toString().replace(
127                "%s1", mHost).replace("%s2", mRealm);
128
129        mDialog = new AlertDialog.Builder(mContext)
130                .setTitle(title)
131                .setIcon(android.R.drawable.ic_dialog_alert)
132                .setView(v)
133                .setPositiveButton(R.string.action, new DialogInterface.OnClickListener() {
134                    public void onClick(DialogInterface dialog, int whichButton) {
135                        if (mOkListener != null) {
136                            mOkListener.onOk(mHost, mRealm, getUsername(), getPassword());
137                        }
138                    }})
139                .setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener() {
140                    public void onClick(DialogInterface dialog, int whichButton) {
141                        if (mCancelListener != null) mCancelListener.onCancel();
142                    }})
143                .setOnCancelListener(new DialogInterface.OnCancelListener() {
144                    public void onCancel(DialogInterface dialog) {
145                        if (mCancelListener != null) mCancelListener.onCancel();
146                    }})
147                .create();
148
149        // Make the IME appear when the dialog is displayed if applicable.
150        mDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
151    }
152
153    /**
154     * Interface for listeners that are notified when the user submits the credentials.
155     */
156    public interface OkListener {
157        void onOk(String host, String realm, String username, String password);
158    }
159
160    /**
161     * Interface for listeners that are notified when the user cancels the dialog.
162     */
163    public interface CancelListener {
164        void onCancel();
165    }
166}
167