| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.preferences; | 5 package org.chromium.chrome.browser.preferences; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.content.Intent; | 8 import android.content.Intent; |
| 9 import android.content.SharedPreferences; | 9 import android.content.SharedPreferences; |
| 10 import android.content.res.Resources; | 10 import android.content.res.Resources; |
| 11 import android.os.Build; | 11 import android.os.Build; |
| 12 import android.os.Bundle; | 12 import android.os.Bundle; |
| 13 import android.text.SpannableString; | 13 import android.text.SpannableString; |
| 14 import android.text.style.ForegroundColorSpan; | 14 import android.text.style.ForegroundColorSpan; |
| 15 import android.view.LayoutInflater; | 15 import android.view.LayoutInflater; |
| 16 import android.view.View; | 16 import android.view.View; |
| 17 import android.view.View.AccessibilityDelegate; | 17 import android.view.View.AccessibilityDelegate; |
| 18 import android.view.View.OnClickListener; | 18 import android.view.View.OnClickListener; |
| 19 import android.view.ViewGroup; | 19 import android.view.ViewGroup; |
| 20 import android.view.accessibility.AccessibilityEvent; | 20 import android.view.accessibility.AccessibilityEvent; |
| 21 import android.view.accessibility.AccessibilityNodeInfo; | 21 import android.view.accessibility.AccessibilityNodeInfo; |
| 22 import android.widget.BaseAdapter; | 22 import android.widget.BaseAdapter; |
| 23 import android.widget.RadioButton; | 23 import android.widget.RadioButton; |
| 24 import android.widget.TextView; | 24 import android.widget.TextView; |
| 25 | 25 |
| 26 import org.chromium.base.ApiCompatibilityUtils; | 26 import org.chromium.base.ApiCompatibilityUtils; |
| 27 import org.chromium.base.ContextUtils; | 27 import org.chromium.base.ContextUtils; |
| 28 import org.chromium.base.Log; |
| 28 import org.chromium.base.VisibleForTesting; | 29 import org.chromium.base.VisibleForTesting; |
| 29 import org.chromium.base.metrics.RecordUserAction; | 30 import org.chromium.base.metrics.RecordUserAction; |
| 30 import org.chromium.chrome.R; | 31 import org.chromium.chrome.R; |
| 31 import org.chromium.chrome.browser.ChromeFeatureList; | 32 import org.chromium.chrome.browser.ChromeFeatureList; |
| 32 import org.chromium.chrome.browser.locale.LocaleManager; | 33 import org.chromium.chrome.browser.locale.LocaleManager; |
| 33 import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader; | 34 import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader; |
| 34 import org.chromium.chrome.browser.preferences.website.ContentSetting; | 35 import org.chromium.chrome.browser.preferences.website.ContentSetting; |
| 35 import org.chromium.chrome.browser.preferences.website.GeolocationInfo; | 36 import org.chromium.chrome.browser.preferences.website.GeolocationInfo; |
| 36 import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences; | 37 import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences; |
| 37 import org.chromium.chrome.browser.preferences.website.WebsitePreferenceBridge; | 38 import org.chromium.chrome.browser.preferences.website.WebsitePreferenceBridge; |
| 38 import org.chromium.chrome.browser.search_engines.TemplateUrlService; | 39 import org.chromium.chrome.browser.search_engines.TemplateUrlService; |
| 39 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrl
; | 40 import org.chromium.chrome.browser.search_engines.TemplateUrlService.TemplateUrl
; |
| 40 import org.chromium.components.location.LocationUtils; | 41 import org.chromium.components.location.LocationUtils; |
| 41 import org.chromium.ui.text.SpanApplier; | 42 import org.chromium.ui.text.SpanApplier; |
| 42 import org.chromium.ui.text.SpanApplier.SpanInfo; | 43 import org.chromium.ui.text.SpanApplier.SpanInfo; |
| 43 | 44 |
| 44 import java.util.ArrayList; | 45 import java.util.ArrayList; |
| 45 import java.util.List; | 46 import java.util.List; |
| 46 | 47 |
| 47 /** | 48 /** |
| 48 * A custom adapter for listing search engines. | 49 * A custom adapter for listing search engines. |
| 49 */ | 50 */ |
| 50 public class SearchEngineAdapter extends BaseAdapter | 51 public class SearchEngineAdapter extends BaseAdapter |
| 51 implements TemplateUrlService.LoadListener, TemplateUrlService.TemplateU
rlServiceObserver, | 52 implements TemplateUrlService.LoadListener, TemplateUrlService.TemplateU
rlServiceObserver, |
| 52 OnClickListener { | 53 OnClickListener { |
| 54 private static final String TAG = "cr_SearchEngines"; |
| 55 |
| 53 private static final int VIEW_TYPE_ITEM = 0; | 56 private static final int VIEW_TYPE_ITEM = 0; |
| 54 private static final int VIEW_TYPE_DIVIDER = 1; | 57 private static final int VIEW_TYPE_DIVIDER = 1; |
| 55 private static final int VIEW_TYPE_COUNT = 2; | 58 private static final int VIEW_TYPE_COUNT = 2; |
| 56 | 59 |
| 57 /** The current context. */ | 60 /** The current context. */ |
| 58 private Context mContext; | 61 private Context mContext; |
| 59 | 62 |
| 60 /** The layout inflater to use for the custom views. */ | 63 /** The layout inflater to use for the custom views. */ |
| 61 private LayoutInflater mLayoutInflater; | 64 private LayoutInflater mLayoutInflater; |
| 62 | 65 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 if (position == mPrepopulatedSearchEngines.size() && mRecentSearchEngine
s.size() != 0) { | 244 if (position == mPrepopulatedSearchEngines.size() && mRecentSearchEngine
s.size() != 0) { |
| 242 return VIEW_TYPE_DIVIDER; | 245 return VIEW_TYPE_DIVIDER; |
| 243 } else { | 246 } else { |
| 244 return VIEW_TYPE_ITEM; | 247 return VIEW_TYPE_ITEM; |
| 245 } | 248 } |
| 246 } | 249 } |
| 247 | 250 |
| 248 @Override | 251 @Override |
| 249 public View getView(int position, View convertView, ViewGroup parent) { | 252 public View getView(int position, View convertView, ViewGroup parent) { |
| 250 View view = convertView; | 253 View view = convertView; |
| 251 TemplateUrl templateUrl = (TemplateUrl) getItem(position); | |
| 252 int itemViewType = getItemViewType(position); | 254 int itemViewType = getItemViewType(position); |
| 253 if (convertView == null) { | 255 if (convertView == null) { |
| 254 view = mLayoutInflater.inflate( | 256 view = mLayoutInflater.inflate( |
| 255 itemViewType == VIEW_TYPE_DIVIDER && mRecentSearchEngines.si
ze() != 0 | 257 itemViewType == VIEW_TYPE_DIVIDER && mRecentSearchEngines.si
ze() != 0 |
| 256 ? R.layout.search_engine_recent_title | 258 ? R.layout.search_engine_recent_title |
| 257 : R.layout.search_engine, | 259 : R.layout.search_engine, |
| 258 null); | 260 null); |
| 259 } | 261 } |
| 260 if (itemViewType == VIEW_TYPE_DIVIDER) { | 262 if (itemViewType == VIEW_TYPE_DIVIDER) { |
| 261 return view; | 263 return view; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 273 // TODO(finnur): Remove the encompassing if statement once we go back to
using the AppCompat | 275 // TODO(finnur): Remove the encompassing if statement once we go back to
using the AppCompat |
| 274 // control. | 276 // control. |
| 275 final boolean selected = position == mSelectedSearchEnginePosition; | 277 final boolean selected = position == mSelectedSearchEnginePosition; |
| 276 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | 278 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
| 277 radioButton.setBackgroundResource(0); | 279 radioButton.setBackgroundResource(0); |
| 278 } | 280 } |
| 279 radioButton.setChecked(selected); | 281 radioButton.setChecked(selected); |
| 280 | 282 |
| 281 TextView description = (TextView) view.findViewById(R.id.name); | 283 TextView description = (TextView) view.findViewById(R.id.name); |
| 282 Resources resources = mContext.getResources(); | 284 Resources resources = mContext.getResources(); |
| 285 |
| 286 TemplateUrl templateUrl = (TemplateUrl) getItem(position); |
| 283 description.setText(templateUrl.getShortName()); | 287 description.setText(templateUrl.getShortName()); |
| 284 | 288 |
| 285 TextView url = (TextView) view.findViewById(R.id.url); | 289 TextView url = (TextView) view.findViewById(R.id.url); |
| 286 url.setText(templateUrl.getKeyword()); | 290 url.setText(templateUrl.getKeyword()); |
| 287 if (templateUrl.getType() == TemplateUrlService.TYPE_PREPOPULATED | 291 if (templateUrl.getType() == TemplateUrlService.TYPE_PREPOPULATED |
| 288 || templateUrl.getType() == TemplateUrlService.TYPE_DEFAULT | 292 || templateUrl.getType() == TemplateUrlService.TYPE_DEFAULT |
| 289 || templateUrl.getKeyword().length() == 0) { | 293 || templateUrl.getKeyword().length() == 0) { |
| 290 url.setVisibility(View.GONE); | 294 url.setVisibility(View.GONE); |
| 291 } | 295 } |
| 292 | 296 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 304 @Override | 308 @Override |
| 305 public void onInitializeAccessibilityNodeInfo(View host, Accessibili
tyNodeInfo info) { | 309 public void onInitializeAccessibilityNodeInfo(View host, Accessibili
tyNodeInfo info) { |
| 306 super.onInitializeAccessibilityNodeInfo(host, info); | 310 super.onInitializeAccessibilityNodeInfo(host, info); |
| 307 info.setCheckable(true); | 311 info.setCheckable(true); |
| 308 info.setChecked(selected); | 312 info.setChecked(selected); |
| 309 } | 313 } |
| 310 }); | 314 }); |
| 311 | 315 |
| 312 TextView link = (TextView) view.findViewById(R.id.location_permission); | 316 TextView link = (TextView) view.findViewById(R.id.location_permission); |
| 313 link.setVisibility(selected ? View.VISIBLE : View.GONE); | 317 link.setVisibility(selected ? View.VISIBLE : View.GONE); |
| 314 if (selected) { | 318 if (TemplateUrlService.getInstance().getSearchEngineUrlFromTemplateUrl( |
| 315 if (getLocationPermissionType(position, true) == ContentSetting.ASK)
{ | 319 templateUrl.getKeyword()) == null) { |
| 320 Log.e(TAG, "Invalid template URL found: %s", templateUrl); |
| 321 assert false; |
| 322 link.setVisibility(View.GONE); |
| 323 } else if (selected) { |
| 324 if (getLocationPermissionType(templateUrl, true) == ContentSetting.A
SK) { |
| 316 link.setVisibility(View.GONE); | 325 link.setVisibility(View.GONE); |
| 317 } else { | 326 } else { |
| 318 ForegroundColorSpan linkSpan = new ForegroundColorSpan( | 327 ForegroundColorSpan linkSpan = new ForegroundColorSpan( |
| 319 ApiCompatibilityUtils.getColor(resources, R.color.google
_blue_700)); | 328 ApiCompatibilityUtils.getColor(resources, R.color.google
_blue_700)); |
| 320 if (LocationUtils.getInstance().isSystemLocationSettingEnabled()
) { | 329 if (LocationUtils.getInstance().isSystemLocationSettingEnabled()
) { |
| 321 String message = mContext.getString( | 330 String message = mContext.getString( |
| 322 locationEnabled(position, true) | 331 locationEnabled(templateUrl, true) |
| 323 ? R.string.search_engine_location_allowed | 332 ? R.string.search_engine_location_allowed |
| 324 : R.string.search_engine_location_blocked); | 333 : R.string.search_engine_location_blocked); |
| 325 SpannableString messageWithLink = new SpannableString(messag
e); | 334 SpannableString messageWithLink = new SpannableString(messag
e); |
| 326 messageWithLink.setSpan(linkSpan, 0, messageWithLink.length(
), 0); | 335 messageWithLink.setSpan(linkSpan, 0, messageWithLink.length(
), 0); |
| 327 link.setText(messageWithLink); | 336 link.setText(messageWithLink); |
| 328 } else { | 337 } else { |
| 329 link.setText(SpanApplier.applySpans( | 338 link.setText(SpanApplier.applySpans( |
| 330 mContext.getString(R.string.android_location_off), | 339 mContext.getString(R.string.android_location_off), |
| 331 new SpanInfo("<link>", "</link>", linkSpan))); | 340 new SpanInfo("<link>", "</link>", linkSpan))); |
| 332 } | 341 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 362 searchEngineSelected((int) view.getTag()); | 371 searchEngineSelected((int) view.getTag()); |
| 363 } | 372 } |
| 364 } | 373 } |
| 365 | 374 |
| 366 private String searchEngineSelected(int position) { | 375 private String searchEngineSelected(int position) { |
| 367 // First clean up any automatically added permissions (if any) for the p
reviously selected | 376 // First clean up any automatically added permissions (if any) for the p
reviously selected |
| 368 // search engine. | 377 // search engine. |
| 369 SharedPreferences sharedPreferences = | 378 SharedPreferences sharedPreferences = |
| 370 ContextUtils.getAppSharedPreferences(); | 379 ContextUtils.getAppSharedPreferences(); |
| 371 if (sharedPreferences.getBoolean(PrefServiceBridge.LOCATION_AUTO_ALLOWED
, false)) { | 380 if (sharedPreferences.getBoolean(PrefServiceBridge.LOCATION_AUTO_ALLOWED
, false)) { |
| 372 if (locationEnabled(mSelectedSearchEnginePosition, false)) { | 381 TemplateUrl templateUrl = (TemplateUrl) getItem(mSelectedSearchEngin
ePosition); |
| 382 if (locationEnabled(templateUrl, false)) { |
| 373 String url = TemplateUrlService.getInstance().getSearchEngineUrl
FromTemplateUrl( | 383 String url = TemplateUrlService.getInstance().getSearchEngineUrl
FromTemplateUrl( |
| 374 toKeyword(mSelectedSearchEnginePosition)); | 384 templateUrl.getKeyword()); |
| 375 WebsitePreferenceBridge.nativeSetGeolocationSettingForOrigin( | 385 WebsitePreferenceBridge.nativeSetGeolocationSettingForOrigin( |
| 376 url, url, ContentSetting.DEFAULT.toInt(), false); | 386 url, url, ContentSetting.DEFAULT.toInt(), false); |
| 377 } | 387 } |
| 378 sharedPreferences.edit().remove(PrefServiceBridge.LOCATION_AUTO_ALLO
WED).apply(); | 388 sharedPreferences.edit().remove(PrefServiceBridge.LOCATION_AUTO_ALLO
WED).apply(); |
| 379 } | 389 } |
| 380 | 390 |
| 381 // Record the change in search engine. | 391 // Record the change in search engine. |
| 382 mSelectedSearchEnginePosition = position; | 392 mSelectedSearchEnginePosition = position; |
| 383 | 393 |
| 384 String keyword = toKeyword(mSelectedSearchEnginePosition); | 394 String keyword = toKeyword(mSelectedSearchEnginePosition); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 397 private void onLocationLinkClicked() { | 407 private void onLocationLinkClicked() { |
| 398 if (!LocationUtils.getInstance().isSystemLocationSettingEnabled()) { | 408 if (!LocationUtils.getInstance().isSystemLocationSettingEnabled()) { |
| 399 mContext.startActivity(LocationUtils.getInstance().getSystemLocation
SettingsIntent()); | 409 mContext.startActivity(LocationUtils.getInstance().getSystemLocation
SettingsIntent()); |
| 400 } else { | 410 } else { |
| 401 Intent settingsIntent = PreferencesLauncher.createIntentForSettingsP
age( | 411 Intent settingsIntent = PreferencesLauncher.createIntentForSettingsP
age( |
| 402 mContext, SingleWebsitePreferences.class.getName()); | 412 mContext, SingleWebsitePreferences.class.getName()); |
| 403 String url = TemplateUrlService.getInstance().getSearchEngineUrlFrom
TemplateUrl( | 413 String url = TemplateUrlService.getInstance().getSearchEngineUrlFrom
TemplateUrl( |
| 404 toKeyword(mSelectedSearchEnginePosition)); | 414 toKeyword(mSelectedSearchEnginePosition)); |
| 405 Bundle fragmentArgs = SingleWebsitePreferences.createFragmentArgsFor
Site(url); | 415 Bundle fragmentArgs = SingleWebsitePreferences.createFragmentArgsFor
Site(url); |
| 406 fragmentArgs.putBoolean(SingleWebsitePreferences.EXTRA_LOCATION, | 416 fragmentArgs.putBoolean(SingleWebsitePreferences.EXTRA_LOCATION, |
| 407 locationEnabled(mSelectedSearchEnginePosition, true)); | 417 locationEnabled((TemplateUrl) getItem(mSelectedSearchEngineP
osition), true)); |
| 408 settingsIntent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, f
ragmentArgs); | 418 settingsIntent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, f
ragmentArgs); |
| 409 mContext.startActivity(settingsIntent); | 419 mContext.startActivity(settingsIntent); |
| 410 } | 420 } |
| 411 } | 421 } |
| 412 | 422 |
| 413 private ContentSetting getLocationPermissionType(int position, boolean check
GeoHeader) { | 423 private ContentSetting getLocationPermissionType( |
| 414 if (position == -1) { | 424 TemplateUrl templateUrl, boolean checkGeoHeader) { |
| 425 if (templateUrl == null) { |
| 426 Log.e(TAG, "Invalid null template URL found"); |
| 427 assert false; |
| 415 return ContentSetting.BLOCK; | 428 return ContentSetting.BLOCK; |
| 416 } | 429 } |
| 417 | 430 |
| 418 String url = TemplateUrlService.getInstance().getSearchEngineUrlFromTemp
lateUrl( | 431 String url = TemplateUrlService.getInstance().getSearchEngineUrlFromTemp
lateUrl( |
| 419 toKeyword(position)); | 432 templateUrl.getKeyword()); |
| 433 if (url == null) { |
| 434 Log.e(TAG, "Invalid template URL found: %s", templateUrl); |
| 435 assert false; |
| 436 return ContentSetting.BLOCK; |
| 437 } |
| 420 GeolocationInfo locationSettings = new GeolocationInfo(url, null, false)
; | 438 GeolocationInfo locationSettings = new GeolocationInfo(url, null, false)
; |
| 421 ContentSetting locationPermission = locationSettings.getContentSetting()
; | 439 ContentSetting locationPermission = locationSettings.getContentSetting()
; |
| 422 if (locationPermission == ContentSetting.ASK) { | 440 if (locationPermission == ContentSetting.ASK) { |
| 423 // Handle the case where the geoHeader being sent when no permission
has been specified. | 441 // Handle the case where the geoHeader being sent when no permission
has been specified. |
| 424 if (checkGeoHeader) { | 442 if (checkGeoHeader) { |
| 425 if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONSISTENT_OMN
IBOX_GEOLOCATION)) { | 443 if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONSISTENT_OMN
IBOX_GEOLOCATION)) { |
| 426 if (WebsitePreferenceBridge.shouldUseDSEGeolocationSetting(u
rl, false)) { | 444 if (WebsitePreferenceBridge.shouldUseDSEGeolocationSetting(u
rl, false)) { |
| 427 locationPermission = WebsitePreferenceBridge.getDSEGeolo
cationSetting() | 445 locationPermission = WebsitePreferenceBridge.getDSEGeolo
cationSetting() |
| 428 ? ContentSetting.ALLOW | 446 ? ContentSetting.ALLOW |
| 429 : ContentSetting.BLOCK; | 447 : ContentSetting.BLOCK; |
| 430 } | 448 } |
| 431 } else if (GeolocationHeader.isGeoHeaderEnabledForUrl(url, false
)) { | 449 } else if (GeolocationHeader.isGeoHeaderEnabledForUrl(url, false
)) { |
| 432 locationPermission = ContentSetting.ALLOW; | 450 locationPermission = ContentSetting.ALLOW; |
| 433 } | 451 } |
| 434 } | 452 } |
| 435 } | 453 } |
| 436 return locationPermission; | 454 return locationPermission; |
| 437 } | 455 } |
| 438 | 456 |
| 439 private boolean locationEnabled(int position, boolean checkGeoHeader) { | 457 private boolean locationEnabled(TemplateUrl templateUrl, boolean checkGeoHea
der) { |
| 440 return getLocationPermissionType(position, checkGeoHeader) == ContentSet
ting.ALLOW; | 458 return getLocationPermissionType(templateUrl, checkGeoHeader) == Content
Setting.ALLOW; |
| 441 } | 459 } |
| 442 | 460 |
| 443 private int computeStartIndexForRecentSearchEngines() { | 461 private int computeStartIndexForRecentSearchEngines() { |
| 444 // If there are custom search engines to show, add 1 for showing the "R
ecently visited" | 462 // If there are custom search engines to show, add 1 for showing the "R
ecently visited" |
| 445 // header. | 463 // header. |
| 446 if (mRecentSearchEngines.size() > 0) { | 464 if (mRecentSearchEngines.size() > 0) { |
| 447 return mPrepopulatedSearchEngines.size() + 1; | 465 return mPrepopulatedSearchEngines.size() + 1; |
| 448 } else { | 466 } else { |
| 449 return mPrepopulatedSearchEngines.size(); | 467 return mPrepopulatedSearchEngines.size(); |
| 450 } | 468 } |
| 451 } | 469 } |
| 452 } | 470 } |
| OLD | NEW |