OSDN Git Service

DO NOT MERGE - Backport RLZ code to GB:
authorEd Tam <etam@google.com>
Thu, 5 May 2011 23:19:48 +0000 (16:19 -0700)
committerEd Tam <etam@google.com>
Wed, 18 May 2011 00:58:04 +0000 (17:58 -0700)
  - 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: I7ce0e7bead7954ed9ebfe10b66242553f14ed6f2

AndroidManifest.xml
res/values/strings.xml
src/com/android/browser/BrowserActivity.java
src/com/android/browser/BrowserSettings.java
src/com/android/browser/RlzReceiver.java [new file with mode: 0644]
src/com/android/browser/UrlUtils.java [new file with mode: 0644]

index dc8f599..cfa402a 100644 (file)
         <!-- Makes .BrowserActivity the search target for any activity in Browser -->
         <meta-data android:name="android.app.default_searchable" android:value=".BrowserActivity" />
 
+        <!-- Application code for RLZ tracking.  RLZ assigns non-unique, non-personally identifiable
+             tracking labels to client products; these labels sometimes appear in Google search
+             queries.  See http://code.google.com/p/rlz for more info.
+
+             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>
                 <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"/>
index fc0d68b..720d586 100644 (file)
     <string name="error_console_eval_text_hint" translatable="false">Evaluate JavaScript</string>
     <string name="error_console_eval_button_text" translatable="false">Evaluate</string>
 
+    <!-- Access point for RLZ tracking. -->
+    <string name="rlz_access_point" translatable="false">Y1</string>
 </resources>
index 435560b..793a43c 100644 (file)
@@ -188,6 +188,8 @@ public class BrowserActivity extends Activity
         // Keep a settings instance handy.
         mSettings = BrowserSettings.getInstance();
 
+        mSettings.updateRlzValues(this);
+
         // If this was a web search request, pass it on to the default web
         // search provider and finish this activity.
         if (handleWebSearchIntent(getIntent())) {
@@ -633,6 +635,17 @@ public class BrowserActivity extends Activity
                             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 (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)
@@ -4003,4 +4016,20 @@ public class BrowserActivity extends Activity
     };
 
     /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null);
+
+    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();
+    }
 }
index a322b59..bb5c4bb 100644 (file)
@@ -23,14 +23,21 @@ import com.android.browser.search.SearchEngines;
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Handler;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
+import android.provider.Browser.BookmarkColumns;
 import android.provider.Settings;
 import android.util.Log;
 import android.webkit.CookieManager;
@@ -166,6 +173,11 @@ class BrowserSettings extends Observable {
     // a ListView
     public final static int MAX_TEXTVIEW_LEN = 80;
 
+    public static final String RLZ_PROVIDER = "com.google.android.partnersetup.rlzappprovider";
+    public static final Uri RLZ_PROVIDER_URI = Uri.parse("content://" + RLZ_PROVIDER + "/");
+
+    private String mRlzValue = "";
+
     private TabControl mTabControl;
 
     // Single instance of the BrowserSettings for use in the Browser app.
@@ -653,4 +665,115 @@ class BrowserSettings extends Observable {
         geolocationEnabled = true;
         workersEnabled = true;  // only affects V8. JSC does not have a similar setting
     }
+
+    /*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(Browser.BOOKMARKS_URI,
+                new String[] { BookmarkColumns._ID, BookmarkColumns.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(BookmarkColumns.URL, newUrl);
+                        Uri bookmarkUri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI, 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/RlzReceiver.java b/src/com/android/browser/RlzReceiver.java
new file mode 100644 (file)
index 0000000..1dfb11a
--- /dev/null
@@ -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/UrlUtils.java b/src/com/android/browser/UrlUtils.java
new file mode 100644 (file)
index 0000000..56b4f2e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 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.net.Uri;
+
+/**
+ * Utility methods for Url manipulation
+ */
+public class UrlUtils {
+    // 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;
+    }
+}