blob: 10c091b1a3d0d1accbc559dc2cd72c0d1f5fbe57 [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;
Kevin Hart055e6d82014-12-19 15:53:19 -080061import org.codeaurora.swe.Engine;
Pankaj Garg32e1b942015-06-03 18:13:24 -070062import org.codeaurora.swe.WebRefiner;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080063import org.codeaurora.swe.WebView;
Pankaj Garg32e1b942015-06-03 18:13:24 -070064import org.codeaurora.swe.util.ColorUtils;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080065
John Reck42229bc2011-08-19 13:26:43 -070066public class NavigationBarBase extends LinearLayout implements
67 OnClickListener, UrlInputListener, OnFocusChangeListener,
Enrico Ros1f5a0952014-11-18 20:15:48 -080068 TextWatcher, UrlInputView.StateListener,
69 PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
John Reck0f602f32011-07-07 15:38:43 -070070
kaiyizc4ada322013-07-30 09:58:07 +080071 private final static String TAG = "NavigationBarBase";
72
John Reck0f602f32011-07-07 15:38:43 -070073 protected BaseUi mBaseUi;
74 protected TitleBar mTitleBar;
75 protected UiController mUiController;
76 protected UrlInputView mUrlInput;
Pankaj Garg66f8cef2015-07-07 17:29:03 -070077 protected ImageView mStopButton;
John Reck0f602f32011-07-07 15:38:43 -070078
Pankaj Garg66f8cef2015-07-07 17:29:03 -070079 private SiteTileView mFaviconTile;
80 private ImageView mMagnify;
81 private View mVoiceButton;
82 private ImageView mClearButton;
Enrico Ros1f5a0952014-11-18 20:15:48 -080083 private View mMore;
84 private PopupMenu mPopupMenu;
85 private boolean mOverflowMenuShowing;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070086
Pankaj Garg66f8cef2015-07-07 17:29:03 -070087 private static Bitmap mDefaultFavicon;
88
Pankaj Garg32e1b942015-06-03 18:13:24 -070089 private int mStatusBarColor;
90 private static int mDefaultStatusBarColor = -1;
91
Pankaj Garg66f8cef2015-07-07 17:29:03 -070092 private static final int WEBREFINER_COUNTER_MSG = 4242;
93 private static final int WEBREFINER_COUNTER_MSG_DELAY = 3000;
94 private Handler mHandler;
95
Pankaj Garg66f8cef2015-07-07 17:29:03 -070096 private static final String noSitePrefs[] = {
Axesh R. Ajmera1f998ae2015-04-21 14:16:41 -070097 "browser://",
Pankaj Garg66f8cef2015-07-07 17:29:03 -070098 "about:",
99 "content:",
100 };
101
John Reck0f602f32011-07-07 15:38:43 -0700102 public NavigationBarBase(Context context) {
103 super(context);
104 }
105
106 public NavigationBarBase(Context context, AttributeSet attrs) {
107 super(context, attrs);
108 }
109
110 public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) {
111 super(context, attrs, defStyle);
112 }
113
114 @Override
115 protected void onFinishInflate() {
116 super.onFinishInflate();
John Reck0f602f32011-07-07 15:38:43 -0700117 mUrlInput = (UrlInputView) findViewById(R.id.url);
118 mUrlInput.setUrlInputListener(this);
John Reck0f602f32011-07-07 15:38:43 -0700119 mUrlInput.setOnFocusChangeListener(this);
120 mUrlInput.setSelectAllOnFocus(true);
Narayan Kamathf3174a52011-11-17 14:43:32 +0000121 mUrlInput.addTextChangedListener(this);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800122 mMore = findViewById(R.id.more_browser_settings);
123 mMore.setOnClickListener(this);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700124 mMagnify = (ImageView) findViewById(R.id.magnify);
125 mMagnify.setOnClickListener(this);
126 mFaviconTile = (SiteTileView) findViewById(R.id.favicon_view);
127 mFaviconTile.setOnClickListener(this);
128 mVoiceButton = findViewById(R.id.voice);
129 mVoiceButton.setOnClickListener(this);
130 mClearButton = (ImageView) findViewById(R.id.clear);
131 mClearButton.setOnClickListener(this);
132 mStopButton = (ImageView) findViewById(R.id.stop);
133 mStopButton.setOnClickListener(this);
134
135 mDefaultFavicon = BitmapFactory.decodeResource(getResources(),
136 R.drawable.ic_deco_favicon_normal);
137
138 mHandler = new Handler() {
139 @Override
140 public void handleMessage(Message m) {
141 switch (m.what) {
142 case WEBREFINER_COUNTER_MSG:
143 WebView wv = mUiController.getCurrentTopWebView();
144 if (wv != null && WebRefiner.isInitialized()) {
145 int count = WebRefiner.getInstance().getBlockedURLCount(wv);
146 if (count > 0) {
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700147 mFaviconTile.setBadgeBlockedObjectsCount(count);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700148 }
149 }
150 mHandler.sendEmptyMessageDelayed(WEBREFINER_COUNTER_MSG,
151 WEBREFINER_COUNTER_MSG_DELAY);
152 break;
153 }
154 }
155 };
John Reck0f602f32011-07-07 15:38:43 -0700156 }
157
158 public void setTitleBar(TitleBar titleBar) {
159 mTitleBar = titleBar;
160 mBaseUi = mTitleBar.getUi();
161 mUiController = mTitleBar.getUiController();
Michael Kolbb2e91fd2011-07-14 13:47:29 -0700162 mUrlInput.setController(mUiController);
John Reck0f602f32011-07-07 15:38:43 -0700163 }
164
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700165 public void setSecurityState(Tab.SecurityState securityState) {
Pankaj Garg96d0ccd2015-07-30 16:49:47 -0700166 switch (securityState) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700167 case SECURITY_STATE_SECURE:
168 mFaviconTile.setTrustLevel(SiteTileView.TRUST_TRUSTED);
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700169 mFaviconTile.setBadgeHasCertIssues(false);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700170 break;
171 case SECURITY_STATE_MIXED:
172 mFaviconTile.setTrustLevel(SiteTileView.TRUST_UNTRUSTED);
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700173 mFaviconTile.setBadgeHasCertIssues(true);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700174 break;
175 case SECURITY_STATE_BAD_CERTIFICATE:
176 mFaviconTile.setTrustLevel(SiteTileView.TRUST_AVOID);
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700177 mFaviconTile.setBadgeHasCertIssues(true);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700178 break;
179 case SECURITY_STATE_NOT_SECURE:
180 default:
181 mFaviconTile.setTrustLevel(SiteTileView.TRUST_UNKNOWN);
John Reck0f602f32011-07-07 15:38:43 -0700182 }
183 }
184
Pankaj Garg32e1b942015-06-03 18:13:24 -0700185 public static int adjustColor(int color, float hueMultiplier,
186 float saturationMultiplier, float valueMultiplier) {
187 float[] hsv = new float[3];
188 Color.colorToHSV(color, hsv);
189 hsv[0] *= hueMultiplier;
190 hsv[1] *= saturationMultiplier;
191 hsv[2] *= valueMultiplier;
192 return Color.HSVToColor(Color.alpha(color), hsv);
193 }
194
195 public static void setStatusAndNavigationBarColor(final Activity activity, int color) {
196 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
197 int currentColor = activity.getWindow().getStatusBarColor();
198 Integer from = currentColor;
199 Integer to = color;
200 ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
201
202 if (mDefaultStatusBarColor == -1) {
203 mDefaultStatusBarColor = activity.getWindow().getStatusBarColor();
204 }
205
206 animator.addUpdateListener(
207 new ValueAnimator.AnimatorUpdateListener() {
208 @Override
209 public void onAnimationUpdate(ValueAnimator animation) {
210 Integer value = (Integer) animation.getAnimatedValue();
211 activity.getWindow().setStatusBarColor(value.intValue());
212 //activity.getWindow().setNavigationBarColor(value.intValue());
213 }
214 }
215 );
216 animator.start();
217 }
218 }
219
220 private void updateSiteIconColor(String urlString, int color) {
221 try {
222 URL url = new URL(urlString);
223 String host = url.getHost();
224 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
225 int currentColor = prefs.getInt(host + ":color", 0);
226 if (currentColor != color) {
227 SharedPreferences.Editor editor = prefs.edit();
228 editor.remove(host + ":color");
229 editor.putInt(host + ":color", color);
230 editor.commit();
231 }
232 } catch (MalformedURLException e) {
233 }
234 }
235
236 public static int getSiteIconColor(String urlString) {
237 try {
238 URL url = new URL(urlString);
239 String host = url.getHost();
240 SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
241 return prefs.getInt(host + ":color", 0);
242 } catch (MalformedURLException e) {
243 return 0;
244 }
245 }
246
247 public static int getDefaultStatusBarColor() {
248 return mDefaultStatusBarColor;
249 }
250
John Reck0f602f32011-07-07 15:38:43 -0700251 public void setFavicon(Bitmap icon) {
Pankaj Garg32e1b942015-06-03 18:13:24 -0700252 int color = ColorUtils.getDominantColorForBitmap(icon);
253 Tab tab = mUiController.getCurrentTab();
254
255 if (tab != null) {
256 if (tab.hasFavicon()) {
257 updateSiteIconColor(tab.getUrl(), color);
258 setStatusAndNavigationBarColor(mUiController.getActivity(),
259 adjustColor(color, 1, 1, 0.7f));
260 } else {
261 color = getSiteIconColor(tab.getUrl());
262 if (color != 0) {
263 setStatusAndNavigationBarColor(mUiController.getActivity(),
264 adjustColor(color, 1, 1, 0.7f));
265 } else {
266 setStatusAndNavigationBarColor(mUiController.getActivity(),
267 mDefaultStatusBarColor);
268 }
269 }
270 } else {
271 setStatusAndNavigationBarColor(mUiController.getActivity(), mDefaultStatusBarColor);
272 }
273
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700274 //Bitmap favicon = mUiController.getCurrentTopWebView().getFavicon();
275
276 if (mFaviconTile != null) {
277 mFaviconTile.replaceFavicon(mUiController.getCurrentTopWebView().getFavicon());
278 }
John Reck0f602f32011-07-07 15:38:43 -0700279 }
280
Pankaj Garg32e1b942015-06-03 18:13:24 -0700281 protected void showSiteSpecificSettings() {
282 WebView wv = mUiController.getCurrentTopWebView();
Pankaj Gargdbdf5aa2015-07-16 15:22:37 -0700283 int ads = 0;
284 int tracker = 0;
285 int malware = 0;
Pankaj Garg32e1b942015-06-03 18:13:24 -0700286
Pankaj Gargdbdf5aa2015-07-16 15:22:37 -0700287 WebRefiner webRefiner = WebRefiner.getInstance();
288 if (wv != null && webRefiner != null) {
289 WebRefiner.PageInfo pageInfo = webRefiner.getPageInfo(wv);
290 if (pageInfo != null) {
291 for (WebRefiner.MatchedURLInfo urlInfo : pageInfo.mMatchedURLInfoList) {
Pankaj Gargee992032015-07-24 15:59:36 -0700292 if (urlInfo.mActionTaken == WebRefiner.MatchedURLInfo.ACTION_BLOCKED) {
293 switch (urlInfo.mMatchedFilterCategory) {
294 case WebRefiner.RuleSet.CATEGORY_ADS:
295 ads++;
296 break;
297 case WebRefiner.RuleSet.CATEGORY_TRACKERS:
298 tracker++;
299 break;
300 case WebRefiner.RuleSet.CATEGORY_MALWARE_DOMAINS:
301 malware++;
302 break;
303 }
Pankaj Gargdbdf5aa2015-07-16 15:22:37 -0700304 }
305 }
306 }
Pankaj Garg32e1b942015-06-03 18:13:24 -0700307 }
308
309 Bundle bundle = new Bundle();
310 bundle.putCharSequence(SiteSpecificPreferencesFragment.EXTRA_SITE,
311 mUiController.getCurrentTab().getUrl());
Pankaj Gargdbdf5aa2015-07-16 15:22:37 -0700312
313 bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_WEB_REFINER_ADS_INFO, ads);
314 bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_WEB_REFINER_TRACKER_INFO, tracker);
315 bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_WEB_REFINER_MALWARE_INFO, malware);
Pankaj Garg32e1b942015-06-03 18:13:24 -0700316
317 bundle.putParcelable(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT,
318 SslCertificate.saveState(wv.getCertificate()));
319
Pankaj Garg96d0ccd2015-07-30 16:49:47 -0700320 Tab.SecurityState securityState = Tab.getWebViewSecurityState(
321 mUiController.getCurrentTab().getWebView());
322 if (securityState == Tab.SecurityState.SECURITY_STATE_MIXED) {
323 bundle.putBoolean(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT_MIXED, true);
324 } else if (securityState == Tab.SecurityState.SECURITY_STATE_BAD_CERTIFICATE) {
325 bundle.putBoolean(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT_BAD, true);
Pankaj Garg32e1b942015-06-03 18:13:24 -0700326 }
327
Pankaj Garg68faf1c2015-06-26 17:07:37 -0700328 Bitmap favicon = mUiController.getCurrentTopWebView().getFavicon();
Pankaj Garg32e1b942015-06-03 18:13:24 -0700329 if (favicon != null) {
330 ByteArrayOutputStream baos = new ByteArrayOutputStream();
331 favicon.compress(Bitmap.CompressFormat.PNG, 50, baos);
332 bundle.putByteArray(SiteSpecificPreferencesFragment.EXTRA_FAVICON,
333 baos.toByteArray());
334 }
335 BrowserPreferencesPage.startPreferenceFragmentExtraForResult(
336 mUiController.getActivity(),
337 SiteSpecificPreferencesFragment.class.getName(), bundle, 0);
338 }
339
John Reck0f602f32011-07-07 15:38:43 -0700340 @Override
341 public void onClick(View v) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700342 Tab currentTab = mUiController.getCurrentTab();
Vivek Sekharae3b1792015-08-03 12:26:41 -0700343 WebView wv = currentTab.getWebView();
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700344 String url = null;
345 if (currentTab != null){
346 url = currentTab.getUrl();
347 }
Enrico Ros1f5a0952014-11-18 20:15:48 -0800348 if (mMore == v) {
349 showMenu(mMore);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700350 } else if (mFaviconTile == v) {
Vivek Sekharae3b1792015-08-03 12:26:41 -0700351 if (urlHasSitePrefs(url) && (wv != null && !wv.isShowingInterstitialPage()) ){
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700352 showSiteSpecificSettings();
353 }
354 } else if (mMagnify == v) {
355 startEditingUrl(true, true);
356 } else if (mVoiceButton == v) {
357 mUiController.startVoiceRecognizer();
358 } else if (mStopButton == v) {
359 stopOrRefresh();
360 } else if (mClearButton == v) {
361 clearOrClose();
362 mUrlInput.setText("");
363 }
364 }
365
366 private static boolean urlHasSitePrefs(String url) {
367 if (TextUtils.isEmpty(url)) {
368 return false;
369 }
370
371 for (int i = 0; i < noSitePrefs.length; i++) {
372 if (url.startsWith(noSitePrefs[i])) {
373 return false;
374 }
375 }
376 return true;
377 }
378
379 private void stopOrRefresh() {
380 if (mUiController == null) return;
381 if (mTitleBar.isInLoad()) {
382 mUiController.stopLoading();
383 } else {
384 if (mUiController.getCurrentTopWebView() != null) {
385 stopEditingUrl();
386 mUiController.getCurrentTopWebView().reload();
387 }
388 }
389 }
390
391 private void clearOrClose() {
392 if (TextUtils.isEmpty(mUrlInput.getText())) {
393 // close
394 mUrlInput.clearFocus();
395 } else {
396 // clear
397 mUrlInput.setText("");
Enrico Ros1f5a0952014-11-18 20:15:48 -0800398 }
399 }
400
401 void showMenu(View anchor) {
402 Activity activity = mUiController.getActivity();
403 if (mPopupMenu == null) {
404 mPopupMenu = new PopupMenu(getContext(), anchor);
405 mPopupMenu.setOnMenuItemClickListener(this);
406 mPopupMenu.setOnDismissListener(this);
407 if (!activity.onCreateOptionsMenu(mPopupMenu.getMenu())) {
408 mPopupMenu = null;
409 return;
410 }
411 }
412 Menu menu = mPopupMenu.getMenu();
413
414 if (mUiController instanceof Controller) {
415 Controller controller = (Controller) mUiController;
416 if (controller.onPrepareOptionsMenu(menu)) {
417 mOverflowMenuShowing = true;
418 }
419 }
John Reck0f602f32011-07-07 15:38:43 -0700420 }
421
422 @Override
423 public void onFocusChange(View view, boolean hasFocus) {
424 // if losing focus and not in touch mode, leave as is
425 if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) {
426 setFocusState(hasFocus);
427 }
428 if (hasFocus) {
Kevin Hart055e6d82014-12-19 15:53:19 -0800429 Engine.warmUpChildProcessAsync(mUiController.getActivity().getApplicationContext());
John Reck0f602f32011-07-07 15:38:43 -0700430 mBaseUi.showTitleBar();
Dany Rybnikovbcd37da2015-04-20 11:43:15 +0300431 if (!BrowserSettings.getInstance().isPowerSaveModeEnabled()) {
432 //Notify about anticipated network activity
433 NetworkServices.hintUpcomingUserActivity();
434 }
John Reck0f602f32011-07-07 15:38:43 -0700435 } else if (!mUrlInput.needsUpdate()) {
436 mUrlInput.dismissDropDown();
437 mUrlInput.hideIME();
438 if (mUrlInput.getText().length() == 0) {
439 Tab currentTab = mUiController.getTabControl().getCurrentTab();
440 if (currentTab != null) {
John Reck434e9f82011-08-10 18:16:52 -0700441 setDisplayTitle(currentTab.getUrl());
John Reck0f602f32011-07-07 15:38:43 -0700442 }
443 }
John Reck0f602f32011-07-07 15:38:43 -0700444 }
445 mUrlInput.clearNeedsUpdate();
446 }
447
448 protected void setFocusState(boolean focus) {
449 }
450
John Reck0f602f32011-07-07 15:38:43 -0700451 public boolean isEditingUrl() {
452 return mUrlInput.hasFocus();
453 }
454
455 void stopEditingUrl() {
Michael Kolb0b129122012-06-04 16:31:58 -0700456 WebView currentTopWebView = mUiController.getCurrentTopWebView();
457 if (currentTopWebView != null) {
458 currentTopWebView.requestFocus();
459 }
John Reck0f602f32011-07-07 15:38:43 -0700460 }
461
462 void setDisplayTitle(String title) {
463 if (!isEditingUrl()) {
Michael Kolb29aab402012-05-29 17:22:35 -0700464 if (!title.equals(mUrlInput.getText().toString())) {
465 mUrlInput.setText(title, false);
466 }
John Reck0f602f32011-07-07 15:38:43 -0700467 }
468 }
469
John Reck0f602f32011-07-07 15:38:43 -0700470 void setIncognitoMode(boolean incognito) {
471 mUrlInput.setIncognitoMode(incognito);
472 }
473
474 void clearCompletions() {
Narayan Kamathf3174a52011-11-17 14:43:32 +0000475 mUrlInput.dismissDropDown();
John Reck0f602f32011-07-07 15:38:43 -0700476 }
477
478 // UrlInputListener implementation
479
480 /**
481 * callback from suggestion dropdown
482 * user selected a suggestion
483 */
484 @Override
485 public void onAction(String text, String extra, String source) {
Michael Kolb0b129122012-06-04 16:31:58 -0700486 stopEditingUrl();
John Reck0f602f32011-07-07 15:38:43 -0700487 if (UrlInputView.TYPED.equals(source)) {
kaiyizc4ada322013-07-30 09:58:07 +0800488 String url = null;
Panos Thomas4bdb5252014-11-13 16:20:11 -0800489 boolean wap2estore = BrowserConfig.getInstance(getContext())
490 .hasFeature(BrowserConfig.Feature.WAP2ESTORE);
Vivek Sekhar5e631472014-03-31 23:59:10 -0700491 if ((wap2estore && isEstoreTypeUrl(text)) || isRtspTypeUrl(text)
492 || isMakeCallTypeUrl(text)) {
kaiyizc4ada322013-07-30 09:58:07 +0800493 url = text;
494 } else {
495 url = UrlUtils.smartUrlFilter(text, false);
496 }
497
John Reck0f602f32011-07-07 15:38:43 -0700498 Tab t = mBaseUi.getActiveTab();
499 // Only shortcut javascript URIs for now, as there is special
500 // logic in UrlHandler for other schemas
Axesh R. Ajmera1f998ae2015-04-21 14:16:41 -0700501 if (url != null && t != null && url.startsWith("javascript:")) {
John Reck0f602f32011-07-07 15:38:43 -0700502 mUiController.loadUrl(t, url);
503 setDisplayTitle(text);
504 return;
505 }
kaiyizc4ada322013-07-30 09:58:07 +0800506
507 // add for carrier wap2estore feature
508 if (url != null && t != null && wap2estore && isEstoreTypeUrl(url)) {
Vivek Sekharb54614f2014-05-01 19:03:37 -0700509 if (handleEstoreTypeUrl(url)) {
510 setDisplayTitle(text);
511 return;
512 }
kaiyizc4ada322013-07-30 09:58:07 +0800513 }
kaiyiz950eca22013-08-08 11:01:28 +0800514 // add for rtsp scheme feature
515 if (url != null && t != null && isRtspTypeUrl(url)) {
516 if (handleRtspTypeUrl(url)) {
Vivek Sekharb54614f2014-05-01 19:03:37 -0700517 setDisplayTitle(text);
kaiyiz950eca22013-08-08 11:01:28 +0800518 return;
519 }
520 }
Vivek Sekhar5e631472014-03-31 23:59:10 -0700521 // add for "wtai://wp/mc;" scheme feature
522 if (url != null && t != null && isMakeCallTypeUrl(url)) {
523 if (handleMakeCallTypeUrl(url)) {
524 return;
525 }
526 }
John Reck0f602f32011-07-07 15:38:43 -0700527 }
528 Intent i = new Intent();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700529 String action = Intent.ACTION_SEARCH;
John Reck0f602f32011-07-07 15:38:43 -0700530 i.setAction(action);
531 i.putExtra(SearchManager.QUERY, text);
532 if (extra != null) {
533 i.putExtra(SearchManager.EXTRA_DATA_KEY, extra);
534 }
535 if (source != null) {
536 Bundle appData = new Bundle();
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800537 appData.putString("source", source);
538 i.putExtra("source", appData);
John Reck0f602f32011-07-07 15:38:43 -0700539 }
540 mUiController.handleNewIntent(i);
541 setDisplayTitle(text);
542 }
543
Vivek Sekhar5e631472014-03-31 23:59:10 -0700544 private boolean isMakeCallTypeUrl(String url) {
545 String utf8Url = null;
546 try {
547 utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
548 } catch (UnsupportedEncodingException e) {
549 Log.e(TAG, "err " + e);
550 }
551 if (utf8Url != null && utf8Url.startsWith(UrlHandler.SCHEME_WTAI_MC)) {
552 return true;
553 }
554 return false;
555 }
556
557 private boolean handleMakeCallTypeUrl(String url) {
558 // wtai://wp/mc;number
559 // number=string(phone-number)
560 if (url.startsWith(UrlHandler.SCHEME_WTAI_MC)) {
561 Intent intent = new Intent(Intent.ACTION_VIEW,
562 Uri.parse(WebView.SCHEME_TEL +
563 url.substring(UrlHandler.SCHEME_WTAI_MC.length())));
564 getContext().startActivity(intent);
565 // before leaving BrowserActivity, close the empty child tab.
566 // If a new tab is created through JavaScript open to load this
567 // url, we would like to close it as we will load this url in a
568 // different Activity.
569 Tab current = mUiController.getCurrentTab();
570 if (current != null
571 && current.getWebView().copyBackForwardList().getSize() == 0) {
572 mUiController.closeCurrentTab();
573 }
574 return true;
575 }
576 return false;
577 }
578
kaiyizc4ada322013-07-30 09:58:07 +0800579 private boolean isEstoreTypeUrl(String url) {
Vivek Sekharb54614f2014-05-01 19:03:37 -0700580 if (url != null && url.startsWith("estore:")) {
kaiyizc4ada322013-07-30 09:58:07 +0800581 return true;
582 }
583 return false;
584 }
585
Vivek Sekharb54614f2014-05-01 19:03:37 -0700586 private boolean handleEstoreTypeUrl(String url) {
587 if (url.getBytes().length > 256) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800588 Toast.makeText(getContext(), R.string.estore_url_warning, Toast.LENGTH_LONG).show();
Vivek Sekharb54614f2014-05-01 19:03:37 -0700589 return false;
kaiyizc4ada322013-07-30 09:58:07 +0800590 }
Vivek Sekharb54614f2014-05-01 19:03:37 -0700591
592 Intent intent;
593 // perform generic parsing of the URI to turn it into an Intent.
594 try {
595 intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
596 } catch (URISyntaxException ex) {
597 Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
598 return false;
599 }
600
kaiyizc4ada322013-07-30 09:58:07 +0800601 try {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800602 getContext().startActivity(intent);
kaiyizc4ada322013-07-30 09:58:07 +0800603 } catch (ActivityNotFoundException ex) {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800604 String downloadUrl = getContext().getResources().getString(R.string.estore_homepage);
kaiyizc4ada322013-07-30 09:58:07 +0800605 mUiController.loadUrl(mBaseUi.getActiveTab(), downloadUrl);
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800606 Toast.makeText(getContext(), R.string.download_estore_app, Toast.LENGTH_LONG).show();
kaiyizc4ada322013-07-30 09:58:07 +0800607 }
Vivek Sekharb54614f2014-05-01 19:03:37 -0700608
609 return true;
kaiyizc4ada322013-07-30 09:58:07 +0800610 }
611
kaiyiz950eca22013-08-08 11:01:28 +0800612 private boolean isRtspTypeUrl(String url) {
613 String utf8Url = null;
614 try {
615 utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
616 } catch (UnsupportedEncodingException e) {
617 Log.e(TAG, "err " + e);
618 }
619 if (utf8Url != null && utf8Url.startsWith("rtsp://")) {
620 return true;
621 }
622 return false;
623 }
624
625 private boolean handleRtspTypeUrl(String url) {
626 Intent intent;
627 // perform generic parsing of the URI to turn it into an Intent.
628 try {
629 intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
630 } catch (URISyntaxException ex) {
631 Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
632 return false;
633 }
634
635 try {
Bijan Amirzada9b1e9882014-02-26 17:15:46 -0800636 getContext().startActivity(intent);
kaiyiz950eca22013-08-08 11:01:28 +0800637 } catch (ActivityNotFoundException ex) {
638 Log.w("Browser", "No resolveActivity " + url);
639 return false;
640 }
641 return true;
642 }
643
John Reck0f602f32011-07-07 15:38:43 -0700644 @Override
645 public void onDismiss() {
646 final Tab currentTab = mBaseUi.getActiveTab();
647 mBaseUi.hideTitleBar();
648 post(new Runnable() {
649 public void run() {
650 clearFocus();
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700651 if (currentTab != null) {
John Reck0f602f32011-07-07 15:38:43 -0700652 setDisplayTitle(currentTab.getUrl());
653 }
654 }
655 });
656 }
657
658 /**
659 * callback from the suggestion dropdown
660 * copy text to input field and stay in edit mode
661 */
662 @Override
663 public void onCopySuggestion(String text) {
664 mUrlInput.setText(text, true);
665 if (text != null) {
666 mUrlInput.setSelection(text.length());
667 }
668 }
669
670 public void setCurrentUrlIsBookmark(boolean isBookmark) {
671 }
672
673 @Override
674 public boolean dispatchKeyEventPreIme(KeyEvent evt) {
675 if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) {
Sagar Dhawan5a5d01f2015-07-30 17:16:21 -0700676 if (mUiController.getCurrentTab() != null &&
677 mUiController.getCurrentTab().isKeyboardShowing()){
678 stopEditingUrl();
679 return true;
680 }
John Reck0f602f32011-07-07 15:38:43 -0700681 // catch back key in order to do slightly more cleanup than usual
Michael Kolb0b129122012-06-04 16:31:58 -0700682 stopEditingUrl();
John Reck0f602f32011-07-07 15:38:43 -0700683 }
684 return super.dispatchKeyEventPreIme(evt);
685 }
686
John Reck0f602f32011-07-07 15:38:43 -0700687 /**
688 * called from the Ui when the user wants to edit
689 * @param clearInput clear the input field
690 */
Michael Kolb1f9b3562012-04-24 14:38:34 -0700691 void startEditingUrl(boolean clearInput, boolean forceIME) {
John Reck0f602f32011-07-07 15:38:43 -0700692 // editing takes preference of progress
693 setVisibility(View.VISIBLE);
John Reck0f602f32011-07-07 15:38:43 -0700694 if (!mUrlInput.hasFocus()) {
695 mUrlInput.requestFocus();
696 }
697 if (clearInput) {
698 mUrlInput.setText("");
John Reck0f602f32011-07-07 15:38:43 -0700699 }
Michael Kolb1f9b3562012-04-24 14:38:34 -0700700 if (forceIME) {
Michael Kolb4bb6fcb2012-04-13 14:25:27 -0700701 mUrlInput.showIME();
702 }
John Reck0f602f32011-07-07 15:38:43 -0700703 }
704
705 public void onProgressStarted() {
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700706 mFaviconTile.setBadgeBlockedObjectsCount(0);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700707 mFaviconTile.setTrustLevel(SiteTileView.TRUST_UNKNOWN);
Pankaj Garg07b2fd92015-07-15 12:07:37 -0700708 mFaviconTile.setBadgeHasCertIssues(false);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700709 mFaviconTile.replaceFavicon(mDefaultFavicon);
Pankaj Garg96d0ccd2015-07-30 16:49:47 -0700710 setSecurityState(Tab.SecurityState.SECURITY_STATE_NOT_SECURE);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700711 mHandler.removeMessages(WEBREFINER_COUNTER_MSG);
712 mHandler.sendEmptyMessageDelayed(WEBREFINER_COUNTER_MSG,
713 WEBREFINER_COUNTER_MSG_DELAY);
714 mStopButton.setImageResource(R.drawable.ic_action_stop);
715 mStopButton.setContentDescription(getResources().
716 getString(R.string.accessibility_button_stop));
John Reck0f602f32011-07-07 15:38:43 -0700717 }
718
719 public void onProgressStopped() {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700720 if (!isEditingUrl()) {
721 mFaviconTile.setVisibility(View.VISIBLE);
722 }
723 mStopButton.setImageResource(R.drawable.ic_action_reload);
724 mStopButton.setContentDescription(getResources().
725 getString(R.string.accessibility_button_refresh));
John Reck0f602f32011-07-07 15:38:43 -0700726 }
727
John Reck419f6b42011-08-16 16:10:51 -0700728 public void onTabDataChanged(Tab tab) {
729 }
730
Michael Kolb0b129122012-06-04 16:31:58 -0700731 public void onVoiceResult(String s) {
732 startEditingUrl(true, true);
733 onCopySuggestion(s);
734 }
735
Narayan Kamathf3174a52011-11-17 14:43:32 +0000736 @Override
737 public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
738
739 @Override
Michael Kolb5ff5c8b2012-05-03 11:37:58 -0700740 public void onTextChanged(CharSequence s, int start, int before, int count) { }
Narayan Kamathf3174a52011-11-17 14:43:32 +0000741
742 @Override
743 public void afterTextChanged(Editable s) { }
Michael Kolb0b129122012-06-04 16:31:58 -0700744
Enrico Ros1f5a0952014-11-18 20:15:48 -0800745 @Override
746 public void onStateChanged(int state) {
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700747 mVoiceButton.setVisibility(View.GONE);
Sagar Dhawan84ef4442015-07-29 12:08:10 -0700748 mClearButton.setVisibility(View.GONE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800749 switch(state) {
750 case STATE_NORMAL:
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700751 mFaviconTile.setVisibility(View.VISIBLE);
752 mMagnify.setVisibility(View.GONE);
Sagar Dhawanaff56c92015-07-13 15:57:11 -0700753 mMore.setVisibility(View.VISIBLE);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700754 if (mUiController != null) {
755 Tab currentTab = mUiController.getCurrentTab();
756 if (currentTab != null){
757 if (TextUtils.isEmpty(currentTab.getUrl())) {
758 mFaviconTile.setVisibility(View.GONE);
759 mMagnify.setVisibility(View.VISIBLE);
760 }
761 }
762 mUiController.setWindowDimming(0.0f);
763 }
764
Enrico Ros1f5a0952014-11-18 20:15:48 -0800765 break;
766 case STATE_HIGHLIGHTED:
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700767 mFaviconTile.setVisibility(View.GONE);
Sagar Dhawan84ef4442015-07-29 12:08:10 -0700768 mMagnify.setVisibility(View.VISIBLE);
769 mClearButton.setVisibility(View.VISIBLE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800770 mMore.setVisibility(View.GONE);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700771 if (mUiController != null) {
772 mUiController.setWindowDimming(0.75f);
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700773 }
Enrico Ros1f5a0952014-11-18 20:15:48 -0800774 break;
775 case STATE_EDITED:
Sagar Dhawan84ef4442015-07-29 12:08:10 -0700776 if (TextUtils.isEmpty(mUrlInput.getText()) &&
777 mUiController != null &&
778 mUiController.supportsVoice()) {
779 mVoiceButton.setVisibility(View.VISIBLE);
780 }
781 else {
782 mClearButton.setVisibility(View.VISIBLE);
783 }
Pankaj Garg66f8cef2015-07-07 17:29:03 -0700784 mFaviconTile.setVisibility(View.GONE);
785 mMagnify.setVisibility(View.VISIBLE);
Enrico Ros1f5a0952014-11-18 20:15:48 -0800786 mMore.setVisibility(View.GONE);
787 break;
788 }
789 }
790
791 public boolean isMenuShowing() {
792 return mOverflowMenuShowing;
793 }
794
795
796 @Override
797 public void onDismiss(PopupMenu popupMenu) {
798 if (popupMenu == mPopupMenu) {
799 onMenuHidden();
800 }
801 }
802
803 private void onMenuHidden() {
804 mOverflowMenuShowing = false;
Enrico Ros1f5a0952014-11-18 20:15:48 -0800805 }
806
807
808 @Override
809 public boolean onMenuItemClick(MenuItem item) {
810 return mUiController.onOptionsItemSelected(item);
811 }
John Reck0f602f32011-07-07 15:38:43 -0700812}