OSDN Git Service

Make RemoteView margins density-change safe
authorAdrian Roos <roosa@google.com>
Thu, 9 Jun 2016 00:11:53 +0000 (17:11 -0700)
committerAdrian Roos <roosa@google.com>
Mon, 13 Jun 2016 22:39:05 +0000 (15:39 -0700)
Bug: 28935363
Change-Id: I279da8da84f794c512a66cb46c76ae9e746a6387

core/java/android/app/Notification.java
core/java/android/widget/RemoteViews.java
core/res/res/values/dimens.xml
core/res/res/values/symbols.xml

index 83a2066..456f592 100644 (file)
@@ -3171,8 +3171,8 @@ public class Notification implements Parcelable
         }
 
         private void resetContentMargins(RemoteViews contentView) {
-            contentView.setViewLayoutMarginEnd(R.id.line1, 0);
-            contentView.setViewLayoutMarginEnd(R.id.text, 0);
+            contentView.setViewLayoutMarginEndDimen(R.id.line1, 0);
+            contentView.setViewLayoutMarginEndDimen(R.id.text, 0);
         }
 
         private RemoteViews applyStandardTemplate(int resId) {
@@ -3266,11 +3266,10 @@ public class Notification implements Parcelable
                 contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
                 contentView.setImageViewIcon(R.id.right_icon, mN.mLargeIcon);
                 processLargeLegacyIcon(mN.mLargeIcon, contentView);
-                int endMargin = mContext.getResources().getDimensionPixelSize(
-                        R.dimen.notification_content_picture_margin);
-                contentView.setViewLayoutMarginEnd(R.id.line1, endMargin);
-                contentView.setViewLayoutMarginEnd(R.id.text, endMargin);
-                contentView.setViewLayoutMarginEnd(R.id.progress, endMargin);
+                int endMargin = R.dimen.notification_content_picture_margin;
+                contentView.setViewLayoutMarginEndDimen(R.id.line1, endMargin);
+                contentView.setViewLayoutMarginEndDimen(R.id.text, endMargin);
+                contentView.setViewLayoutMarginEndDimen(R.id.progress, endMargin);
             }
         }
 
@@ -4595,9 +4594,8 @@ public class Notification implements Parcelable
             }
 
             int i=0;
-            int titlePadding = mBuilder.mContext.getResources().getDimensionPixelSize(
-                    R.dimen.notification_messaging_spacing);
-            contentView.setViewLayoutMarginBottom(R.id.line1, hasTitle ? titlePadding : 0);
+            contentView.setViewLayoutMarginBottomDimen(R.id.line1,
+                    hasTitle ? R.dimen.notification_messaging_spacing : 0);
             contentView.setInt(R.id.notification_messaging, "setNumIndentLines",
                     mBuilder.mN.mLargeIcon == null ? 0 : (hasTitle ? 1 : 2));
 
@@ -4964,11 +4962,10 @@ public class Notification implements Parcelable
                 final boolean ind = mBuilder.mN.extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
                 boolean hasProgress = max != 0 || ind;
                 if (mBuilder.mN.mLargeIcon != null && !hasProgress) {
-                    endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
-                            R.dimen.notification_content_picture_margin);
+                    endMargin = R.dimen.notification_content_picture_margin;
                 }
             }
-            contentView.setViewLayoutMarginEnd(id, endMargin);
+            contentView.setViewLayoutMarginEndDimen(id, endMargin);
         }
     }
 
@@ -5153,13 +5150,11 @@ public class Notification implements Parcelable
             }
             handleImage(view);
             // handle the content margin
-            int endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
-                    R.dimen.notification_content_margin_end);;
+            int endMargin = R.dimen.notification_content_margin_end;
             if (mBuilder.mN.mLargeIcon != null) {
-                endMargin += mBuilder.mContext.getResources().getDimensionPixelSize(
-                        R.dimen.notification_content_picture_margin);
+                endMargin = R.dimen.notification_content_plus_picture_margin_end;
             }
-            view.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin);
+            view.setViewLayoutMarginEndDimen(R.id.notification_main_column, endMargin);
             return view;
         }
 
@@ -5190,8 +5185,8 @@ public class Notification implements Parcelable
 
         private void handleImage(RemoteViews contentView) {
             if (mBuilder.mN.mLargeIcon != null) {
-                contentView.setViewLayoutMarginEnd(R.id.line1, 0);
-                contentView.setViewLayoutMarginEnd(R.id.text, 0);
+                contentView.setViewLayoutMarginEndDimen(R.id.line1, 0);
+                contentView.setViewLayoutMarginEndDimen(R.id.text, 0);
             }
         }
 
@@ -5306,13 +5301,11 @@ public class Notification implements Parcelable
                 remoteViews.addView(R.id.notification_main_column, customContent);
             }
             // also update the end margin if there is an image
-            int endMargin = mBuilder.mContext.getResources().getDimensionPixelSize(
-                    R.dimen.notification_content_margin_end);
+            int endMargin = R.dimen.notification_content_margin_end;
             if (mBuilder.mN.mLargeIcon != null) {
-                endMargin += mBuilder.mContext.getResources().getDimensionPixelSize(
-                        R.dimen.notification_content_picture_margin);
+                endMargin = R.dimen.notification_content_plus_picture_margin_end;
             }
-            remoteViews.setViewLayoutMarginEnd(R.id.notification_main_column, endMargin);
+            remoteViews.setViewLayoutMarginEndDimen(R.id.notification_main_column, endMargin);
         }
     }
 
index 6dc5ff7..1f74518 100644 (file)
@@ -17,6 +17,7 @@
 package android.widget;
 
 import android.annotation.ColorInt;
+import android.annotation.DimenRes;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
@@ -1850,13 +1851,13 @@ public class RemoteViews implements Parcelable, Filter {
     /**
      * Helper action to set layout params on a View.
      */
-    private class LayoutParamAction extends Action {
+    private static class LayoutParamAction extends Action {
 
         /** Set marginEnd */
-        public static final int LAYOUT_MARGIN_END = 1;
+        public static final int LAYOUT_MARGIN_END_DIMEN = 1;
         /** Set width */
         public static final int LAYOUT_WIDTH = 2;
-        public static final int LAYOUT_MARGIN_BOTTOM = 3;
+        public static final int LAYOUT_MARGIN_BOTTOM_DIMEN = 3;
 
         /**
          * @param viewId ID of the view alter
@@ -1893,15 +1894,17 @@ public class RemoteViews implements Parcelable, Filter {
                 return;
             }
             switch (property) {
-                case LAYOUT_MARGIN_END:
+                case LAYOUT_MARGIN_END_DIMEN:
                     if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
-                        ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(value);
+                        int resolved = resolveDimenPixelOffset(target, value);
+                        ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(resolved);
                         target.setLayoutParams(layoutParams);
                     }
                     break;
-                case LAYOUT_MARGIN_BOTTOM:
+                case LAYOUT_MARGIN_BOTTOM_DIMEN:
                     if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
-                        ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin = value;
+                        int resolved = resolveDimenPixelOffset(target, value);
+                        ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin = resolved;
                         target.setLayoutParams(layoutParams);
                     }
                     break;
@@ -1914,6 +1917,13 @@ public class RemoteViews implements Parcelable, Filter {
             }
         }
 
+        private static int resolveDimenPixelOffset(View target, int value) {
+            if (value == 0) {
+                return 0;
+            }
+            return target.getContext().getResources().getDimensionPixelOffset(value);
+        }
+
         public String getActionName() {
             return "LayoutParamAction" + property + ".";
         }
@@ -2870,27 +2880,36 @@ public class RemoteViews implements Parcelable, Filter {
      * Hidden for now since we don't want to support this for all different layout margins yet.
      *
      * @param viewId The id of the view to change
-     * @param endMargin the left padding in pixels
+     * @param endMarginDimen a dimen resource to read the margin from or 0 to clear the margin.
      */
-    public void setViewLayoutMarginEnd(int viewId, int endMargin) {
-        addAction(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_MARGIN_END, endMargin));
+    public void setViewLayoutMarginEndDimen(int viewId, @DimenRes int endMarginDimen) {
+        addAction(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_MARGIN_END_DIMEN,
+                endMarginDimen));
     }
 
     /**
      * Equivalent to setting {@link android.view.ViewGroup.MarginLayoutParams#bottomMargin}.
      *
+     * @param bottomMarginDimen a dimen resource to read the margin from or 0 to clear the margin.
      * @hide
      */
-    public void setViewLayoutMarginBottom(int viewId, int bottomMargin) {
-        addAction(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_MARGIN_BOTTOM,
-                bottomMargin));
+    public void setViewLayoutMarginBottomDimen(int viewId, @DimenRes int bottomMarginDimen) {
+        addAction(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_MARGIN_BOTTOM_DIMEN,
+                bottomMarginDimen));
     }
 
     /**
      * Equivalent to setting {@link android.view.ViewGroup.LayoutParams#width}.
+     *
+     * @param layoutWidth one of 0, MATCH_PARENT or WRAP_CONTENT. Other sizes are not allowed
+     *                    because they behave poorly when the density changes.
      * @hide
      */
     public void setViewLayoutWidth(int viewId, int layoutWidth) {
+        if (layoutWidth != 0 && layoutWidth != ViewGroup.LayoutParams.MATCH_PARENT
+                && layoutWidth != ViewGroup.LayoutParams.WRAP_CONTENT) {
+            throw new IllegalArgumentException("Only supports 0, WRAP_CONTENT and MATCH_PARENT");
+        }
         mActions.add(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_WIDTH, layoutWidth));
     }
 
index 37fb816..91d7227 100644 (file)
     <!-- The margin on the start of the content view -->
     <dimen name="notification_content_margin_start">16dp</dimen>
 
-    <!-- The margin on the end of the content view -->
+    <!-- The margin on the end of the content view
+        Keep in sync with notification_content_plus_picture_margin! -->
     <dimen name="notification_content_margin_end">16dp</dimen>
 
-    <!-- The margin on the end of the content view with a picture.-->
+    <!-- The margin on the end of the content view with a picture.
+        Keep in sync with notification_content_plus_picture_margin! -->
     <dimen name="notification_content_picture_margin">56dp</dimen>
 
+    <!-- The margin on the end of the content view with a picture, plus the standard
+        content end margin.
+        Keep equal to (notification_content_picture_margin + notification_content_margin_end)!
+    -->
+    <dimen name="notification_content_plus_picture_margin_end">72dp</dimen>
+
     <!-- The height of the notification action list -->
     <dimen name="notification_action_list_height">56dp</dimen>
 
index abef7f8..2fbcdf2 100644 (file)
 
   <java-symbol type="bool" name="config_supportPreRebootSecurityLogs" />
 
+  <java-symbol type="dimen" name="notification_content_plus_picture_margin_end" />
+
   <!-- Pinner Service -->
   <java-symbol type="array" name="config_defaultPinnerServiceFiles" />