blob: fd8869d02ff580adfa9fd50e429517c332dee4ce [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;
Pankaj Garg32e1b942015-06-03 18:13:24 -070031import android.os.Build;
John Reck0f602f32011-07-07 15:38:43 -070032import android.os.Bundle;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070033import android.os.Handler;
34import android.os.Message;
Narayan Kamathf3174a52011-11-17 14:43:32 +000035import android.text.Editable;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070036import android.text.TextUtils;
Narayan Kamathf3174a52011-11-17 14:43:32 +000037import android.text.TextWatcher;
John Reck0f602f32011-07-07 15:38:43 -070038import android.util.AttributeSet;
kaiyizc4ada322013-07-30 09:58:07 +080039import android.util.Log;
John Reck0f602f32011-07-07 15:38:43 -070040import android.view.KeyEvent;
Enrico Ros1f5a0952014-11-18 20:15:48 -080041import android.view.Menu;
42import android.view.MenuItem;
John Reck0f602f32011-07-07 15:38:43 -070043import android.view.View;
44import android.view.View.OnClickListener;
45import android.view.View.OnFocusChangeListener;
John Reck0f602f32011-07-07 15:38:43 -070046import android.widget.ImageView;
47import android.widget.LinearLayout;
Enrico Ros1f5a0952014-11-18 20:15:48 -080048import android.widget.PopupMenu;
kaiyizc4ada322013-07-30 09:58:07 +080049import android.widget.Toast;
John Reck0f602f32011-07-07 15:38:43 -070050
Bijan Amirzada41242f22014-03-21 12:12:18 -070051import com.android.browser.UrlInputView.UrlInputListener;
Pankaj Garg32e1b942015-06-03 18:13:24 -070052import com.android.browser.preferences.SiteSpecificPreferencesFragment;
John Reck0f602f32011-07-07 15:38:43 -070053
Pankaj Garg32e1b942015-06-03 18:13:24 -070054import java.io.ByteArrayOutputStream;
kaiyizc4ada322013-07-30 09:58:07 +080055import java.io.UnsupportedEncodingException;
Pankaj Garg32e1b942015-06-03 18:13:24 -070056import java.net.MalformedURLException;
kaiyiz950eca22013-08-08 11:01:28 +080057import java.net.URISyntaxException;
Pankaj Garg32e1b942015-06-03 18:13:24 -070058import java.net.URL;
kaiyizc4ada322013-07-30 09:58:07 +080059
Dany Rybnikovbcd37da2015-04-20 11:43:15 +030060import org.codeaurora.net.NetworkServices;
Pankaj Garg32e1b942015-06-03 18:13:24 -070061import org.codeaurora.swe.WebRefiner;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080062import org.codeaurora.swe.WebView;
Pankaj Garg32e1b942015-06-03 18:13:24 -070063import org.codeaurora.swe.util.ColorUtils;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080064
John Reck42229bc2011-08-19 13:26:43 -070065public class NavigationBarBase extends LinearLayout implements
66 OnClickListener, UrlInputListener, OnFocusChangeListener,
Enrico Ros1f5a0952014-11-18 20:15:48 -080067 TextWatcher, UrlInputView.StateListener,
68 PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
John Reck0f602f32011-07-07 15:38:43 -070069
kaiyizc4ada322013-07-30 09:58:07 +080070 private final static String TAG = "NavigationBarBase";
71
John Reck0f602f32011-07-07 15:38:43 -070072 protected BaseUi mBaseUi;
73 protected TitleBar mTitleBar;
74 protected UiController mUiController;
75 protected UrlInputView mUrlInput;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070076 protected ImageView mStopButton;
John Reck0f602f32011-07-07 15:38:43 -070077
Pankaj Garg66f8cef2015-07-07 17:29:03 -070078 private SiteTileView mFaviconTile;
79 private ImageView mMagnify;
80 private View mVoiceButton;
81 private ImageView mClearButton;
Enrico Ros1f5a0952014-11-18 20:15:48 -080082 private View mMore;
83 private PopupMenu mPopupMenu;
84 private boolean mOverflowMenuShowing;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070085
Pankaj Garg66f8cef2015-07-07 17:29:03 -070086 private static Bitmap mDefaultFavicon;
87
Pankaj Garg32e1b942015-06-03 18:13:24 -070088 private int mStatusBarColor;
89 private static int mDefaultStatusBarColor = -1;
90
Pankaj Garg66f8cef2015-07-07 17:29:03 -070091 private static final int WEBREFINER_COUNTER_MSG = 4242;
92 private static final int WEBREFINER_COUNTER_MSG_DELAY = 3000;
93 private Handler mHandler;
94
Pankaj Garg8d2e98f2015-08-07 10:01:49 -070095 protected int mTrustLevel = SiteTileView.TRUST_UNKNOWN;
96
Pankaj Garg66f8cef2015-07-07 17:29:03 -070097 private static final String noSitePrefs[] = {
Axesh R. Ajmera6fc73692015-08-11 16:32:10 -070098 "chrome://",
Pankaj Garg66f8cef2015-07-07 17:29:03 -070099 "about:",
100 "content:",
101 };
102
John Reck0f602f32011-07-07 15:38:43 -0700103 public NavigationBarBase(Context context) {
104 super(context);
105 }
106
107 public NavigationBarBase(Context context, AttributeSet attrs) {
108 super(context, attrs);
109 }
110
111 public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) {
112 super(context, attrs, defStyle);
113 }
114
115 @Override
116 protected void onFinishInflate() {
117 super.onFinishInflate();
John Reck0f602f32011-07-07 15:38:43 -0700118 mUrlInput = (UrlInputView) findViewById(R.id.url);
119 mUrlInput.setUrlInputListener(this);
John Reck0f602f32011-07-07 15:38:43 -0700120 mUrlInput.setOnFocusChangeListener(this);
121 mUrlInput.setSelectAllOnFocus(true);
Narayan Kamathf3174a52011-11-17 14:43:32 +0000122 mUrlInput.addTextChangedListener(this);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800123 mMore = findViewById(R.id.more_browser_settings);
124 mMore.setOnClickListener(this);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700125 mMagnify = (ImageView) findViewById(R.id.magnify);
126 mMagnify.setOnClickListener(this);
127 mFaviconTile = (SiteTileView) findViewById(R.id.favicon_view);
128 mFaviconTile.setOnClickListener(this);
129 mVoiceButton = findViewById(R.id.voice);
130 mVoiceButton.setOnClickListener(this);
131 mClearButton = (ImageView) findViewById(R.id.clear);
132 mClearButton.setOnClickListener(this);
133 mStopButton = (ImageView) findViewById(R.id.stop);
134 mStopButton.setOnClickListener(this);
135
136 mDefaultFavicon = BitmapFactory.decodeResource(getResources(),
137 R.drawable.ic_deco_favicon_normal);
138
139 mHandler = new Handler() {
140 @Override
141 public void handleMessage(Message m) {
142 switch (m.what) {
143 case WEBREFINER_COUNTER_MSG:
144 WebView wv = mUiController.getCurrentTopWebView();
145 if (wv != null && WebRefiner.isInitialized()) {
146 int count = WebRefiner.getInstance().getBlockedURLCount(wv);
147 if (count > 0) {
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700148 mFaviconTile.setBadgeBlockedObjectsCount(count);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700149 }
150 }
151 mHandler.sendEmptyMessageDelayed(WEBREFINER_COUNTER_MSG,
152 WEBREFINER_COUNTER_MSG_DELAY);
153 break;
154 }
155 }
156 };
John Reck0f602f32011-07-07 15:38:43 -0700157 }
158
159 public void setTitleBar(TitleBar titleBar) {
160 mTitleBar = titleBar;
161 mBaseUi = mTitleBar.getUi();
162 mUiController = mTitleBar.getUiController();
Michael Kolbb2e91fd2011-07-14 13:47:29 -0700163 mUrlInput.setController(mUiController);
John Reck0f602f32011-07-07 15:38:43 -0700164 }
165
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700166 public void setSecurityState(Tab.SecurityState securityState) {
Pankaj Garg96d0ccd2015-07-30 16:49:47 -0700167 switch (securityState) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700168 case SECURITY_STATE_SECURE:
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700169 mTrustLevel = SiteTileView.TRUST_TRUSTED;
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700170 mFaviconTile.setBadgeHasCertIssues(false);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700171 break;
172 case SECURITY_STATE_MIXED:
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700173 mTrustLevel = SiteTileView.TRUST_UNTRUSTED;
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700174 mFaviconTile.setBadgeHasCertIssues(true);
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700175 mTitleBar.showTopControls(false);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700176 break;
177 case SECURITY_STATE_BAD_CERTIFICATE:
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700178 mTrustLevel = SiteTileView.TRUST_AVOID;
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700179 mFaviconTile.setBadgeHasCertIssues(true);
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700180 mTitleBar.showTopControls(false);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700181 break;
182 case SECURITY_STATE_NOT_SECURE:
183 default:
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700184 mTrustLevel = SiteTileView.TRUST_UNKNOWN;
John Reck0f602f32011-07-07 15:38:43 -0700185 }
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700186 mFaviconTile.setTrustLevel(mTrustLevel);
187 }
188
189 public int getTrustLevel() {
190 return mTrustLevel;
John Reck0f602f32011-07-07 15:38:43 -0700191 }
192
Pankaj Garg32e1b942015-06-03 18:13:24 -0700193 public static int adjustColor(int color, float hueMultiplier,
194 float saturationMultiplier, float valueMultiplier) {
195 float[] hsv = new float[3];
196 Color.colorToHSV(color, hsv);
197 hsv[0] *= hueMultiplier;
198 hsv[1] *= saturationMultiplier;
199 hsv[2] *= valueMultiplier;
200 return Color.HSVToColor(Color.alpha(color), hsv);
201 }
202
203 public static void setStatusAndNavigationBarColor(final Activity activity, int color) {
204 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
205 int currentColor = activity.getWindow().getStatusBarColor();
206 Integer from = currentColor;
207 Integer to = color;
208 ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
209
210 if (mDefaultStatusBarColor == -1) {
211 mDefaultStatusBarColor = activity.getWindow().getStatusBarColor();
212 }
213
214 animator.addUpdateListener(
215 new ValueAnimator.AnimatorUpdateListener() {
216 @Override
217 public void onAnimationUpdate(ValueAnimator animation) {
218 Integer value = (Integer) animation.getAnimatedValue();
219 activity.getWindow().setStatusBarColor(value.intValue());
220 //activity.getWindow().setNavigationBarColor(value.intValue());
221 }
222 }
223 );
224 animator.start();
225 }
226 }
227
228 private void updateSiteIconColor(String urlString, int color) {
229 try {
230 URL url = new URL(urlString);
231 String host = url.getHost();
232 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
233 int currentColor = prefs.getInt(host + ":color", 0);
234 if (currentColor != color) {
235 SharedPreferences.Editor editor = prefs.edit();
236 editor.remove(host + ":color");
237 editor.putInt(host + ":color", color);
238 editor.commit();
239 }
240 } catch (MalformedURLException e) {
241 }
242 }
243
244 public static int getSiteIconColor(String urlString) {
245 try {
246 URL url = new URL(urlString);
247 String host = url.getHost();
248 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
249 return prefs.getInt(host + ":color", 0);
250 } catch (MalformedURLException e) {
251 return 0;
252 }
253 }
254
255 public static int getDefaultStatusBarColor() {
256 return mDefaultStatusBarColor;
257 }
258
John Reck0f602f32011-07-07 15:38:43 -0700259 public void setFavicon(Bitmap icon) {
Pankaj Garg32e1b942015-06-03 18:13:24 -0700260 int color = ColorUtils.getDominantColorForBitmap(icon);
261 Tab tab = mUiController.getCurrentTab();
262
263 if (tab != null) {
264 if (tab.hasFavicon()) {
265 updateSiteIconColor(tab.getUrl(), color);
266 setStatusAndNavigationBarColor(mUiController.getActivity(),
267 adjustColor(color, 1, 1, 0.7f));
268 } else {
269 color = getSiteIconColor(tab.getUrl());
270 if (color != 0) {
271 setStatusAndNavigationBarColor(mUiController.getActivity(),
272 adjustColor(color, 1, 1, 0.7f));
273 } else {
274 setStatusAndNavigationBarColor(mUiController.getActivity(),
275 mDefaultStatusBarColor);
276 }
277 }
278 } else {
279 setStatusAndNavigationBarColor(mUiController.getActivity(), mDefaultStatusBarColor);
280 }
281
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700282 //Bitmap favicon = mUiController.getCurrentTopWebView().getFavicon();
283
284 if (mFaviconTile != null) {
285 mFaviconTile.replaceFavicon(mUiController.getCurrentTopWebView().getFavicon());
286 }
John Reck0f602f32011-07-07 15:38:43 -0700287 }
288
Pankaj Garg32e1b942015-06-03 18:13:24 -0700289 protected void showSiteSpecificSettings() {
290 WebView wv = mUiController.getCurrentTopWebView();
Pankaj Gargdbdf5aa2015-07-16 15:22:37 -0700291 int ads = 0;
292 int tracker = 0;
293 int malware = 0;
Pankaj Garg32e1b942015-06-03 18:13:24 -0700294
Pankaj Gargdbdf5aa2015-07-16 15:22:37 -0700295 WebRefiner webRefiner = WebRefiner.getInstance();
296 if (wv != null && webRefiner != null) {
297 WebRefiner.PageInfo pageInfo = webRefiner.getPageInfo(wv);
298 if (pageInfo != null) {
299 for (WebRefiner.MatchedURLInfo urlInfo : pageInfo.mMatchedURLInfoList) {
Pankaj Gargee992032015-07-24 15:59:36 -0700300 if (urlInfo.mActionTaken == WebRefiner.MatchedURLInfo.ACTION_BLOCKED) {
301 switch (urlInfo.mMatchedFilterCategory) {
302 case WebRefiner.RuleSet.CATEGORY_ADS:
303 ads++;
304 break;
305 case WebRefiner.RuleSet.CATEGORY_TRACKERS:
306 tracker++;
307 break;
308 case WebRefiner.RuleSet.CATEGORY_MALWARE_DOMAINS:
309 malware++;
310 break;
311 }
Pankaj Gargdbdf5aa2015-07-16 15:22:37 -0700312 }
313 }
314 }
Pankaj Garg32e1b942015-06-03 18:13:24 -0700315 }
316
317 Bundle bundle = new Bundle();
318 bundle.putCharSequence(SiteSpecificPreferencesFragment.EXTRA_SITE,
319 mUiController.getCurrentTab().getUrl());
Pankaj Gargdbdf5aa2015-07-16 15:22:37 -0700320
321 bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_WEB_REFINER_ADS_INFO, ads);
322 bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_WEB_REFINER_TRACKER_INFO, tracker);
323 bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_WEB_REFINER_MALWARE_INFO, malware);
Pankaj Garg32e1b942015-06-03 18:13:24 -0700324
325 bundle.putParcelable(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT,
326 SslCertificate.saveState(wv.getCertificate()));
327
Pankaj Garg96d0ccd2015-07-30 16:49:47 -0700328 Tab.SecurityState securityState = Tab.getWebViewSecurityState(
329 mUiController.getCurrentTab().getWebView());
330 if (securityState == Tab.SecurityState.SECURITY_STATE_MIXED) {
331 bundle.putBoolean(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT_MIXED, true);
332 } else if (securityState == Tab.SecurityState.SECURITY_STATE_BAD_CERTIFICATE) {
333 bundle.putBoolean(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT_BAD, true);
Pankaj Garg32e1b942015-06-03 18:13:24 -0700334 }
335
Pankaj Garg68faf1c2015-06-26 17:07:37 -0700336 Bitmap favicon = mUiController.getCurrentTopWebView().getFavicon();
Pankaj Garg32e1b942015-06-03 18:13:24 -0700337 if (favicon != null) {
338 ByteArrayOutputStream baos = new ByteArrayOutputStream();
339 favicon.compress(Bitmap.CompressFormat.PNG, 50, baos);
340 bundle.putByteArray(SiteSpecificPreferencesFragment.EXTRA_FAVICON,
341 baos.toByteArray());
342 }
343 BrowserPreferencesPage.startPreferenceFragmentExtraForResult(
344 mUiController.getActivity(),
345 SiteSpecificPreferencesFragment.class.getName(), bundle, 0);
346 }
347
John Reck0f602f32011-07-07 15:38:43 -0700348 @Override
349 public void onClick(View v) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700350 Tab currentTab = mUiController.getCurrentTab();
Vivek Sekharae3b1792015-08-03 12:26:41 -0700351 WebView wv = currentTab.getWebView();
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700352 String url = null;
353 if (currentTab != null){
354 url = currentTab.getUrl();
355 }
Enrico Ros1f5a0952014-11-18 20:15:48 -0800356 if (mMore == v) {
357 showMenu(mMore);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700358 } else if (mFaviconTile == v) {
Vivek Sekharae3b1792015-08-03 12:26:41 -0700359 if (urlHasSitePrefs(url) && (wv != null && !wv.isShowingInterstitialPage()) ){
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700360 showSiteSpecificSettings();
361 }
362 } else if (mMagnify == v) {
363 startEditingUrl(true, true);
364 } else if (mVoiceButton == v) {
365 mUiController.startVoiceRecognizer();
366 } else if (mStopButton == v) {
367 stopOrRefresh();
368 } else if (mClearButton == v) {
369 clearOrClose();
370 mUrlInput.setText("");
371 }
372 }
373
374 private static boolean urlHasSitePrefs(String url) {
375 if (TextUtils.isEmpty(url)) {
376 return false;
377 }
378
379 for (int i = 0; i < noSitePrefs.length; i++) {
380 if (url.startsWith(noSitePrefs[i])) {
381 return false;
382 }
383 }
384 return true;
385 }
386
387 private void stopOrRefresh() {
388 if (mUiController == null) return;
389 if (mTitleBar.isInLoad()) {
390 mUiController.stopLoading();
391 } else {
392 if (mUiController.getCurrentTopWebView() != null) {
393 stopEditingUrl();
394 mUiController.getCurrentTopWebView().reload();
395 }
396 }
397 }
398
399 private void clearOrClose() {
400 if (TextUtils.isEmpty(mUrlInput.getText())) {
401 // close
402 mUrlInput.clearFocus();
403 } else {
404 // clear
405 mUrlInput.setText("");
Enrico Ros1f5a0952014-11-18 20:15:48 -0800406 }
407 }
408
409 void showMenu(View anchor) {
410 Activity activity = mUiController.getActivity();
411 if (mPopupMenu == null) {
412 mPopupMenu = new PopupMenu(getContext(), anchor);
413 mPopupMenu.setOnMenuItemClickListener(this);
414 mPopupMenu.setOnDismissListener(this);
415 if (!activity.onCreateOptionsMenu(mPopupMenu.getMenu())) {
416 mPopupMenu = null;
417 return;
418 }
419 }
420 Menu menu = mPopupMenu.getMenu();
421
422 if (mUiController instanceof Controller) {
423 Controller controller = (Controller) mUiController;
424 if (controller.onPrepareOptionsMenu(menu)) {
425 mOverflowMenuShowing = true;
426 }
427 }
John Reck0f602f32011-07-07 15:38:43 -0700428 }
429
430 @Override
431 public void onFocusChange(View view, boolean hasFocus) {
432 // if losing focus and not in touch mode, leave as is
433 if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) {
434 setFocusState(hasFocus);
435 }
436 if (hasFocus) {
437 mBaseUi.showTitleBar();
Dany Rybnikovbcd37da2015-04-20 11:43:15 +0300438 if (!BrowserSettings.getInstance().isPowerSaveModeEnabled()) {
439 //Notify about anticipated network activity
440 NetworkServices.hintUpcomingUserActivity();
441 }
John Reck0f602f32011-07-07 15:38:43 -0700442 } else if (!mUrlInput.needsUpdate()) {
443 mUrlInput.dismissDropDown();
444 mUrlInput.hideIME();
445 if (mUrlInput.getText().length() == 0) {
446 Tab currentTab = mUiController.getTabControl().getCurrentTab();
447 if (currentTab != null) {
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700448 setDisplayTitle(currentTab.getTitle(), currentTab.getUrl());
John Reck0f602f32011-07-07 15:38:43 -0700449 }
450 }
John Reck0f602f32011-07-07 15:38:43 -0700451 }
452 mUrlInput.clearNeedsUpdate();
453 }
454
455 protected void setFocusState(boolean focus) {
456 }
457
John Reck0f602f32011-07-07 15:38:43 -0700458 public boolean isEditingUrl() {
459 return mUrlInput.hasFocus();
460 }
461
462 void stopEditingUrl() {
Michael Kolb0b129122012-06-04 16:31:58 -0700463 WebView currentTopWebView = mUiController.getCurrentTopWebView();
464 if (currentTopWebView != null) {
465 currentTopWebView.requestFocus();
466 }
John Reck0f602f32011-07-07 15:38:43 -0700467 }
468
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700469 void setDisplayTitle(String title, String url) {
John Reck0f602f32011-07-07 15:38:43 -0700470 if (!isEditingUrl()) {
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700471 if (!TextUtils.isEmpty(title)) {
472 if (mTrustLevel == SiteTileView.TRUST_TRUSTED) {
473 if (!title.equals(mUrlInput.getText().toString())) {
474 mUrlInput.setText(title, false);
475 }
476 return;
477 }
478 }
479 if (!url.equals(mUrlInput.getText().toString())) {
480 mUrlInput.setText(url, false);
Michael Kolb29aab402012-05-29 17:22:35 -0700481 }
John Reck0f602f32011-07-07 15:38:43 -0700482 }
483 }
484
John Reck0f602f32011-07-07 15:38:43 -0700485 void setIncognitoMode(boolean incognito) {
486 mUrlInput.setIncognitoMode(incognito);
487 }
488
489 void clearCompletions() {
Narayan Kamathf3174a52011-11-17 14:43:32 +0000490 mUrlInput.dismissDropDown();
John Reck0f602f32011-07-07 15:38:43 -0700491 }
492
493 // UrlInputListener implementation
494
495 /**
496 * callback from suggestion dropdown
497 * user selected a suggestion
498 */
499 @Override
500 public void onAction(String text, String extra, String source) {
Michael Kolb0b129122012-06-04 16:31:58 -0700501 stopEditingUrl();
John Reck0f602f32011-07-07 15:38:43 -0700502 if (UrlInputView.TYPED.equals(source)) {
kaiyizc4ada322013-07-30 09:58:07 +0800503 String url = null;
Panos Thomas4bdb5252014-11-13 16:20:11 -0800504 boolean wap2estore = BrowserConfig.getInstance(getContext())
505 .hasFeature(BrowserConfig.Feature.WAP2ESTORE);
Vivek Sekhar5e631472014-03-31 23:59:10 -0700506 if ((wap2estore && isEstoreTypeUrl(text)) || isRtspTypeUrl(text)
507 || isMakeCallTypeUrl(text)) {
kaiyizc4ada322013-07-30 09:58:07 +0800508 url = text;
509 } else {
510 url = UrlUtils.smartUrlFilter(text, false);
511 }
512
John Reck0f602f32011-07-07 15:38:43 -0700513 Tab t = mBaseUi.getActiveTab();
514 // Only shortcut javascript URIs for now, as there is special
515 // logic in UrlHandler for other schemas
Axesh R. Ajmera6fc73692015-08-11 16:32:10 -0700516 if (url != null && t != null && url.startsWith("javascript:")) {
John Reck0f602f32011-07-07 15:38:43 -0700517 mUiController.loadUrl(t, url);
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700518 setDisplayTitle(null, text);
John Reck0f602f32011-07-07 15:38:43 -0700519 return;
520 }
kaiyizc4ada322013-07-30 09:58:07 +0800521
522 // add for carrier wap2estore feature
523 if (url != null && t != null && wap2estore && isEstoreTypeUrl(url)) {
Vivek Sekharb54614f2014-05-01 19:03:37 -0700524 if (handleEstoreTypeUrl(url)) {
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700525 setDisplayTitle(null, text);
Vivek Sekharb54614f2014-05-01 19:03:37 -0700526 return;
527 }
kaiyizc4ada322013-07-30 09:58:07 +0800528 }
kaiyiz950eca22013-08-08 11:01:28 +0800529 // add for rtsp scheme feature
530 if (url != null && t != null && isRtspTypeUrl(url)) {
531 if (handleRtspTypeUrl(url)) {
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700532 setDisplayTitle(null, text);
kaiyiz950eca22013-08-08 11:01:28 +0800533 return;
534 }
535 }
Vivek Sekhar5e631472014-03-31 23:59:10 -0700536 // add for "wtai://wp/mc;" scheme feature
537 if (url != null && t != null && isMakeCallTypeUrl(url)) {
538 if (handleMakeCallTypeUrl(url)) {
539 return;
540 }
541 }
John Reck0f602f32011-07-07 15:38:43 -0700542 }
543 Intent i = new Intent();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700544 String action = Intent.ACTION_SEARCH;
John Reck0f602f32011-07-07 15:38:43 -0700545 i.setAction(action);
546 i.putExtra(SearchManager.QUERY, text);
547 if (extra != null) {
548 i.putExtra(SearchManager.EXTRA_DATA_KEY, extra);
549 }
550 if (source != null) {
551 Bundle appData = new Bundle();
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800552 appData.putString("source", source);
553 i.putExtra("source", appData);
John Reck0f602f32011-07-07 15:38:43 -0700554 }
555 mUiController.handleNewIntent(i);
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700556 setDisplayTitle(null, text);
John Reck0f602f32011-07-07 15:38:43 -0700557 }
558
Vivek Sekhar5e631472014-03-31 23:59:10 -0700559 private boolean isMakeCallTypeUrl(String url) {
560 String utf8Url = null;
561 try {
562 utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
563 } catch (UnsupportedEncodingException e) {
564 Log.e(TAG, "err " + e);
565 }
566 if (utf8Url != null && utf8Url.startsWith(UrlHandler.SCHEME_WTAI_MC)) {
567 return true;
568 }
569 return false;
570 }
571
572 private boolean handleMakeCallTypeUrl(String url) {
573 // wtai://wp/mc;number
574 // number=string(phone-number)
575 if (url.startsWith(UrlHandler.SCHEME_WTAI_MC)) {
576 Intent intent = new Intent(Intent.ACTION_VIEW,
577 Uri.parse(WebView.SCHEME_TEL +
578 url.substring(UrlHandler.SCHEME_WTAI_MC.length())));
579 getContext().startActivity(intent);
580 // before leaving BrowserActivity, close the empty child tab.
581 // If a new tab is created through JavaScript open to load this
582 // url, we would like to close it as we will load this url in a
583 // different Activity.
584 Tab current = mUiController.getCurrentTab();
585 if (current != null
586 && current.getWebView().copyBackForwardList().getSize() == 0) {
587 mUiController.closeCurrentTab();
588 }
589 return true;
590 }
591 return false;
592 }
593
kaiyizc4ada322013-07-30 09:58:07 +0800594 private boolean isEstoreTypeUrl(String url) {
Vivek Sekharb54614f2014-05-01 19:03:37 -0700595 if (url != null && url.startsWith("estore:")) {
kaiyizc4ada322013-07-30 09:58:07 +0800596 return true;
597 }
598 return false;
599 }
600
Vivek Sekharb54614f2014-05-01 19:03:37 -0700601 private boolean handleEstoreTypeUrl(String url) {
602 if (url.getBytes().length > 256) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800603 Toast.makeText(getContext(), R.string.estore_url_warning, Toast.LENGTH_LONG).show();
Vivek Sekharb54614f2014-05-01 19:03:37 -0700604 return false;
kaiyizc4ada322013-07-30 09:58:07 +0800605 }
Vivek Sekharb54614f2014-05-01 19:03:37 -0700606
607 Intent intent;
608 // perform generic parsing of the URI to turn it into an Intent.
609 try {
610 intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
611 } catch (URISyntaxException ex) {
612 Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
613 return false;
614 }
615
kaiyizc4ada322013-07-30 09:58:07 +0800616 try {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800617 getContext().startActivity(intent);
kaiyizc4ada322013-07-30 09:58:07 +0800618 } catch (ActivityNotFoundException ex) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800619 String downloadUrl = getContext().getResources().getString(R.string.estore_homepage);
kaiyizc4ada322013-07-30 09:58:07 +0800620 mUiController.loadUrl(mBaseUi.getActiveTab(), downloadUrl);
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800621 Toast.makeText(getContext(), R.string.download_estore_app, Toast.LENGTH_LONG).show();
kaiyizc4ada322013-07-30 09:58:07 +0800622 }
Vivek Sekharb54614f2014-05-01 19:03:37 -0700623
624 return true;
kaiyizc4ada322013-07-30 09:58:07 +0800625 }
626
kaiyiz950eca22013-08-08 11:01:28 +0800627 private boolean isRtspTypeUrl(String url) {
628 String utf8Url = null;
629 try {
630 utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
631 } catch (UnsupportedEncodingException e) {
632 Log.e(TAG, "err " + e);
633 }
634 if (utf8Url != null && utf8Url.startsWith("rtsp://")) {
635 return true;
636 }
637 return false;
638 }
639
640 private boolean handleRtspTypeUrl(String url) {
641 Intent intent;
642 // perform generic parsing of the URI to turn it into an Intent.
643 try {
644 intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
645 } catch (URISyntaxException ex) {
646 Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
647 return false;
648 }
649
650 try {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800651 getContext().startActivity(intent);
kaiyiz950eca22013-08-08 11:01:28 +0800652 } catch (ActivityNotFoundException ex) {
653 Log.w("Browser", "No resolveActivity " + url);
654 return false;
655 }
656 return true;
657 }
658
John Reck0f602f32011-07-07 15:38:43 -0700659 @Override
660 public void onDismiss() {
661 final Tab currentTab = mBaseUi.getActiveTab();
662 mBaseUi.hideTitleBar();
663 post(new Runnable() {
664 public void run() {
665 clearFocus();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700666 if (currentTab != null) {
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700667 setDisplayTitle(currentTab.getTitle(), currentTab.getUrl());
John Reck0f602f32011-07-07 15:38:43 -0700668 }
669 }
670 });
671 }
672
673 /**
674 * callback from the suggestion dropdown
675 * copy text to input field and stay in edit mode
676 */
677 @Override
678 public void onCopySuggestion(String text) {
679 mUrlInput.setText(text, true);
680 if (text != null) {
681 mUrlInput.setSelection(text.length());
682 }
683 }
684
685 public void setCurrentUrlIsBookmark(boolean isBookmark) {
686 }
687
688 @Override
689 public boolean dispatchKeyEventPreIme(KeyEvent evt) {
690 if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
Sagar Dhawan5a5d01f2015-07-30 17:16:21 -0700691 if (mUiController.getCurrentTab() != null &&
692 mUiController.getCurrentTab().isKeyboardShowing()){
693 stopEditingUrl();
694 return true;
695 }
John Reck0f602f32011-07-07 15:38:43 -0700696 // catch back key in order to do slightly more cleanup than usual
Michael Kolb0b129122012-06-04 16:31:58 -0700697 stopEditingUrl();
John Reck0f602f32011-07-07 15:38:43 -0700698 }
699 return super.dispatchKeyEventPreIme(evt);
700 }
701
John Reck0f602f32011-07-07 15:38:43 -0700702 /**
703 * called from the Ui when the user wants to edit
704 * @param clearInput clear the input field
705 */
Michael Kolb1f9b3562012-04-24 14:38:34 -0700706 void startEditingUrl(boolean clearInput, boolean forceIME) {
John Reck0f602f32011-07-07 15:38:43 -0700707 // editing takes preference of progress
708 setVisibility(View.VISIBLE);
John Reck0f602f32011-07-07 15:38:43 -0700709 if (!mUrlInput.hasFocus()) {
710 mUrlInput.requestFocus();
711 }
712 if (clearInput) {
713 mUrlInput.setText("");
John Reck0f602f32011-07-07 15:38:43 -0700714 }
Michael Kolb1f9b3562012-04-24 14:38:34 -0700715 if (forceIME) {
Michael Kolb4bb6fcb2012-04-13 14:25:27 -0700716 mUrlInput.showIME();
717 }
John Reck0f602f32011-07-07 15:38:43 -0700718 }
719
720 public void onProgressStarted() {
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700721 mFaviconTile.setBadgeBlockedObjectsCount(0);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700722 mFaviconTile.setTrustLevel(SiteTileView.TRUST_UNKNOWN);
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700723 mFaviconTile.setBadgeHasCertIssues(false);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700724 mFaviconTile.replaceFavicon(mDefaultFavicon);
Pankaj Garg96d0ccd2015-07-30 16:49:47 -0700725 setSecurityState(Tab.SecurityState.SECURITY_STATE_NOT_SECURE);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700726 mHandler.removeMessages(WEBREFINER_COUNTER_MSG);
727 mHandler.sendEmptyMessageDelayed(WEBREFINER_COUNTER_MSG,
728 WEBREFINER_COUNTER_MSG_DELAY);
729 mStopButton.setImageResource(R.drawable.ic_action_stop);
730 mStopButton.setContentDescription(getResources().
731 getString(R.string.accessibility_button_stop));
John Reck0f602f32011-07-07 15:38:43 -0700732 }
733
734 public void onProgressStopped() {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700735 if (!isEditingUrl()) {
736 mFaviconTile.setVisibility(View.VISIBLE);
737 }
738 mStopButton.setImageResource(R.drawable.ic_action_reload);
739 mStopButton.setContentDescription(getResources().
740 getString(R.string.accessibility_button_refresh));
John Reck0f602f32011-07-07 15:38:43 -0700741 }
742
John Reck419f6b42011-08-16 16:10:51 -0700743 public void onTabDataChanged(Tab tab) {
744 }
745
Michael Kolb0b129122012-06-04 16:31:58 -0700746 public void onVoiceResult(String s) {
747 startEditingUrl(true, true);
748 onCopySuggestion(s);
749 }
750
Narayan Kamathf3174a52011-11-17 14:43:32 +0000751 @Override
752 public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
753
754 @Override
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700755 public void onTextChanged(CharSequence s, int start, int before, int count) { }
Narayan Kamathf3174a52011-11-17 14:43:32 +0000756
757 @Override
758 public void afterTextChanged(Editable s) { }
Michael Kolb0b129122012-06-04 16:31:58 -0700759
Enrico Ros1f5a0952014-11-18 20:15:48 -0800760 @Override
761 public void onStateChanged(int state) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700762 mVoiceButton.setVisibility(View.GONE);
Sagar Dhawan84ef4442015-07-29 12:08:10 -0700763 mClearButton.setVisibility(View.GONE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800764 switch(state) {
765 case STATE_NORMAL:
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700766 mFaviconTile.setVisibility(View.VISIBLE);
767 mMagnify.setVisibility(View.GONE);
Sagar Dhawanaff56c92015-07-13 15:57:11 -0700768 mMore.setVisibility(View.VISIBLE);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700769 if (mUiController != null) {
770 Tab currentTab = mUiController.getCurrentTab();
771 if (currentTab != null){
772 if (TextUtils.isEmpty(currentTab.getUrl())) {
773 mFaviconTile.setVisibility(View.GONE);
774 mMagnify.setVisibility(View.VISIBLE);
775 }
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700776 setDisplayTitle(currentTab.getTitle(), currentTab.getUrl());
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700777 }
778 mUiController.setWindowDimming(0.0f);
779 }
780
Enrico Ros1f5a0952014-11-18 20:15:48 -0800781 break;
782 case STATE_HIGHLIGHTED:
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700783 mFaviconTile.setVisibility(View.GONE);
Sagar Dhawan84ef4442015-07-29 12:08:10 -0700784 mMagnify.setVisibility(View.VISIBLE);
785 mClearButton.setVisibility(View.VISIBLE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800786 mMore.setVisibility(View.GONE);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700787 if (mUiController != null) {
788 mUiController.setWindowDimming(0.75f);
Pankaj Garg8d2e98f2015-08-07 10:01:49 -0700789 if (mTrustLevel == SiteTileView.TRUST_TRUSTED) {
790 Tab currentTab = mUiController.getCurrentTab();
791 if (currentTab != null) {
792 mUrlInput.setText(currentTab.getUrl(), false);
793 mUrlInput.selectAll();
794 }
795 }
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700796 }
Enrico Ros1f5a0952014-11-18 20:15:48 -0800797 break;
798 case STATE_EDITED:
Sagar Dhawan84ef4442015-07-29 12:08:10 -0700799 if (TextUtils.isEmpty(mUrlInput.getText()) &&
800 mUiController != null &&
801 mUiController.supportsVoice()) {
802 mVoiceButton.setVisibility(View.VISIBLE);
803 }
804 else {
805 mClearButton.setVisibility(View.VISIBLE);
806 }
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700807 mFaviconTile.setVisibility(View.GONE);
808 mMagnify.setVisibility(View.VISIBLE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800809 mMore.setVisibility(View.GONE);
810 break;
811 }
812 }
813
814 public boolean isMenuShowing() {
815 return mOverflowMenuShowing;
816 }
817
818
819 @Override
820 public void onDismiss(PopupMenu popupMenu) {
821 if (popupMenu == mPopupMenu) {
822 onMenuHidden();
823 }
824 }
825
826 private void onMenuHidden() {
827 mOverflowMenuShowing = false;
Enrico Ros1f5a0952014-11-18 20:15:48 -0800828 }
829
830
831 @Override
832 public boolean onMenuItemClick(MenuItem item) {
833 return mUiController.onOptionsItemSelected(item);
834 }
John Reck0f602f32011-07-07 15:38:43 -0700835}