From a503f6f7cf09c64bde708e3bcfb7103378ddfcff Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 8 Dec 2009 21:50:14 -0800 Subject: [PATCH] Adjust for compatibility mode before setSourceBounds(). When invoked from an anyDensity="false" or pre-Donut app, View.getLocationOnScreen() returns values in compatibility mode. This change fixes QuickContact and RemoteViews to always adjust based on CompatibilityInfo.applicationScale. Also deprecates an extra previously being used to pass Rect for QuickContact windows. Fixes http://b/2306495 --- .../android/provider/ContactsContract.java | 27 ++++++++++++------- core/java/android/widget/RemoteViews.java | 18 ++++++++++--- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 657d6c2dfd72d..2a9157e548d41 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -35,6 +35,7 @@ import android.graphics.Rect; import android.net.Uri; import android.os.RemoteException; import android.text.TextUtils; +import android.util.DisplayMetrics; import android.util.Pair; import android.view.View; @@ -4896,8 +4897,10 @@ public final class ContactsContract { /** * Extra used to specify pivot dialog location in screen coordinates. + * @deprecated Use {@link Intent#setSourceBounds(Rect)} instead. * @hide */ + @Deprecated public static final String EXTRA_TARGET_RECT = "target_rect"; /** @@ -4957,15 +4960,17 @@ public final class ContactsContract { */ public static void showQuickContact(Context context, View target, Uri lookupUri, int mode, String[] excludeMimes) { - // Find location and bounds of target view - final int[] location = new int[2]; - target.getLocationOnScreen(location); + // Find location and bounds of target view, adjusting based on the + // assumed local density. + final float appScale = context.getResources().getCompatibilityInfo().applicationScale; + final int[] pos = new int[2]; + target.getLocationOnScreen(pos); final Rect rect = new Rect(); - rect.left = location[0]; - rect.top = location[1]; - rect.right = rect.left + target.getWidth(); - rect.bottom = rect.top + target.getHeight(); + rect.left = (int) (pos[0] * appScale + 0.5f); + rect.top = (int) (pos[1] * appScale + 0.5f); + rect.right = (int) ((pos[0] + target.getWidth()) * appScale + 0.5f); + rect.bottom = (int) ((pos[1] + target.getHeight()) * appScale + 0.5f); // Trigger with obtained rectangle showQuickContact(context, rect, lookupUri, mode, excludeMimes); @@ -4982,8 +4987,10 @@ public final class ContactsContract { * @param target Specific {@link Rect} that this dialog should be * centered around, in screen coordinates. In particular, if * the dialog has a "callout" arrow, it will be pointed and - * centered around this {@link Rect}. - * @param lookupUri A {@link ContactsContract.Contacts#CONTENT_LOOKUP_URI} style + * centered around this {@link Rect}. If you are running at a + * non-native density, you need to manually adjust using + * {@link DisplayMetrics#density} before calling. + * @param lookupUri A {@link Contacts#CONTENT_LOOKUP_URI} style * {@link Uri} that describes a specific contact to feature * in this dialog. * @param mode Any of {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or @@ -5002,7 +5009,7 @@ public final class ContactsContract { | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); intent.setData(lookupUri); - intent.putExtra(EXTRA_TARGET_RECT, target); + intent.setSourceBounds(target); intent.putExtra(EXTRA_MODE, mode); intent.putExtra(EXTRA_EXCLUDE_MIMES, excludeMimes); context.startActivity(intent); diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index b847e574362dc..c1150733e282a 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -137,11 +137,21 @@ public class RemoteViews implements Parcelable, Filter { if (target != null && pendingIntent != null) { OnClickListener listener = new OnClickListener() { public void onClick(View v) { - int[] pos = new int[2]; + // Find target view location in screen coordinates and + // fill into PendingIntent before sending. + final float appScale = v.getContext().getResources() + .getCompatibilityInfo().applicationScale; + final int[] pos = new int[2]; v.getLocationOnScreen(pos); - Intent intent = new Intent(); - intent.setSourceBounds(new Rect(pos[0], pos[1], - pos[0]+v.getWidth(), pos[1]+v.getHeight())); + + final Rect rect = new Rect(); + rect.left = (int) (pos[0] * appScale + 0.5f); + rect.top = (int) (pos[1] * appScale + 0.5f); + rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f); + rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f); + + final Intent intent = new Intent(); + intent.setSourceBounds(rect); try { // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT? v.getContext().startIntentSender(