blob: 0d980211769c33c6d48262e046a50477b1a331d9 [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 */
Bijan Amirzada41242f22014-03-21 12:12:18 -070016package com.android.browser;
John Reck0f602f32011-07-07 15:38:43 -070017
Pankaj Garg32e1b942015-06-03 18:13:24 -070018import android.animation.ArgbEvaluator;
19import android.animation.ValueAnimator;
Enrico Ros1f5a0952014-11-18 20:15:48 -080020import android.app.Activity;
John Reck0f602f32011-07-07 15:38:43 -070021import android.app.SearchManager;
kaiyizc4ada322013-07-30 09:58:07 +080022import android.content.ActivityNotFoundException;
John Reck0f602f32011-07-07 15:38:43 -070023import android.content.Context;
24import android.content.Intent;
Pankaj Garg32e1b942015-06-03 18:13:24 -070025import android.content.SharedPreferences;
John Reck0f602f32011-07-07 15:38:43 -070026import android.graphics.Bitmap;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070027import android.graphics.BitmapFactory;
Pankaj Garg32e1b942015-06-03 18:13:24 -070028import android.graphics.Color;
kaiyizc4ada322013-07-30 09:58:07 +080029import android.net.Uri;
Pankaj Garg32e1b942015-06-03 18:13:24 -070030import android.net.http.SslCertificate;
31import android.net.http.SslError;
32import android.os.Build;
John Reck0f602f32011-07-07 15:38:43 -070033import android.os.Bundle;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070034import android.os.Handler;
35import android.os.Message;
Narayan Kamathf3174a52011-11-17 14:43:32 +000036import android.text.Editable;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070037import android.text.TextUtils;
Narayan Kamathf3174a52011-11-17 14:43:32 +000038import android.text.TextWatcher;
John Reck0f602f32011-07-07 15:38:43 -070039import android.util.AttributeSet;
kaiyizc4ada322013-07-30 09:58:07 +080040import android.util.Log;
John Reck0f602f32011-07-07 15:38:43 -070041import android.view.KeyEvent;
Enrico Ros1f5a0952014-11-18 20:15:48 -080042import android.view.Menu;
43import android.view.MenuItem;
John Reck0f602f32011-07-07 15:38:43 -070044import android.view.View;
45import android.view.View.OnClickListener;
46import android.view.View.OnFocusChangeListener;
Enrico Ros1f5a0952014-11-18 20:15:48 -080047import android.view.ViewConfiguration;
John Reck0f602f32011-07-07 15:38:43 -070048import android.widget.ImageView;
49import android.widget.LinearLayout;
Enrico Ros1f5a0952014-11-18 20:15:48 -080050import android.widget.PopupMenu;
kaiyizc4ada322013-07-30 09:58:07 +080051import android.widget.Toast;
John Reck0f602f32011-07-07 15:38:43 -070052
Bijan Amirzada41242f22014-03-21 12:12:18 -070053import com.android.browser.UrlInputView.UrlInputListener;
Pankaj Garg32e1b942015-06-03 18:13:24 -070054import com.android.browser.preferences.SiteSpecificPreferencesFragment;
John Reck0f602f32011-07-07 15:38:43 -070055
Pankaj Garg32e1b942015-06-03 18:13:24 -070056import java.io.ByteArrayOutputStream;
kaiyizc4ada322013-07-30 09:58:07 +080057import java.io.UnsupportedEncodingException;
Pankaj Garg32e1b942015-06-03 18:13:24 -070058import java.net.MalformedURLException;
kaiyiz950eca22013-08-08 11:01:28 +080059import java.net.URISyntaxException;
Pankaj Garg32e1b942015-06-03 18:13:24 -070060import java.net.URL;
kaiyizc4ada322013-07-30 09:58:07 +080061
Dany Rybnikovbcd37da2015-04-20 11:43:15 +030062import org.codeaurora.net.NetworkServices;
Kevin Hart055e6d82014-12-19 15:53:19 -080063import org.codeaurora.swe.Engine;
Pankaj Garg32e1b942015-06-03 18:13:24 -070064import org.codeaurora.swe.WebRefiner;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080065import org.codeaurora.swe.WebView;
Pankaj Garg32e1b942015-06-03 18:13:24 -070066import org.codeaurora.swe.util.ColorUtils;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080067
John Reck42229bc2011-08-19 13:26:43 -070068public class NavigationBarBase extends LinearLayout implements
69 OnClickListener, UrlInputListener, OnFocusChangeListener,
Enrico Ros1f5a0952014-11-18 20:15:48 -080070 TextWatcher, UrlInputView.StateListener,
71 PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
John Reck0f602f32011-07-07 15:38:43 -070072
kaiyizc4ada322013-07-30 09:58:07 +080073 private final static String TAG = "NavigationBarBase";
74
John Reck0f602f32011-07-07 15:38:43 -070075 protected BaseUi mBaseUi;
76 protected TitleBar mTitleBar;
77 protected UiController mUiController;
78 protected UrlInputView mUrlInput;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070079 protected ImageView mStopButton;
John Reck0f602f32011-07-07 15:38:43 -070080
Pankaj Garg66f8cef2015-07-07 17:29:03 -070081 private SiteTileView mFaviconTile;
82 private ImageView mMagnify;
83 private View mVoiceButton;
84 private ImageView mClearButton;
Enrico Ros1f5a0952014-11-18 20:15:48 -080085 private View mMore;
86 private PopupMenu mPopupMenu;
87 private boolean mOverflowMenuShowing;
88 private boolean mNeedsMenu;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070089
Pankaj Garg66f8cef2015-07-07 17:29:03 -070090 private static Bitmap mDefaultFavicon;
91
Pankaj Garg32e1b942015-06-03 18:13:24 -070092 private int mStatusBarColor;
93 private static int mDefaultStatusBarColor = -1;
94
Pankaj Garg66f8cef2015-07-07 17:29:03 -070095 private static final int WEBREFINER_COUNTER_MSG = 4242;
96 private static final int WEBREFINER_COUNTER_MSG_DELAY = 3000;
97 private Handler mHandler;
98
Pankaj Garg32e1b942015-06-03 18:13:24 -070099 private Tab.SecurityState mSecurityState = Tab.SecurityState.SECURITY_STATE_NOT_SECURE;
100
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700101 private static final String noSitePrefs[] = {
102 "chrome://",
103 "about:",
104 "content:",
105 };
106
John Reck0f602f32011-07-07 15:38:43 -0700107 public NavigationBarBase(Context context) {
108 super(context);
109 }
110
111 public NavigationBarBase(Context context, AttributeSet attrs) {
112 super(context, attrs);
113 }
114
115 public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) {
116 super(context, attrs, defStyle);
117 }
118
119 @Override
120 protected void onFinishInflate() {
121 super.onFinishInflate();
John Reck0f602f32011-07-07 15:38:43 -0700122 mUrlInput = (UrlInputView) findViewById(R.id.url);
123 mUrlInput.setUrlInputListener(this);
John Reck0f602f32011-07-07 15:38:43 -0700124 mUrlInput.setOnFocusChangeListener(this);
125 mUrlInput.setSelectAllOnFocus(true);
Narayan Kamathf3174a52011-11-17 14:43:32 +0000126 mUrlInput.addTextChangedListener(this);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800127 mMore = findViewById(R.id.more_browser_settings);
128 mMore.setOnClickListener(this);
129 mNeedsMenu = !ViewConfiguration.get(getContext()).hasPermanentMenuKey();
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700130 mMagnify = (ImageView) findViewById(R.id.magnify);
131 mMagnify.setOnClickListener(this);
132 mFaviconTile = (SiteTileView) findViewById(R.id.favicon_view);
133 mFaviconTile.setOnClickListener(this);
134 mVoiceButton = findViewById(R.id.voice);
135 mVoiceButton.setOnClickListener(this);
136 mClearButton = (ImageView) findViewById(R.id.clear);
137 mClearButton.setOnClickListener(this);
138 mStopButton = (ImageView) findViewById(R.id.stop);
139 mStopButton.setOnClickListener(this);
140
141 mDefaultFavicon = BitmapFactory.decodeResource(getResources(),
142 R.drawable.ic_deco_favicon_normal);
143
144 mHandler = new Handler() {
145 @Override
146 public void handleMessage(Message m) {
147 switch (m.what) {
148 case WEBREFINER_COUNTER_MSG:
149 WebView wv = mUiController.getCurrentTopWebView();
150 if (wv != null && WebRefiner.isInitialized()) {
151 int count = WebRefiner.getInstance().getBlockedURLCount(wv);
152 if (count > 0) {
153 mFaviconTile.setExtraBlockedObjectsCount(count);
154 }
155 }
156 mHandler.sendEmptyMessageDelayed(WEBREFINER_COUNTER_MSG,
157 WEBREFINER_COUNTER_MSG_DELAY);
158 break;
159 }
160 }
161 };
John Reck0f602f32011-07-07 15:38:43 -0700162 }
163
164 public void setTitleBar(TitleBar titleBar) {
165 mTitleBar = titleBar;
166 mBaseUi = mTitleBar.getUi();
167 mUiController = mTitleBar.getUiController();
Michael Kolbb2e91fd2011-07-14 13:47:29 -0700168 mUrlInput.setController(mUiController);
John Reck0f602f32011-07-07 15:38:43 -0700169 }
170
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700171 public void setSecurityState(Tab.SecurityState securityState) {
Pankaj Garg32e1b942015-06-03 18:13:24 -0700172 mSecurityState = securityState;
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700173 switch (mSecurityState) {
174 case SECURITY_STATE_SECURE:
175 mFaviconTile.setTrustLevel(SiteTileView.TRUST_TRUSTED);
176 break;
177 case SECURITY_STATE_MIXED:
178 mFaviconTile.setTrustLevel(SiteTileView.TRUST_UNTRUSTED);
179 break;
180 case SECURITY_STATE_BAD_CERTIFICATE:
181 mFaviconTile.setTrustLevel(SiteTileView.TRUST_AVOID);
182 break;
183 case SECURITY_STATE_NOT_SECURE:
184 default:
185 mFaviconTile.setTrustLevel(SiteTileView.TRUST_UNKNOWN);
John Reck0f602f32011-07-07 15:38:43 -0700186 }
187 }
188
Pankaj Garg32e1b942015-06-03 18:13:24 -0700189 public static int adjustColor(int color, float hueMultiplier,
190 float saturationMultiplier, float valueMultiplier) {
191 float[] hsv = new float[3];
192 Color.colorToHSV(color, hsv);
193 hsv[0] *= hueMultiplier;
194 hsv[1] *= saturationMultiplier;
195 hsv[2] *= valueMultiplier;
196 return Color.HSVToColor(Color.alpha(color), hsv);
197 }
198
199 public static void setStatusAndNavigationBarColor(final Activity activity, int color) {
200 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
201 int currentColor = activity.getWindow().getStatusBarColor();
202 Integer from = currentColor;
203 Integer to = color;
204 ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
205
206 if (mDefaultStatusBarColor == -1) {
207 mDefaultStatusBarColor = activity.getWindow().getStatusBarColor();
208 }
209
210 animator.addUpdateListener(
211 new ValueAnimator.AnimatorUpdateListener() {
212 @Override
213 public void onAnimationUpdate(ValueAnimator animation) {
214 Integer value = (Integer) animation.getAnimatedValue();
215 activity.getWindow().setStatusBarColor(value.intValue());
216 //activity.getWindow().setNavigationBarColor(value.intValue());
217 }
218 }
219 );
220 animator.start();
221 }
222 }
223
224 private void updateSiteIconColor(String urlString, int color) {
225 try {
226 URL url = new URL(urlString);
227 String host = url.getHost();
228 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
229 int currentColor = prefs.getInt(host + ":color", 0);
230 if (currentColor != color) {
231 SharedPreferences.Editor editor = prefs.edit();
232 editor.remove(host + ":color");
233 editor.putInt(host + ":color", color);
234 editor.commit();
235 }
236 } catch (MalformedURLException e) {
237 }
238 }
239
240 public static int getSiteIconColor(String urlString) {
241 try {
242 URL url = new URL(urlString);
243 String host = url.getHost();
244 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
245 return prefs.getInt(host + ":color", 0);
246 } catch (MalformedURLException e) {
247 return 0;
248 }
249 }
250
251 public static int getDefaultStatusBarColor() {
252 return mDefaultStatusBarColor;
253 }
254
John Reck0f602f32011-07-07 15:38:43 -0700255 public void setFavicon(Bitmap icon) {
Pankaj Garg32e1b942015-06-03 18:13:24 -0700256 int color = ColorUtils.getDominantColorForBitmap(icon);
257 Tab tab = mUiController.getCurrentTab();
258
259 if (tab != null) {
260 if (tab.hasFavicon()) {
261 updateSiteIconColor(tab.getUrl(), color);
262 setStatusAndNavigationBarColor(mUiController.getActivity(),
263 adjustColor(color, 1, 1, 0.7f));
264 } else {
265 color = getSiteIconColor(tab.getUrl());
266 if (color != 0) {
267 setStatusAndNavigationBarColor(mUiController.getActivity(),
268 adjustColor(color, 1, 1, 0.7f));
269 } else {
270 setStatusAndNavigationBarColor(mUiController.getActivity(),
271 mDefaultStatusBarColor);
272 }
273 }
274 } else {
275 setStatusAndNavigationBarColor(mUiController.getActivity(), mDefaultStatusBarColor);
276 }
277
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700278 //Bitmap favicon = mUiController.getCurrentTopWebView().getFavicon();
279
280 if (mFaviconTile != null) {
281 mFaviconTile.replaceFavicon(mUiController.getCurrentTopWebView().getFavicon());
282 }
John Reck0f602f32011-07-07 15:38:43 -0700283 }
284
Pankaj Garg32e1b942015-06-03 18:13:24 -0700285 protected void showSiteSpecificSettings() {
286 WebView wv = mUiController.getCurrentTopWebView();
287 int count = 0;
288
289 if (wv != null && WebRefiner.getInstance() != null) {
290 count = WebRefiner.getInstance().getBlockedURLCount(wv);
291 }
292
293 Bundle bundle = new Bundle();
294 bundle.putCharSequence(SiteSpecificPreferencesFragment.EXTRA_SITE,
295 mUiController.getCurrentTab().getUrl());
296 bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_WEB_REFINER_INFO, count);
297
298 bundle.putParcelable(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT,
299 SslCertificate.saveState(wv.getCertificate()));
300
301 SslError error = mUiController.getCurrentTab().getSslCertificateError();
302 if (error != null) {
303 int certError = 0;
304 if (error.hasError(SslError.SSL_DATE_INVALID)) {
305 certError |= (1 << SslError.SSL_DATE_INVALID);
306 }
307
308 if (error.hasError(SslError.SSL_EXPIRED)) {
309 certError |= (1 << SslError.SSL_EXPIRED);
310 }
311
312 if (error.hasError(SslError.SSL_IDMISMATCH)) {
313 certError |= (1 << SslError.SSL_IDMISMATCH);
314 }
315
316 if (error.hasError(SslError.SSL_INVALID)) {
317 certError |= (1 << SslError.SSL_INVALID);
318 }
319
320 if (error.hasError(SslError.SSL_NOTYETVALID)) {
321 certError |= (1 << SslError.SSL_NOTYETVALID);
322 }
323
324 if (error.hasError(SslError.SSL_UNTRUSTED)) {
325 certError |= (1 << SslError.SSL_UNTRUSTED);
326 }
327
328 bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT_ERR, certError);
329 }
330
Pankaj Garg68faf1c2015-06-26 17:07:37 -0700331 Bitmap favicon = mUiController.getCurrentTopWebView().getFavicon();
Pankaj Garg32e1b942015-06-03 18:13:24 -0700332 if (favicon != null) {
333 ByteArrayOutputStream baos = new ByteArrayOutputStream();
334 favicon.compress(Bitmap.CompressFormat.PNG, 50, baos);
335 bundle.putByteArray(SiteSpecificPreferencesFragment.EXTRA_FAVICON,
336 baos.toByteArray());
337 }
338 BrowserPreferencesPage.startPreferenceFragmentExtraForResult(
339 mUiController.getActivity(),
340 SiteSpecificPreferencesFragment.class.getName(), bundle, 0);
341 }
342
John Reck0f602f32011-07-07 15:38:43 -0700343 @Override
344 public void onClick(View v) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700345 Tab currentTab = mUiController.getCurrentTab();
346 String url = null;
347 if (currentTab != null){
348 url = currentTab.getUrl();
349 }
Enrico Ros1f5a0952014-11-18 20:15:48 -0800350 if (mMore == v) {
351 showMenu(mMore);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700352 } else if (mFaviconTile == v) {
353 if (urlHasSitePrefs(url)){
354 showSiteSpecificSettings();
355 }
356 } else if (mMagnify == v) {
357 startEditingUrl(true, true);
358 } else if (mVoiceButton == v) {
359 mUiController.startVoiceRecognizer();
360 } else if (mStopButton == v) {
361 stopOrRefresh();
362 } else if (mClearButton == v) {
363 clearOrClose();
364 mUrlInput.setText("");
365 }
366 }
367
368 private static boolean urlHasSitePrefs(String url) {
369 if (TextUtils.isEmpty(url)) {
370 return false;
371 }
372
373 for (int i = 0; i < noSitePrefs.length; i++) {
374 if (url.startsWith(noSitePrefs[i])) {
375 return false;
376 }
377 }
378 return true;
379 }
380
381 private void stopOrRefresh() {
382 if (mUiController == null) return;
383 if (mTitleBar.isInLoad()) {
384 mUiController.stopLoading();
385 } else {
386 if (mUiController.getCurrentTopWebView() != null) {
387 stopEditingUrl();
388 mUiController.getCurrentTopWebView().reload();
389 }
390 }
391 }
392
393 private void clearOrClose() {
394 if (TextUtils.isEmpty(mUrlInput.getText())) {
395 // close
396 mUrlInput.clearFocus();
397 } else {
398 // clear
399 mUrlInput.setText("");
Enrico Ros1f5a0952014-11-18 20:15:48 -0800400 }
401 }
402
403 void showMenu(View anchor) {
404 Activity activity = mUiController.getActivity();
405 if (mPopupMenu == null) {
406 mPopupMenu = new PopupMenu(getContext(), anchor);
407 mPopupMenu.setOnMenuItemClickListener(this);
408 mPopupMenu.setOnDismissListener(this);
409 if (!activity.onCreateOptionsMenu(mPopupMenu.getMenu())) {
410 mPopupMenu = null;
411 return;
412 }
413 }
414 Menu menu = mPopupMenu.getMenu();
415
416 if (mUiController instanceof Controller) {
417 Controller controller = (Controller) mUiController;
418 if (controller.onPrepareOptionsMenu(menu)) {
419 mOverflowMenuShowing = true;
420 }
421 }
John Reck0f602f32011-07-07 15:38:43 -0700422 }
423
424 @Override
425 public void onFocusChange(View view, boolean hasFocus) {
426 // if losing focus and not in touch mode, leave as is
427 if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) {
428 setFocusState(hasFocus);
429 }
430 if (hasFocus) {
Kevin Hart055e6d82014-12-19 15:53:19 -0800431 Engine.warmUpChildProcessAsync(mUiController.getActivity().getApplicationContext());
John Reck0f602f32011-07-07 15:38:43 -0700432 mBaseUi.showTitleBar();
Dany Rybnikovbcd37da2015-04-20 11:43:15 +0300433 if (!BrowserSettings.getInstance().isPowerSaveModeEnabled()) {
434 //Notify about anticipated network activity
435 NetworkServices.hintUpcomingUserActivity();
436 }
John Reck0f602f32011-07-07 15:38:43 -0700437 } else if (!mUrlInput.needsUpdate()) {
438 mUrlInput.dismissDropDown();
439 mUrlInput.hideIME();
440 if (mUrlInput.getText().length() == 0) {
441 Tab currentTab = mUiController.getTabControl().getCurrentTab();
442 if (currentTab != null) {
John Reck434e9f82011-08-10 18:16:52 -0700443 setDisplayTitle(currentTab.getUrl());
John Reck0f602f32011-07-07 15:38:43 -0700444 }
445 }
446 mBaseUi.suggestHideTitleBar();
447 }
448 mUrlInput.clearNeedsUpdate();
449 }
450
451 protected void setFocusState(boolean focus) {
452 }
453
John Reck0f602f32011-07-07 15:38:43 -0700454 public boolean isEditingUrl() {
455 return mUrlInput.hasFocus();
456 }
457
458 void stopEditingUrl() {
Michael Kolb0b129122012-06-04 16:31:58 -0700459 WebView currentTopWebView = mUiController.getCurrentTopWebView();
460 if (currentTopWebView != null) {
461 currentTopWebView.requestFocus();
462 }
John Reck0f602f32011-07-07 15:38:43 -0700463 }
464
465 void setDisplayTitle(String title) {
466 if (!isEditingUrl()) {
Michael Kolb29aab402012-05-29 17:22:35 -0700467 if (!title.equals(mUrlInput.getText().toString())) {
468 mUrlInput.setText(title, false);
469 }
John Reck0f602f32011-07-07 15:38:43 -0700470 }
471 }
472
John Reck0f602f32011-07-07 15:38:43 -0700473 void setIncognitoMode(boolean incognito) {
474 mUrlInput.setIncognitoMode(incognito);
475 }
476
477 void clearCompletions() {
Narayan Kamathf3174a52011-11-17 14:43:32 +0000478 mUrlInput.dismissDropDown();
John Reck0f602f32011-07-07 15:38:43 -0700479 }
480
481 // UrlInputListener implementation
482
483 /**
484 * callback from suggestion dropdown
485 * user selected a suggestion
486 */
487 @Override
488 public void onAction(String text, String extra, String source) {
Michael Kolb0b129122012-06-04 16:31:58 -0700489 stopEditingUrl();
John Reck0f602f32011-07-07 15:38:43 -0700490 if (UrlInputView.TYPED.equals(source)) {
kaiyizc4ada322013-07-30 09:58:07 +0800491 String url = null;
Panos Thomas4bdb5252014-11-13 16:20:11 -0800492 boolean wap2estore = BrowserConfig.getInstance(getContext())
493 .hasFeature(BrowserConfig.Feature.WAP2ESTORE);
Vivek Sekhar5e631472014-03-31 23:59:10 -0700494 if ((wap2estore && isEstoreTypeUrl(text)) || isRtspTypeUrl(text)
495 || isMakeCallTypeUrl(text)) {
kaiyizc4ada322013-07-30 09:58:07 +0800496 url = text;
497 } else {
498 url = UrlUtils.smartUrlFilter(text, false);
499 }
500
John Reck0f602f32011-07-07 15:38:43 -0700501 Tab t = mBaseUi.getActiveTab();
502 // Only shortcut javascript URIs for now, as there is special
503 // logic in UrlHandler for other schemas
504 if (url != null && t != null && url.startsWith("javascript:")) {
505 mUiController.loadUrl(t, url);
506 setDisplayTitle(text);
507 return;
508 }
kaiyizc4ada322013-07-30 09:58:07 +0800509
510 // add for carrier wap2estore feature
511 if (url != null && t != null && wap2estore && isEstoreTypeUrl(url)) {
Vivek Sekharb54614f2014-05-01 19:03:37 -0700512 if (handleEstoreTypeUrl(url)) {
513 setDisplayTitle(text);
514 return;
515 }
kaiyizc4ada322013-07-30 09:58:07 +0800516 }
kaiyiz950eca22013-08-08 11:01:28 +0800517 // add for rtsp scheme feature
518 if (url != null && t != null && isRtspTypeUrl(url)) {
519 if (handleRtspTypeUrl(url)) {
Vivek Sekharb54614f2014-05-01 19:03:37 -0700520 setDisplayTitle(text);
kaiyiz950eca22013-08-08 11:01:28 +0800521 return;
522 }
523 }
Vivek Sekhar5e631472014-03-31 23:59:10 -0700524 // add for "wtai://wp/mc;" scheme feature
525 if (url != null && t != null && isMakeCallTypeUrl(url)) {
526 if (handleMakeCallTypeUrl(url)) {
527 return;
528 }
529 }
John Reck0f602f32011-07-07 15:38:43 -0700530 }
531 Intent i = new Intent();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700532 String action = Intent.ACTION_SEARCH;
John Reck0f602f32011-07-07 15:38:43 -0700533 i.setAction(action);
534 i.putExtra(SearchManager.QUERY, text);
535 if (extra != null) {
536 i.putExtra(SearchManager.EXTRA_DATA_KEY, extra);
537 }
538 if (source != null) {
539 Bundle appData = new Bundle();
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800540 appData.putString("source", source);
541 i.putExtra("source", appData);
John Reck0f602f32011-07-07 15:38:43 -0700542 }
543 mUiController.handleNewIntent(i);
544 setDisplayTitle(text);
545 }
546
Vivek Sekhar5e631472014-03-31 23:59:10 -0700547 private boolean isMakeCallTypeUrl(String url) {
548 String utf8Url = null;
549 try {
550 utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
551 } catch (UnsupportedEncodingException e) {
552 Log.e(TAG, "err " + e);
553 }
554 if (utf8Url != null && utf8Url.startsWith(UrlHandler.SCHEME_WTAI_MC)) {
555 return true;
556 }
557 return false;
558 }
559
560 private boolean handleMakeCallTypeUrl(String url) {
561 // wtai://wp/mc;number
562 // number=string(phone-number)
563 if (url.startsWith(UrlHandler.SCHEME_WTAI_MC)) {
564 Intent intent = new Intent(Intent.ACTION_VIEW,
565 Uri.parse(WebView.SCHEME_TEL +
566 url.substring(UrlHandler.SCHEME_WTAI_MC.length())));
567 getContext().startActivity(intent);
568 // before leaving BrowserActivity, close the empty child tab.
569 // If a new tab is created through JavaScript open to load this
570 // url, we would like to close it as we will load this url in a
571 // different Activity.
572 Tab current = mUiController.getCurrentTab();
573 if (current != null
574 && current.getWebView().copyBackForwardList().getSize() == 0) {
575 mUiController.closeCurrentTab();
576 }
577 return true;
578 }
579 return false;
580 }
581
kaiyizc4ada322013-07-30 09:58:07 +0800582 private boolean isEstoreTypeUrl(String url) {
Vivek Sekharb54614f2014-05-01 19:03:37 -0700583 if (url != null && url.startsWith("estore:")) {
kaiyizc4ada322013-07-30 09:58:07 +0800584 return true;
585 }
586 return false;
587 }
588
Vivek Sekharb54614f2014-05-01 19:03:37 -0700589 private boolean handleEstoreTypeUrl(String url) {
590 if (url.getBytes().length > 256) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800591 Toast.makeText(getContext(), R.string.estore_url_warning, Toast.LENGTH_LONG).show();
Vivek Sekharb54614f2014-05-01 19:03:37 -0700592 return false;
kaiyizc4ada322013-07-30 09:58:07 +0800593 }
Vivek Sekharb54614f2014-05-01 19:03:37 -0700594
595 Intent intent;
596 // perform generic parsing of the URI to turn it into an Intent.
597 try {
598 intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
599 } catch (URISyntaxException ex) {
600 Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
601 return false;
602 }
603
kaiyizc4ada322013-07-30 09:58:07 +0800604 try {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800605 getContext().startActivity(intent);
kaiyizc4ada322013-07-30 09:58:07 +0800606 } catch (ActivityNotFoundException ex) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800607 String downloadUrl = getContext().getResources().getString(R.string.estore_homepage);
kaiyizc4ada322013-07-30 09:58:07 +0800608 mUiController.loadUrl(mBaseUi.getActiveTab(), downloadUrl);
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800609 Toast.makeText(getContext(), R.string.download_estore_app, Toast.LENGTH_LONG).show();
kaiyizc4ada322013-07-30 09:58:07 +0800610 }
Vivek Sekharb54614f2014-05-01 19:03:37 -0700611
612 return true;
kaiyizc4ada322013-07-30 09:58:07 +0800613 }
614
kaiyiz950eca22013-08-08 11:01:28 +0800615 private boolean isRtspTypeUrl(String url) {
616 String utf8Url = null;
617 try {
618 utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
619 } catch (UnsupportedEncodingException e) {
620 Log.e(TAG, "err " + e);
621 }
622 if (utf8Url != null && utf8Url.startsWith("rtsp://")) {
623 return true;
624 }
625 return false;
626 }
627
628 private boolean handleRtspTypeUrl(String url) {
629 Intent intent;
630 // perform generic parsing of the URI to turn it into an Intent.
631 try {
632 intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
633 } catch (URISyntaxException ex) {
634 Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
635 return false;
636 }
637
638 try {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800639 getContext().startActivity(intent);
kaiyiz950eca22013-08-08 11:01:28 +0800640 } catch (ActivityNotFoundException ex) {
641 Log.w("Browser", "No resolveActivity " + url);
642 return false;
643 }
644 return true;
645 }
646
John Reck0f602f32011-07-07 15:38:43 -0700647 @Override
648 public void onDismiss() {
649 final Tab currentTab = mBaseUi.getActiveTab();
650 mBaseUi.hideTitleBar();
651 post(new Runnable() {
652 public void run() {
653 clearFocus();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700654 if (currentTab != null) {
John Reck0f602f32011-07-07 15:38:43 -0700655 setDisplayTitle(currentTab.getUrl());
656 }
657 }
658 });
659 }
660
661 /**
662 * callback from the suggestion dropdown
663 * copy text to input field and stay in edit mode
664 */
665 @Override
666 public void onCopySuggestion(String text) {
667 mUrlInput.setText(text, true);
668 if (text != null) {
669 mUrlInput.setSelection(text.length());
670 }
671 }
672
673 public void setCurrentUrlIsBookmark(boolean isBookmark) {
674 }
675
676 @Override
677 public boolean dispatchKeyEventPreIme(KeyEvent evt) {
678 if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
679 // catch back key in order to do slightly more cleanup than usual
Michael Kolb0b129122012-06-04 16:31:58 -0700680 stopEditingUrl();
John Reck0f602f32011-07-07 15:38:43 -0700681 }
682 return super.dispatchKeyEventPreIme(evt);
683 }
684
John Reck0f602f32011-07-07 15:38:43 -0700685 /**
686 * called from the Ui when the user wants to edit
687 * @param clearInput clear the input field
688 */
Michael Kolb1f9b3562012-04-24 14:38:34 -0700689 void startEditingUrl(boolean clearInput, boolean forceIME) {
John Reck0f602f32011-07-07 15:38:43 -0700690 // editing takes preference of progress
691 setVisibility(View.VISIBLE);
John Reck0f602f32011-07-07 15:38:43 -0700692 if (!mUrlInput.hasFocus()) {
693 mUrlInput.requestFocus();
694 }
695 if (clearInput) {
696 mUrlInput.setText("");
John Reck0f602f32011-07-07 15:38:43 -0700697 }
Michael Kolb1f9b3562012-04-24 14:38:34 -0700698 if (forceIME) {
Michael Kolb4bb6fcb2012-04-13 14:25:27 -0700699 mUrlInput.showIME();
700 }
John Reck0f602f32011-07-07 15:38:43 -0700701 }
702
703 public void onProgressStarted() {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700704 mFaviconTile.setExtraBlockedObjectsCount(0);
705 mFaviconTile.setTrustLevel(SiteTileView.TRUST_UNKNOWN);
706 mFaviconTile.replaceFavicon(mDefaultFavicon);
Pankaj Garg32e1b942015-06-03 18:13:24 -0700707 mSecurityState = Tab.SecurityState.SECURITY_STATE_NOT_SECURE;
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700708 mHandler.removeMessages(WEBREFINER_COUNTER_MSG);
709 mHandler.sendEmptyMessageDelayed(WEBREFINER_COUNTER_MSG,
710 WEBREFINER_COUNTER_MSG_DELAY);
711 mStopButton.setImageResource(R.drawable.ic_action_stop);
712 mStopButton.setContentDescription(getResources().
713 getString(R.string.accessibility_button_stop));
John Reck0f602f32011-07-07 15:38:43 -0700714 }
715
716 public void onProgressStopped() {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700717 if (!isEditingUrl()) {
718 mFaviconTile.setVisibility(View.VISIBLE);
719 }
720 mStopButton.setImageResource(R.drawable.ic_action_reload);
721 mStopButton.setContentDescription(getResources().
722 getString(R.string.accessibility_button_refresh));
John Reck0f602f32011-07-07 15:38:43 -0700723 }
724
John Reck419f6b42011-08-16 16:10:51 -0700725 public void onTabDataChanged(Tab tab) {
726 }
727
Michael Kolb0b129122012-06-04 16:31:58 -0700728 public void onVoiceResult(String s) {
729 startEditingUrl(true, true);
730 onCopySuggestion(s);
731 }
732
Narayan Kamathf3174a52011-11-17 14:43:32 +0000733 @Override
734 public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
735
736 @Override
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700737 public void onTextChanged(CharSequence s, int start, int before, int count) { }
Narayan Kamathf3174a52011-11-17 14:43:32 +0000738
739 @Override
740 public void afterTextChanged(Editable s) { }
Michael Kolb0b129122012-06-04 16:31:58 -0700741
Enrico Ros1f5a0952014-11-18 20:15:48 -0800742 @Override
743 public void onStateChanged(int state) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700744 mVoiceButton.setVisibility(View.GONE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800745 switch(state) {
746 case STATE_NORMAL:
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700747 mFaviconTile.setVisibility(View.VISIBLE);
748 mMagnify.setVisibility(View.GONE);
749 mClearButton.setVisibility(View.GONE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800750 mMore.setVisibility(mNeedsMenu ? View.VISIBLE : View.GONE);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700751 if (mUiController != null) {
752 Tab currentTab = mUiController.getCurrentTab();
753 if (currentTab != null){
754 if (TextUtils.isEmpty(currentTab.getUrl())) {
755 mFaviconTile.setVisibility(View.GONE);
756 mMagnify.setVisibility(View.VISIBLE);
757 }
758 }
759 mUiController.setWindowDimming(0.0f);
760 }
761
Enrico Ros1f5a0952014-11-18 20:15:48 -0800762 break;
763 case STATE_HIGHLIGHTED:
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700764 mFaviconTile.setVisibility(View.GONE);
765 mMagnify.setVisibility(View.GONE);
766 mClearButton.setVisibility(View.GONE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800767 mMore.setVisibility(View.GONE);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700768 if (mUiController != null) {
769 mUiController.setWindowDimming(0.75f);
770 if (mUiController.supportsVoice()) {
771 mVoiceButton.setVisibility(View.VISIBLE);
772 }
773 }
Enrico Ros1f5a0952014-11-18 20:15:48 -0800774 break;
775 case STATE_EDITED:
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700776 mFaviconTile.setVisibility(View.GONE);
777 mMagnify.setVisibility(View.VISIBLE);
778 mClearButton.setVisibility(View.VISIBLE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800779 mMore.setVisibility(View.GONE);
780 break;
781 }
782 }
783
784 public boolean isMenuShowing() {
785 return mOverflowMenuShowing;
786 }
787
788
789 @Override
790 public void onDismiss(PopupMenu popupMenu) {
791 if (popupMenu == mPopupMenu) {
792 onMenuHidden();
793 }
794 }
795
796 private void onMenuHidden() {
797 mOverflowMenuShowing = false;
798 mBaseUi.showTitleBarForDuration();
799 }
800
801
802 @Override
803 public boolean onMenuItemClick(MenuItem item) {
804 return mUiController.onOptionsItemSelected(item);
805 }
John Reck0f602f32011-07-07 15:38:43 -0700806}