summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSatish Sampath <satish@android.com>2009-06-02 15:02:26 +0100
committerSatish Sampath <satish@android.com>2009-06-03 12:06:34 +0100
commite178fb528229d5e2c7f3e8e8b5b9a32fc901b5bd (patch)
tree2b3b5463327ee5ddc37fa908c866dcab195e8309
parent175a700d454a96ac4550035cad6c5176e9db1b29 (diff)
downloadWebSearchProvider-e178fb528229d5e2c7f3e8e8b5b9a32fc901b5bd.tar.gz
Sets up default web search intent action handler on boot.
On boot, typically there will be multiple activities registered to handle intent action WEB_SEARCH. We make the WebSearchProvider receive the boot completed broadcast message and in that event check our list of known web search providers ordered by priority and set the highest priority one found as the preferred activity.
-rw-r--r--AndroidManifest.xml8
-rw-r--r--res/values/default_providers.xml33
-rw-r--r--src/com/android/websearch/WebSearchReceiver.java104
3 files changed, 145 insertions, 0 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b5cbe3e..d29c769 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -21,9 +21,17 @@
package="com.android.websearch"
android:sharedUserId="android.uid.shared">
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+
<application android:label="Web Search"
android:process="android.process.acore">
+ <receiver android:name=".WebSearchReceiver" >
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ </intent-filter>
+ </receiver>
+
<activity android:name=".WebSearch"
android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true">
diff --git a/res/values/default_providers.xml b/res/values/default_providers.xml
new file mode 100644
index 0000000..6865df9
--- /dev/null
+++ b/res/values/default_providers.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, 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.
+*/
+-->
+
+<!--
+/*
+ * Each string points to the component name of an ACTION_WEB_SEARCH handling activity. When the app
+ * starts up and it finds that there are no preferred ACTION_WEB_SEARCH handlers, it iterates
+ * through this list and sets the first one found as the preferred activity.
+ */
+-->
+<resources>
+ <string-array name="default_providers">
+ <item>com.google.android.providers.genie/.GenieLauncher</item>
+ <item>com.android.googlesearch/.GoogleSearch</item>
+ <item>com.android.websearch/.Search.1</item>
+ </string-array>
+</resources>
diff --git a/src/com/android/websearch/WebSearchReceiver.java b/src/com/android/websearch/WebSearchReceiver.java
new file mode 100644
index 0000000..099b806
--- /dev/null
+++ b/src/com/android/websearch/WebSearchReceiver.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2009 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.websearch;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.util.Log;
+import android.util.LogPrinter;
+
+import com.android.internal.app.ResolverActivity;
+
+import java.util.List;
+
+/**
+ * This class receives the broadcast event of boot completed from the system and sets up the default
+ * web search provider activity if required.
+ */
+public class WebSearchReceiver extends BroadcastReceiver {
+ private static final String TAG = "WebSearch";
+
+ /**
+ * Checks if the given activity component is present in the system and if so makes it the
+ * preferred activity for handling ACTION_WEB_SEARCH.
+ * @param componentName Name of the component to check and set as preferred.
+ * @return true if component was detected and set as preferred activity, false if not.
+ */
+ private boolean setPreferredActivity(Context context, String componentName) {
+ Log.d(TAG, "Checking component " + componentName);
+ ComponentName activity = ComponentName.unflattenFromString(componentName);
+ PackageManager pm = context.getPackageManager();
+ ActivityInfo ai;
+ try {
+ ai = pm.getActivityInfo(activity, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+
+ // The code here to find the value for bestMatch is heavily inspired by the code
+ // in ResolverActivity where the preferred activity is set.
+ Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ List<ResolveInfo> webSearchActivities = pm.queryIntentActivities(intent, 0);
+ ComponentName set[] = new ComponentName[webSearchActivities.size()];
+ int bestMatch = 0;
+ for (int i = 0; i < webSearchActivities.size(); ++i) {
+ ResolveInfo ri = webSearchActivities.get(i);
+ set[i] = new ComponentName(ri.activityInfo.packageName,
+ ri.activityInfo.name);
+ if (ri.match > bestMatch) bestMatch = ri.match;
+ }
+
+ Log.d(TAG, "Setting preferred web search activity to " + componentName);
+ IntentFilter filter = new IntentFilter(Intent.ACTION_WEB_SEARCH);
+ filter.addCategory(Intent.CATEGORY_DEFAULT);
+ pm.replacePreferredActivity(filter, bestMatch, set, activity);
+ return true;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent receivedIntent) {
+ Log.d(TAG, "boot completed.");
+
+ // Check if we have a preferred web search activity.
+ Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ PackageManager pm = context.getPackageManager();
+ ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+
+ if (ri == null || ri.activityInfo.name.equals(ResolverActivity.class.getName())) {
+ Log.d(TAG, "No preferred activity set for action web search.");
+
+ // The components in the providers array are checked in the order of declaration so the
+ // first one has the highest priority. If the component exists in the system it is set
+ // as the preferred activity to handle intent action web search.
+ String[] preferredActivities = context.getResources().getStringArray(
+ R.array.default_providers);
+ for (String componentName : preferredActivities) {
+ if (setPreferredActivity(context, componentName)) {
+ break;
+ }
+ }
+ }
+ }
+}