DO NOT MERGE - Update and fix RLZ code:
- Cache RLZ parameter
- Set RLZ parameter for address bar searches
- Add broadcast receiver to handle RLZ updates
- Update RLZ parameters in home page and bookmarks
Bug: 4436761
Change-Id: I505932656c68dca458283598c2f647e035f120d3
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 440a141..0f6cb13 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -208,6 +208,11 @@
This value signifies to the RLZ client that this application uses RLZ tracking. -->
<meta-data android:name="com.google.android.partnersetup.RLZ_ACCESS_POINT"
android:value="@string/rlz_access_point" />
+ <receiver android:name=".RlzReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.RLZ_VALUES_UPDATED"/>
+ </intent-filter>
+ </receiver>
<receiver android:name=".OpenDownloadReceiver">
<intent-filter>
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 357d1e9..9ae2a25 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -23,16 +23,20 @@
import android.app.ActivityManager;
import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.Browser;
+import android.provider.BrowserContract.Bookmarks;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.GeolocationPermissions;
@@ -205,6 +209,8 @@
private HashMap<WebSettings,Observer> mWebSettingsToObservers =
new HashMap<WebSettings,Observer>();
+ private String mRlzValue = "";
+
private boolean mLoadFromDbComplete;
public void waitForLoadFromDbToComplete() {
@@ -892,4 +898,115 @@
updateSearchEngine(mController.getActivity(), searchEngineName, false);
}
}
+
+ /*package*/ String getRlzValue() {
+ return mRlzValue;
+ }
+
+ /*package*/ void updateRlzValues(Context context) {
+ // Use AsyncTask because this queries both RlzProvider and Bookmarks URIs
+ new RlzUpdateTask(context).execute();
+ }
+
+ private class RlzUpdateTask extends AsyncTask<Void, Void, Void> {
+ private final Context context;
+
+ public RlzUpdateTask(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ protected Void doInBackground(Void...unused) {
+ String rlz = retrieveRlzValue(context);
+ if (!rlz.isEmpty()) {
+ mRlzValue = rlz;
+ updateHomePageRlzParameter(context);
+ updateBookmarksRlzParameter(context);
+ }
+ return null;
+ }
+ }
+
+ // Update RLZ value if present in Home page
+ private void updateHomePageRlzParameter(Context context) {
+ Uri uri = Uri.parse(homeUrl);
+ if ((uri.getQueryParameter("rlz") != null) && UrlUtils.isGoogleUri(uri)) {
+ String newHomeUrl = updateRlzParameter(homeUrl);
+ if (!homeUrl.equals(newHomeUrl)) {
+ setHomePage(context, newHomeUrl);
+ }
+ }
+ }
+
+ // Update RLZ value if present in bookmarks
+ private void updateBookmarksRlzParameter(Context context) {
+ Cursor cur = null;
+ try {
+ cur = context.getContentResolver().query(Bookmarks.CONTENT_URI_DEFAULT_FOLDER,
+ new String[] { Bookmarks._ID, Bookmarks.URL }, "url LIKE '%rlz=%'", null, null);
+ if ((cur == null) || (cur.getCount() == 0)) {
+ return;
+ }
+ for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
+ long id = cur.getLong(0);
+ String url = cur.getString(1);
+ if ((url == null) || url.isEmpty()) {
+ continue;
+ }
+
+ Uri uri = Uri.parse(url);
+ if ((uri.getQueryParameter("rlz") != null) && UrlUtils.isGoogleUri(uri)) {
+ String newUrl = updateRlzParameter(url);
+ if (!url.equals(newUrl)) {
+ ContentValues values = new ContentValues();
+ values.put(Bookmarks.URL, newUrl);
+ Uri bookmarkUri = ContentUris.withAppendedId(
+ BookmarkUtils.getBookmarksUri(context), id);
+ context.getContentResolver().update(bookmarkUri, values, null, null);
+ }
+ }
+ }
+ } finally {
+ if (cur != null) {
+ cur.close();
+ }
+ }
+ }
+
+ private String updateRlzParameter(String url) {
+ Uri uri = Uri.parse(url);
+ String oldRlz = uri.getQueryParameter("rlz");
+ if (oldRlz != null) {
+ return url.replace("rlz=" + oldRlz, "rlz=" + mRlzValue);
+ }
+ return url;
+ }
+
+ // Retrieve the RLZ value from the Rlz Provider
+ private static String retrieveRlzValue(Context context) {
+ String rlz = "";
+ PackageManager pm = context.getPackageManager();
+ if (pm.resolveContentProvider(RLZ_PROVIDER, 0) == null) {
+ return rlz;
+ }
+
+ String ap = context.getResources().getString(R.string.rlz_access_point);
+ if (ap.isEmpty()) {
+ return rlz;
+ }
+
+ Uri rlzUri = Uri.withAppendedPath(RLZ_PROVIDER_URI, ap);
+ Cursor cur = null;
+ try {
+ cur = context.getContentResolver().query(rlzUri, null, null, null, null);
+ if (cur != null && cur.moveToFirst() && !cur.isNull(0)) {
+ rlz = cur.getString(0);
+ }
+ } finally {
+ if (cur != null) {
+ cur.close();
+ }
+ }
+ return rlz;
+ }
}
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index a028882..dcb62a6 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -80,7 +80,6 @@
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;
-
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URLEncoder;
@@ -219,6 +218,7 @@
mDataController = DataController.getInstance(mActivity);
mTabControl = new TabControl(this);
mSettings.setController(this);
+ mSettings.updateRlzValues(mActivity);
mUrlHandler = new UrlHandler(this);
mIntentHandler = new IntentHandler(mActivity, this);
@@ -2441,7 +2441,7 @@
return bundle;
}
- /**
+ /**
* helper method for key handler
* returns the current tab if it can't advance
*/
diff --git a/src/com/android/browser/IntentHandler.java b/src/com/android/browser/IntentHandler.java
index fa8bfbc..b556638 100644
--- a/src/com/android/browser/IntentHandler.java
+++ b/src/com/android/browser/IntentHandler.java
@@ -221,6 +221,17 @@
headers.put(key, pairs.getString(key));
}
}
+
+ // AppId will be set to the Browser for Search Bar initiated searches
+ final String appId = intent.getStringExtra(Browser.EXTRA_APPLICATION_ID);
+ if (mActivity.getPackageName().equals(appId)) {
+ String rlz = mSettings.getRlzValue();
+ Uri uri = Uri.parse(url);
+ if (!rlz.isEmpty() && needsRlz(uri)) {
+ Uri rlzUri = addRlzParameter(uri, rlz);
+ url = rlzUri.toString();
+ }
+ }
}
} else if (Intent.ACTION_SEARCH.equals(action)
|| MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
@@ -364,4 +375,19 @@
}
}
+ private static boolean needsRlz(Uri uri) {
+ if ((uri.getQueryParameter("rlz") == null) &&
+ (uri.getQueryParameter("q") != null) &&
+ UrlUtils.isGoogleUri(uri)) {
+ return true;
+ }
+ return false;
+ }
+
+ private static Uri addRlzParameter(Uri uri, String rlz) {
+ if (rlz.isEmpty()) {
+ return uri;
+ }
+ return uri.buildUpon().appendQueryParameter("rlz", rlz).build();
+ }
}
diff --git a/src/com/android/browser/RlzReceiver.java b/src/com/android/browser/RlzReceiver.java
new file mode 100644
index 0000000..1dfb11a
--- /dev/null
+++ b/src/com/android/browser/RlzReceiver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+/**
+ * This {@link BroadcastReceiver} handles RLZ broadcast notifications.
+ */
+public class RlzReceiver extends BroadcastReceiver {
+ public static final String RLZ_VALUES_UPDATED_ACTION =
+ "android.intent.action.RLZ_VALUES_UPDATED";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (RLZ_VALUES_UPDATED_ACTION.equals(action)) {
+ BrowserSettings settings = BrowserSettings.getInstance();
+ settings.updateRlzValues(context);
+ }
+ }
+}
diff --git a/src/com/android/browser/UrlHandler.java b/src/com/android/browser/UrlHandler.java
index 03bab9b..b23dc7d 100644
--- a/src/com/android/browser/UrlHandler.java
+++ b/src/com/android/browser/UrlHandler.java
@@ -22,9 +22,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.database.Cursor;
import android.net.Uri;
-import android.os.AsyncTask;
import android.util.Log;
import android.webkit.WebView;
@@ -46,9 +44,6 @@
Controller mController;
Activity mActivity;
- private Boolean mIsProviderPresent = null;
- private Uri mRlzUri = null;
-
public UrlHandler(Controller controller) {
mController = controller;
mActivity = mController.getActivity();
@@ -97,20 +92,6 @@
return false;
}
- // If this is a Google search, attempt to add an RLZ string
- // (if one isn't already present).
- if (rlzProviderPresent()) {
- Uri siteUri = Uri.parse(url);
- if (needsRlzString(siteUri)) {
- // Need to look up the RLZ info from a database, so do it in an
- // AsyncTask. Although we are not overriding the URL load synchronously,
- // we guarantee that we will handle this URL load after the task executes,
- // so it's safe to just return true to WebCore now to stop its own loading.
- new RLZTask(tab, siteUri, view).execute();
- return true;
- }
- }
-
if (startActivityForUrl(url)) {
return true;
}
@@ -218,112 +199,4 @@
return false;
}
-
- // TODO: Move this class into Tab, where it can be properly stopped upon
- // closure of the tab
- private class RLZTask extends AsyncTask<Void, Void, String> {
- private Tab mTab;
- private Uri mSiteUri;
- private WebView mWebView;
-
- public RLZTask(Tab tab, Uri uri, WebView webView) {
- mTab = tab;
- mSiteUri = uri;
- mWebView = webView;
- }
-
- protected String doInBackground(Void... unused) {
- String result = mSiteUri.toString();
- Cursor cur = null;
- try {
- cur = mActivity.getContentResolver()
- .query(getRlzUri(), null, null, null, null);
- if (cur != null && cur.moveToFirst() && !cur.isNull(0)) {
- result = mSiteUri.buildUpon()
- .appendQueryParameter("rlz", cur.getString(0))
- .build().toString();
- }
- } finally {
- if (cur != null) {
- cur.close();
- }
- }
- return result;
- }
-
- protected void onPostExecute(String result) {
- // Make sure the Tab was not closed while handling the task
- if (mController.getTabControl().getTabIndex(mTab) != -1) {
- // If the Activity Manager is not invoked, load the URL directly
- if (!startActivityForUrl(result)) {
- if (!handleMenuClick(mTab, result)) {
- mController.loadUrl(mWebView, result);
- }
- }
- }
- }
- }
-
- // Determine whether the RLZ provider is present on the system.
- private boolean rlzProviderPresent() {
- if (mIsProviderPresent == null) {
- PackageManager pm = mActivity.getPackageManager();
- mIsProviderPresent = pm.resolveContentProvider(
- BrowserSettings.RLZ_PROVIDER, 0) != null;
- }
- return mIsProviderPresent;
- }
-
- // Retrieve the RLZ access point string and cache the URI used to
- // retrieve RLZ values.
- private Uri getRlzUri() {
- if (mRlzUri == null) {
- String ap = mActivity.getResources()
- .getString(R.string.rlz_access_point);
- mRlzUri = Uri.withAppendedPath(BrowserSettings.RLZ_PROVIDER_URI, ap);
- }
- return mRlzUri;
- }
-
- // Determine if this URI appears to be for a Google search
- // and does not have an RLZ parameter.
- // Taken largely from Chrome source, src/chrome/browser/google_url_tracker.cc
- private static boolean needsRlzString(Uri uri) {
- String scheme = uri.getScheme();
- if (("http".equals(scheme) || "https".equals(scheme)) &&
- (uri.getQueryParameter("q") != null) &&
- (uri.getQueryParameter("rlz") == null)) {
- String host = uri.getHost();
- if (host == null) {
- return false;
- }
- String[] hostComponents = host.split("\\.");
-
- if (hostComponents.length < 2) {
- return false;
- }
- int googleComponent = hostComponents.length - 2;
- String component = hostComponents[googleComponent];
- if (!"google".equals(component)) {
- if (hostComponents.length < 3 ||
- (!"co".equals(component) && !"com".equals(component))) {
- return false;
- }
- googleComponent = hostComponents.length - 3;
- if (!"google".equals(hostComponents[googleComponent])) {
- return false;
- }
- }
-
- // Google corp network handling.
- if (googleComponent > 0 && "corp".equals(
- hostComponents[googleComponent - 1])) {
- return false;
- }
-
- return true;
- }
- return false;
- }
-
}
diff --git a/src/com/android/browser/UrlUtils.java b/src/com/android/browser/UrlUtils.java
index d6278ca..8c789db 100644
--- a/src/com/android/browser/UrlUtils.java
+++ b/src/com/android/browser/UrlUtils.java
@@ -159,4 +159,34 @@
return inUrl;
}
+ // Determine if this URI appears to be a Google property
+ /* package */ static boolean isGoogleUri(Uri uri) {
+ String scheme = uri.getScheme();
+ if (!"http".equals(scheme) && !"https".equals(scheme)) {
+ return false;
+ }
+
+ String host = uri.getHost();
+ if (host == null) {
+ return false;
+ }
+ String[] hostComponents = host.split("\\.");
+ if (hostComponents.length < 2) {
+ return false;
+ }
+
+ int googleComponent = hostComponents.length - 2;
+ String component = hostComponents[googleComponent];
+ if (!"google".equals(component)) {
+ if (hostComponents.length < 3 ||
+ (!"co".equals(component) && !"com".equals(component))) {
+ return false;
+ }
+ googleComponent = hostComponents.length - 3;
+ if (!"google".equals(hostComponents[googleComponent])) {
+ return false;
+ }
+ }
+ return true;
+ }
}