blob: 196356467bbe9ef18502ab33eee461f4e4733d55 [file] [log] [blame]
John Reck0f602f32011-07-07 15:38:43 -07001/*
2 * Copyright (C) 2011 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.SearchManager;
kaiyizc4ada322013-07-30 09:58:07 +080019import android.content.ActivityNotFoundException;
John Reck0f602f32011-07-07 15:38:43 -070020import android.content.Context;
21import android.content.Intent;
22import android.graphics.Bitmap;
23import android.graphics.drawable.Drawable;
kaiyizc4ada322013-07-30 09:58:07 +080024import android.net.Uri;
John Reck0f602f32011-07-07 15:38:43 -070025import android.os.Bundle;
kaiyizc4ada322013-07-30 09:58:07 +080026import android.os.SystemProperties;
Narayan Kamathf3174a52011-11-17 14:43:32 +000027import android.text.Editable;
28import android.text.TextWatcher;
John Reck0f602f32011-07-07 15:38:43 -070029import android.util.AttributeSet;
kaiyizc4ada322013-07-30 09:58:07 +080030import android.util.Log;
John Reck0f602f32011-07-07 15:38:43 -070031import android.view.KeyEvent;
John Reck0f602f32011-07-07 15:38:43 -070032import android.view.View;
33import android.view.View.OnClickListener;
34import android.view.View.OnFocusChangeListener;
John Reckfa6177a2011-11-15 14:51:11 -080035import android.webkit.WebView;
John Reck0f602f32011-07-07 15:38:43 -070036import android.widget.ImageView;
37import android.widget.LinearLayout;
kaiyizc4ada322013-07-30 09:58:07 +080038import android.widget.Toast;
John Reck0f602f32011-07-07 15:38:43 -070039
John Reck0f602f32011-07-07 15:38:43 -070040import com.android.browser.UrlInputView.UrlInputListener;
John Reck0f602f32011-07-07 15:38:43 -070041
kaiyizc4ada322013-07-30 09:58:07 +080042import java.io.UnsupportedEncodingException;
43
John Reck42229bc2011-08-19 13:26:43 -070044public class NavigationBarBase extends LinearLayout implements
45 OnClickListener, UrlInputListener, OnFocusChangeListener,
Narayan Kamathf3174a52011-11-17 14:43:32 +000046 TextWatcher {
John Reck0f602f32011-07-07 15:38:43 -070047
kaiyizc4ada322013-07-30 09:58:07 +080048 private final static String TAG = "NavigationBarBase";
49
John Reck0f602f32011-07-07 15:38:43 -070050 protected BaseUi mBaseUi;
51 protected TitleBar mTitleBar;
52 protected UiController mUiController;
53 protected UrlInputView mUrlInput;
John Reck0f602f32011-07-07 15:38:43 -070054
55 private ImageView mFavicon;
56 private ImageView mLockIcon;
John Reck0f602f32011-07-07 15:38:43 -070057
58 public NavigationBarBase(Context context) {
59 super(context);
60 }
61
62 public NavigationBarBase(Context context, AttributeSet attrs) {
63 super(context, attrs);
64 }
65
66 public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) {
67 super(context, attrs, defStyle);
68 }
69
70 @Override
71 protected void onFinishInflate() {
72 super.onFinishInflate();
73 mLockIcon = (ImageView) findViewById(R.id.lock);
74 mFavicon = (ImageView) findViewById(R.id.favicon);
75 mUrlInput = (UrlInputView) findViewById(R.id.url);
76 mUrlInput.setUrlInputListener(this);
John Reck0f602f32011-07-07 15:38:43 -070077 mUrlInput.setOnFocusChangeListener(this);
78 mUrlInput.setSelectAllOnFocus(true);
Narayan Kamathf3174a52011-11-17 14:43:32 +000079 mUrlInput.addTextChangedListener(this);
John Reck0f602f32011-07-07 15:38:43 -070080 }
81
82 public void setTitleBar(TitleBar titleBar) {
83 mTitleBar = titleBar;
84 mBaseUi = mTitleBar.getUi();
85 mUiController = mTitleBar.getUiController();
Michael Kolbb2e91fd2011-07-14 13:47:29 -070086 mUrlInput.setController(mUiController);
John Reck0f602f32011-07-07 15:38:43 -070087 }
88
89 public void setLock(Drawable d) {
90 if (mLockIcon == null) return;
91 if (d == null) {
92 mLockIcon.setVisibility(View.GONE);
93 } else {
94 mLockIcon.setImageDrawable(d);
95 mLockIcon.setVisibility(View.VISIBLE);
96 }
97 }
98
99 public void setFavicon(Bitmap icon) {
100 if (mFavicon == null) return;
101 mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon));
102 }
103
John Reck0f602f32011-07-07 15:38:43 -0700104 @Override
105 public void onClick(View v) {
John Reck0f602f32011-07-07 15:38:43 -0700106 }
107
108 @Override
109 public void onFocusChange(View view, boolean hasFocus) {
110 // if losing focus and not in touch mode, leave as is
111 if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) {
112 setFocusState(hasFocus);
113 }
114 if (hasFocus) {
115 mBaseUi.showTitleBar();
John Reck0f602f32011-07-07 15:38:43 -0700116 } else if (!mUrlInput.needsUpdate()) {
117 mUrlInput.dismissDropDown();
118 mUrlInput.hideIME();
119 if (mUrlInput.getText().length() == 0) {
120 Tab currentTab = mUiController.getTabControl().getCurrentTab();
121 if (currentTab != null) {
John Reck434e9f82011-08-10 18:16:52 -0700122 setDisplayTitle(currentTab.getUrl());
John Reck0f602f32011-07-07 15:38:43 -0700123 }
124 }
125 mBaseUi.suggestHideTitleBar();
126 }
127 mUrlInput.clearNeedsUpdate();
128 }
129
130 protected void setFocusState(boolean focus) {
131 }
132
John Reck0f602f32011-07-07 15:38:43 -0700133 public boolean isEditingUrl() {
134 return mUrlInput.hasFocus();
135 }
136
137 void stopEditingUrl() {
Michael Kolb0b129122012-06-04 16:31:58 -0700138 WebView currentTopWebView = mUiController.getCurrentTopWebView();
139 if (currentTopWebView != null) {
140 currentTopWebView.requestFocus();
141 }
John Reck0f602f32011-07-07 15:38:43 -0700142 }
143
144 void setDisplayTitle(String title) {
145 if (!isEditingUrl()) {
Michael Kolb29aab402012-05-29 17:22:35 -0700146 if (!title.equals(mUrlInput.getText().toString())) {
147 mUrlInput.setText(title, false);
148 }
John Reck0f602f32011-07-07 15:38:43 -0700149 }
150 }
151
John Reck0f602f32011-07-07 15:38:43 -0700152 void setIncognitoMode(boolean incognito) {
153 mUrlInput.setIncognitoMode(incognito);
154 }
155
156 void clearCompletions() {
Narayan Kamathf3174a52011-11-17 14:43:32 +0000157 mUrlInput.dismissDropDown();
John Reck0f602f32011-07-07 15:38:43 -0700158 }
159
160 // UrlInputListener implementation
161
162 /**
163 * callback from suggestion dropdown
164 * user selected a suggestion
165 */
166 @Override
167 public void onAction(String text, String extra, String source) {
Michael Kolb0b129122012-06-04 16:31:58 -0700168 stopEditingUrl();
John Reck0f602f32011-07-07 15:38:43 -0700169 if (UrlInputView.TYPED.equals(source)) {
kaiyizc4ada322013-07-30 09:58:07 +0800170 String url = null;
171 boolean wap2estore = SystemProperties.getBoolean(
172 "persist.env.browser.wap2estore", false);
173 if (wap2estore && isEstoreTypeUrl(text)) {
174 url = text;
175 } else {
176 url = UrlUtils.smartUrlFilter(text, false);
177 }
178
John Reck0f602f32011-07-07 15:38:43 -0700179 Tab t = mBaseUi.getActiveTab();
180 // Only shortcut javascript URIs for now, as there is special
181 // logic in UrlHandler for other schemas
182 if (url != null && t != null && url.startsWith("javascript:")) {
183 mUiController.loadUrl(t, url);
184 setDisplayTitle(text);
185 return;
186 }
kaiyizc4ada322013-07-30 09:58:07 +0800187
188 // add for carrier wap2estore feature
189 if (url != null && t != null && wap2estore && isEstoreTypeUrl(url)) {
190 handleEstoreTypeUrl(url);
191 setDisplayTitle(text);
192 return;
193 }
John Reck0f602f32011-07-07 15:38:43 -0700194 }
195 Intent i = new Intent();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700196 String action = Intent.ACTION_SEARCH;
John Reck0f602f32011-07-07 15:38:43 -0700197 i.setAction(action);
198 i.putExtra(SearchManager.QUERY, text);
199 if (extra != null) {
200 i.putExtra(SearchManager.EXTRA_DATA_KEY, extra);
201 }
202 if (source != null) {
203 Bundle appData = new Bundle();
204 appData.putString(com.android.common.Search.SOURCE, source);
205 i.putExtra(SearchManager.APP_DATA, appData);
206 }
207 mUiController.handleNewIntent(i);
208 setDisplayTitle(text);
209 }
210
kaiyizc4ada322013-07-30 09:58:07 +0800211 private boolean isEstoreTypeUrl(String url) {
212 String utf8Url = null;
213 try {
214 utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
215 } catch (UnsupportedEncodingException e) {
216 Log.e(TAG, "err " + e);
217 }
218 if (utf8Url != null && utf8Url.startsWith("estore:")) {
219 return true;
220 }
221 return false;
222 }
223
224 private void handleEstoreTypeUrl(String url) {
225 String utf8Url = null, finalUrl = null;
226 try {
227 utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
228 } catch (UnsupportedEncodingException e) {
229 Log.e(TAG, "err " + e);
230 }
231 if (utf8Url != null) {
232 finalUrl = utf8Url;
233 } else {
234 finalUrl = url;
235 }
236 if (finalUrl.replaceFirst("estore:", "").length() > 256) {
237 Toast.makeText(mContext, R.string.estore_url_warning, Toast.LENGTH_LONG).show();
238 return;
239 }
240 Intent intent = new Intent(Intent.ACTION_VIEW);
241 intent.setData(Uri.parse(finalUrl));
242 try {
243 mContext.startActivity(intent);
244 } catch (ActivityNotFoundException ex) {
245 String downloadUrl = mContext.getResources().getString(R.string.estore_homepage);
246 mUiController.loadUrl(mBaseUi.getActiveTab(), downloadUrl);
247 Toast.makeText(mContext, R.string.download_estore_app, Toast.LENGTH_LONG).show();
248 }
249 }
250
John Reck0f602f32011-07-07 15:38:43 -0700251 @Override
252 public void onDismiss() {
253 final Tab currentTab = mBaseUi.getActiveTab();
254 mBaseUi.hideTitleBar();
255 post(new Runnable() {
256 public void run() {
257 clearFocus();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700258 if (currentTab != null) {
John Reck0f602f32011-07-07 15:38:43 -0700259 setDisplayTitle(currentTab.getUrl());
260 }
261 }
262 });
263 }
264
265 /**
266 * callback from the suggestion dropdown
267 * copy text to input field and stay in edit mode
268 */
269 @Override
270 public void onCopySuggestion(String text) {
271 mUrlInput.setText(text, true);
272 if (text != null) {
273 mUrlInput.setSelection(text.length());
274 }
275 }
276
277 public void setCurrentUrlIsBookmark(boolean isBookmark) {
278 }
279
280 @Override
281 public boolean dispatchKeyEventPreIme(KeyEvent evt) {
282 if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
283 // catch back key in order to do slightly more cleanup than usual
Michael Kolb0b129122012-06-04 16:31:58 -0700284 stopEditingUrl();
John Reck0f602f32011-07-07 15:38:43 -0700285 return true;
286 }
287 return super.dispatchKeyEventPreIme(evt);
288 }
289
John Reck0f602f32011-07-07 15:38:43 -0700290 /**
291 * called from the Ui when the user wants to edit
292 * @param clearInput clear the input field
293 */
Michael Kolb1f9b3562012-04-24 14:38:34 -0700294 void startEditingUrl(boolean clearInput, boolean forceIME) {
John Reck0f602f32011-07-07 15:38:43 -0700295 // editing takes preference of progress
296 setVisibility(View.VISIBLE);
297 if (mTitleBar.useQuickControls()) {
298 mTitleBar.getProgressView().setVisibility(View.GONE);
299 }
300 if (!mUrlInput.hasFocus()) {
301 mUrlInput.requestFocus();
302 }
303 if (clearInput) {
304 mUrlInput.setText("");
John Reck0f602f32011-07-07 15:38:43 -0700305 }
Michael Kolb1f9b3562012-04-24 14:38:34 -0700306 if (forceIME) {
Michael Kolb4bb6fcb2012-04-13 14:25:27 -0700307 mUrlInput.showIME();
308 }
John Reck0f602f32011-07-07 15:38:43 -0700309 }
310
311 public void onProgressStarted() {
312 }
313
314 public void onProgressStopped() {
315 }
316
John Reck58891902011-08-11 17:48:53 -0700317 public boolean isMenuShowing() {
John Reck42229bc2011-08-19 13:26:43 -0700318 return false;
John Reck58891902011-08-11 17:48:53 -0700319 }
320
John Reck419f6b42011-08-16 16:10:51 -0700321 public void onTabDataChanged(Tab tab) {
322 }
323
Michael Kolb0b129122012-06-04 16:31:58 -0700324 public void onVoiceResult(String s) {
325 startEditingUrl(true, true);
326 onCopySuggestion(s);
327 }
328
Narayan Kamathf3174a52011-11-17 14:43:32 +0000329 @Override
330 public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
331
332 @Override
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700333 public void onTextChanged(CharSequence s, int start, int before, int count) { }
Narayan Kamathf3174a52011-11-17 14:43:32 +0000334
335 @Override
336 public void afterTextChanged(Editable s) { }
Michael Kolb0b129122012-06-04 16:31:58 -0700337
John Reck0f602f32011-07-07 15:38:43 -0700338}