mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-03 09:26:51 +00:00
Merge "Hotseats: better strategy for finding the default browser." into froyo
This commit is contained in:
committed by
Android (Google) Code Review
commit
0554b74917
11
res/values/arrays.xml
Normal file
11
res/values/arrays.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="hotseats" translatable="false">
|
||||
<item>intent:#Intent;action=android.intent.action.MAIN;component=com.android.contacts/.ContactsLaunchActivity;end</item>
|
||||
<item>*BROWSER*</item>
|
||||
</string-array>
|
||||
<array name="hotseat_icons" translatable="false">
|
||||
<item>@drawable/hotseat_phone</item>
|
||||
<item>@drawable/hotseat_browser</item>
|
||||
</array>
|
||||
</resources>
|
||||
@@ -141,4 +141,10 @@
|
||||
<!-- Text to show user in place of a gadget when we can't display it properly -->
|
||||
<string name="gadget_error_text">Problem loading widget</string>
|
||||
|
||||
<!-- URL to use when detecting the current default browser.
|
||||
Attempts to mimic homepage_base in Browser; {CID} should be replaced
|
||||
by the client-id, e.g. "android-google". -->
|
||||
<string name="default_browser_url" translatable="false">
|
||||
http://www.google.com/m?client=ms-{CID}&source=android-home-hotseat</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -35,8 +35,10 @@ import android.content.Intent.ShortcutIconResource;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
@@ -74,6 +76,7 @@ import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -203,13 +206,10 @@ public final class Launcher extends Activity
|
||||
// Hotseats (quick-launch icons next to AllApps)
|
||||
// TODO: move these intial intents out to Uris in an XML resource
|
||||
private static final int NUM_HOTSEATS = 2;
|
||||
private Intent[] mHotseats = new Intent[] {
|
||||
new Intent(Intent.ACTION_MAIN)
|
||||
.setComponent(ComponentName.unflattenFromString(
|
||||
"com.android.contacts/.ContactsLaunchActivity")),
|
||||
new Intent(Intent.ACTION_WEB_SEARCH, Uri.EMPTY),
|
||||
};
|
||||
private CharSequence[] mHotseatLabels = new CharSequence[2];
|
||||
private String[] mHotseatConfig = null;
|
||||
private Intent[] mHotseats = null;
|
||||
private Drawable[] mHotseatIcons = null;
|
||||
private CharSequence[] mHotseatLabels = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -368,37 +368,144 @@ public final class Launcher extends Activity
|
||||
wpm.suggestDesiredDimensions(width * WALLPAPER_SCREENS_SPAN, height);
|
||||
}
|
||||
|
||||
// Note: This doesn't do all the client-id magic that BrowserProvider does
|
||||
// in Browser. (http://b/2425179)
|
||||
private Uri getDefaultBrowserUri() {
|
||||
String url = getString(R.string.default_browser_url);
|
||||
if (url.indexOf("{CID}") != -1) {
|
||||
url = url.replace("{CID}", "android-google");
|
||||
}
|
||||
return Uri.parse(url);
|
||||
}
|
||||
|
||||
// Load the Intent templates from arrays.xml to populate the hotseats. For
|
||||
// each Intent, if it resolves to a single app, use that as the launch
|
||||
// intent & use that app's label as the contentDescription. Otherwise,
|
||||
// retain the ResolveActivity so the user can pick an app.
|
||||
private void loadHotseats() {
|
||||
if (mHotseatConfig == null) {
|
||||
mHotseatConfig = getResources().getStringArray(R.array.hotseats);
|
||||
if (mHotseatConfig.length > 0) {
|
||||
mHotseats = new Intent[mHotseatConfig.length];
|
||||
mHotseatLabels = new CharSequence[mHotseatConfig.length];
|
||||
mHotseatIcons = new Drawable[mHotseatConfig.length];
|
||||
} else {
|
||||
mHotseats = null;
|
||||
mHotseatIcons = null;
|
||||
mHotseatLabels = null;
|
||||
}
|
||||
|
||||
TypedArray hotseatIconDrawables = getResources().obtainTypedArray(R.array.hotseat_icons);
|
||||
for (int i=0; i<mHotseatConfig.length; i++) {
|
||||
// load icon for this slot; currently unrelated to the actual activity
|
||||
try {
|
||||
mHotseatIcons[i] = hotseatIconDrawables.getDrawable(i);
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
Log.w(TAG, "Missing hotseat_icons array item #" + i);
|
||||
mHotseatIcons[i] = null;
|
||||
}
|
||||
}
|
||||
hotseatIconDrawables.recycle();
|
||||
}
|
||||
|
||||
PackageManager pm = getPackageManager();
|
||||
for (int i=0; i<mHotseats.length; i++) {
|
||||
Intent intent = mHotseats[i];
|
||||
for (int i=0; i<mHotseatConfig.length; i++) {
|
||||
Intent intent = null;
|
||||
if (mHotseatConfig[i].equals("*BROWSER*")) {
|
||||
// magic value meaning "launch user's default web browser"
|
||||
// replace it with a generic web request so we can see if there is indeed a default
|
||||
String defaultUri = getString(R.string.default_browser_url);
|
||||
intent = new Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
((defaultUri != null)
|
||||
? Uri.parse(defaultUri)
|
||||
: getDefaultBrowserUri())
|
||||
).addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
// note: if the user launches this without a default set, she
|
||||
// will always be taken to the default URL above; this is
|
||||
// unavoidable as we must specify a valid URL in order for the
|
||||
// chooser to appear, and once the user selects something, that
|
||||
// URL is unavoidably sent to the chosen app.
|
||||
} else {
|
||||
try {
|
||||
intent = Intent.parseUri(mHotseatConfig[i], 0);
|
||||
} catch (java.net.URISyntaxException ex) {
|
||||
Log.w(TAG, "Invalid hotseat intent: " + mHotseatConfig[i]);
|
||||
// bogus; leave intent=null
|
||||
}
|
||||
}
|
||||
|
||||
if (intent == null) {
|
||||
mHotseats[i] = null;
|
||||
mHotseatLabels[i] = getText(R.string.activity_not_found);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "loadHotseats: hotseat " + i
|
||||
+ " initial intent=[" + intent.toUri(Intent.URI_INTENT_SCHEME)
|
||||
+ " initial intent=["
|
||||
+ intent.toUri(Intent.URI_INTENT_SCHEME)
|
||||
+ "]");
|
||||
}
|
||||
|
||||
// fix up the default intents
|
||||
if (intent.getAction().equals(Intent.ACTION_WEB_SEARCH)
|
||||
&& intent.getData().equals(Uri.EMPTY)) {
|
||||
// use this to represent "default web browser"
|
||||
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com/"));
|
||||
ResolveInfo bestMatch = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
List<ResolveInfo> allMatches = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "Best match for intent: " + bestMatch);
|
||||
Log.d(TAG, "All matches: ");
|
||||
for (ResolveInfo ri : allMatches) {
|
||||
Log.d(TAG, " --> " + ri);
|
||||
}
|
||||
}
|
||||
ComponentName com = intent.resolveActivity(pm);
|
||||
mHotseats[i] = new Intent(Intent.ACTION_MAIN).setComponent(com);
|
||||
// did this resolve to a single app, or the resolver?
|
||||
if (allMatches.size() == 0 || bestMatch == null) {
|
||||
// can't find any activity to handle this. let's leave the
|
||||
// intent as-is and let Launcher show a toast when it fails
|
||||
// to launch.
|
||||
mHotseats[i] = intent;
|
||||
|
||||
// load the labels for accessibility
|
||||
try {
|
||||
ActivityInfo ai = pm.getActivityInfo(com, 0);
|
||||
mHotseatLabels[i] = ai.loadLabel(pm);
|
||||
} catch (PackageManager.NameNotFoundException ex) {
|
||||
mHotseatLabels[i] = "";
|
||||
// set accessibility text to "Not installed"
|
||||
mHotseatLabels[i] = getText(R.string.activity_not_found);
|
||||
} else {
|
||||
boolean found = false;
|
||||
for (ResolveInfo ri : allMatches) {
|
||||
if (bestMatch.activityInfo.name.equals(ri.activityInfo.name)
|
||||
&& bestMatch.activityInfo.applicationInfo.packageName
|
||||
.equals(ri.activityInfo.applicationInfo.packageName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (LOGD) Log.d(TAG, "Multiple options, no default yet");
|
||||
// the bestMatch is probably the ResolveActivity, meaning the
|
||||
// user has not yet selected a default
|
||||
// so: we'll keep the original intent for now
|
||||
mHotseats[i] = intent;
|
||||
|
||||
// set the accessibility text to "Select shortcut"
|
||||
mHotseatLabels[i] = getText(R.string.title_select_shortcut);
|
||||
} else {
|
||||
// we have an app!
|
||||
// now reconstruct the intent to launch it through the front
|
||||
// door
|
||||
ComponentName com = new ComponentName(
|
||||
bestMatch.activityInfo.applicationInfo.packageName,
|
||||
bestMatch.activityInfo.name);
|
||||
mHotseats[i] = new Intent(Intent.ACTION_MAIN).setComponent(com);
|
||||
|
||||
// load the app label for accessibility
|
||||
mHotseatLabels[i] = bestMatch.activityInfo.loadLabel(pm);
|
||||
}
|
||||
}
|
||||
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "loadHotseats: hotseat " + i
|
||||
+ " intent=[" + mHotseats[i].toUri(Intent.URI_INTENT_SCHEME)
|
||||
+ " final intent=["
|
||||
+ ((mHotseats[i] == null)
|
||||
? "null"
|
||||
: mHotseats[i].toUri(Intent.URI_INTENT_SCHEME))
|
||||
+ "] label=[" + mHotseatLabels[i]
|
||||
+ "]"
|
||||
);
|
||||
@@ -622,8 +729,12 @@ public final class Launcher extends Activity
|
||||
mHandleView.setOnClickListener(this);
|
||||
mHandleView.setOnLongClickListener(this);
|
||||
|
||||
findViewById(R.id.hotseat_left).setContentDescription(mHotseatLabels[0]);
|
||||
findViewById(R.id.hotseat_right).setContentDescription(mHotseatLabels[1]);
|
||||
ImageView hotseatLeft = (ImageView) findViewById(R.id.hotseat_left);
|
||||
hotseatLeft.setContentDescription(mHotseatLabels[0]);
|
||||
hotseatLeft.setImageDrawable(mHotseatIcons[0]);
|
||||
ImageView hotseatRight = (ImageView) findViewById(R.id.hotseat_right);
|
||||
hotseatRight.setContentDescription(mHotseatLabels[1]);
|
||||
hotseatRight.setImageDrawable(mHotseatIcons[1]);
|
||||
|
||||
mPreviousView = (ImageView) dragLayer.findViewById(R.id.previous_screen);
|
||||
mNextView = (ImageView) dragLayer.findViewById(R.id.next_screen);
|
||||
@@ -678,7 +789,10 @@ public final class Launcher extends Activity
|
||||
index = 1;
|
||||
}
|
||||
|
||||
if (index >= 0 && mHotseats[index] != null) {
|
||||
// reload these every tap; you never know when they might change
|
||||
loadHotseats();
|
||||
if (index >= 0 && index < mHotseats.length && mHotseats[index] != null) {
|
||||
Intent intent = mHotseats[index];
|
||||
startActivitySafely(
|
||||
mHotseats[index],
|
||||
"hotseat"
|
||||
|
||||
Reference in New Issue
Block a user