Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ab9ece8 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Cache reflection lookups"

parents 623c734d e4d4e20e
Loading
Loading
Loading
Loading
+100 −102
Original line number Original line Diff line number Diff line
@@ -37,6 +37,7 @@ import android.os.Parcelable;
import android.os.StrictMode;
import android.os.StrictMode;
import android.os.UserHandle;
import android.os.UserHandle;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.LayoutInflater.Filter;
import android.view.LayoutInflater.Filter;
@@ -136,6 +137,16 @@ public class RemoteViews implements Parcelable, Filter {


    private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = new OnClickHandler();
    private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = new OnClickHandler();


    private static final Object sMethodsLock = new Object[0];
    private static final ArrayMap<Class<? extends View>, ArrayMap<String, Method>> sMethods =
            new ArrayMap<Class<? extends View>, ArrayMap<String, Method>>();
    private static final ThreadLocal<Object[]> sInvokeArgsTls = new ThreadLocal<Object[]>() {
        @Override
        protected Object[] initialValue() {
            return new Object[1];
        }
    };

    /**
    /**
     * This annotation indicates that a subclass of View is alllowed to be used
     * This annotation indicates that a subclass of View is alllowed to be used
     * with the {@link RemoteViews} mechanism.
     * with the {@link RemoteViews} mechanism.
@@ -206,9 +217,8 @@ public class RemoteViews implements Parcelable, Filter {
         * Overridden by each class to report on it's own memory usage
         * Overridden by each class to report on it's own memory usage
         */
         */
        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
            // We currently only calculate Bitmap memory usage, so by default, don't do anything
            // We currently only calculate Bitmap memory usage, so by default,
            // here
            // don't do anything here
            return;
        }
        }


        public void setBitmapCache(BitmapCache bitmapCache) {
        public void setBitmapCache(BitmapCache bitmapCache) {
@@ -346,7 +356,7 @@ public class RemoteViews implements Parcelable, Filter {
            }
            }
            if (target == root) {
            if (target == root) {
                target.setTagInternal(com.android.internal.R.id.fillInIntent, fillInIntent);
                target.setTagInternal(com.android.internal.R.id.fillInIntent, fillInIntent);
            } else if (target != null && fillInIntent != null) {
            } else if (fillInIntent != null) {
                OnClickListener listener = new OnClickListener() {
                OnClickListener listener = new OnClickListener() {
                    public void onClick(View v) {
                    public void onClick(View v) {
                        // Insure that this view is a child of an AdapterView
                        // Insure that this view is a child of an AdapterView
@@ -372,16 +382,7 @@ public class RemoteViews implements Parcelable, Filter {


                        PendingIntent pendingIntent = (PendingIntent) parent.getTag();
                        PendingIntent pendingIntent = (PendingIntent) parent.getTag();


                        final float appScale = v.getContext().getResources()
                        final Rect rect = getSourceBounds(v);
                                .getCompatibilityInfo().applicationScale;
                        final int[] pos = new int[2];
                        v.getLocationOnScreen(pos);

                        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);


                        fillInIntent.setSourceBounds(rect);
                        fillInIntent.setSourceBounds(rect);
                        handler.onClickHandler(v, pendingIntent, fillInIntent);
                        handler.onClickHandler(v, pendingIntent, fillInIntent);
@@ -452,16 +453,7 @@ public class RemoteViews implements Parcelable, Filter {
                            }
                            }
                            if (fillInIntent == null) return;
                            if (fillInIntent == null) return;


                            final float appScale = view.getContext().getResources()
                            final Rect rect = getSourceBounds(view);
                                    .getCompatibilityInfo().applicationScale;
                            final int[] pos = new int[2];
                            view.getLocationOnScreen(pos);

                            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] + view.getWidth()) * appScale + 0.5f);
                            rect.bottom = (int) ((pos[1] + view.getHeight()) * appScale + 0.5f);


                            final Intent intent = new Intent();
                            final Intent intent = new Intent();
                            intent.setSourceBounds(rect);
                            intent.setSourceBounds(rect);
@@ -679,7 +671,6 @@ public class RemoteViews implements Parcelable, Filter {
                }
                }
            }
            }


            if (target != null) {
            // If the pendingIntent is null, we clear the onClickListener
            // If the pendingIntent is null, we clear the onClickListener
            OnClickListener listener = null;
            OnClickListener listener = null;
            if (pendingIntent != null) {
            if (pendingIntent != null) {
@@ -687,6 +678,27 @@ public class RemoteViews implements Parcelable, Filter {
                    public void onClick(View v) {
                    public void onClick(View v) {
                        // Find target view location in screen coordinates and
                        // Find target view location in screen coordinates and
                        // fill into PendingIntent before sending.
                        // fill into PendingIntent before sending.
                        final Rect rect = getSourceBounds(v);

                        final Intent intent = new Intent();
                        intent.setSourceBounds(rect);
                        handler.onClickHandler(v, pendingIntent, intent);
                    }
                };
            }
            target.setOnClickListener(listener);
        }

        public String getActionName() {
            return "SetOnClickPendingIntent";
        }

        PendingIntent pendingIntent;

        public final static int TAG = 1;
    }

    private static Rect getSourceBounds(View v) {
        final float appScale = v.getContext().getResources()
        final float appScale = v.getContext().getResources()
                .getCompatibilityInfo().applicationScale;
                .getCompatibilityInfo().applicationScale;
        final int[] pos = new int[2];
        final int[] pos = new int[2];
@@ -697,24 +709,51 @@ public class RemoteViews implements Parcelable, Filter {
        rect.top = (int) (pos[1] * appScale + 0.5f);
        rect.top = (int) (pos[1] * appScale + 0.5f);
        rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
        rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
        rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
        rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
        return rect;
    }


                            final Intent intent = new Intent();
    private static Method getMethod(View view, String methodName, Class<?> paramType) {
                            intent.setSourceBounds(rect);
        Method method;
                            handler.onClickHandler(v, pendingIntent, intent);
        Class<? extends View> klass = view.getClass();

        synchronized (sMethodsLock) {
            ArrayMap<String, Method> methods = sMethods.get(klass);
            if (methods == null) {
                methods = new ArrayMap<String, Method>();
                sMethods.put(klass, methods);
            }
            }
                    };

            method = methods.get(methodName);
            if (method == null) {
                try {
                    method = klass.getMethod(methodName, paramType);
                } catch (NoSuchMethodException ex) {
                    throw new ActionException("view: " + klass.getName() + " doesn't have method: "
                            + methodName + getParameters(paramType));
                }
                }
                target.setOnClickListener(listener);

                if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
                    throw new ActionException("view: " + klass.getName()
                            + " can't use method with RemoteViews: "
                            + methodName + getParameters(paramType));
                }

                methods.put(methodName, method);
            }
            }
        }
        }


        public String getActionName() {
        return method;
            return "SetOnClickPendingIntent";
    }
    }


        PendingIntent pendingIntent;
    private static String getParameters(Class<?> paramType) {
        if (paramType == null) return "()";
        return "(" + paramType + ")";
    }


        public final static int TAG = 1;
    private static Object[] wrapArg(Object value) {
        Object[] args = sInvokeArgsTls.get();
        args[0] = value;
        return args;
    }
    }


    /**
    /**
@@ -836,28 +875,10 @@ public class RemoteViews implements Parcelable, Filter {
            final View view = root.findViewById(viewId);
            final View view = root.findViewById(viewId);
            if (view == null) return;
            if (view == null) return;


            Class klass = view.getClass();
            Method method;
            try {
                method = klass.getMethod(this.methodName);
            } catch (NoSuchMethodException ex) {
                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
                        + this.methodName + "()");
            }

            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
                throw new ActionException("view: " + klass.getName()
                        + " can't use method with RemoteViews: "
                        + this.methodName + "()");
            }

            try {
            try {
                //noinspection ConstantIfStatement
                getMethod(view, this.methodName, null).invoke(view);
                if (false) {
            } catch (ActionException e) {
                    Log.d(LOG_TAG, "view: " + klass.getName() + " calling method: "
                throw e;
                        + this.methodName + "()");
                }
                method.invoke(view);
            } catch (Exception ex) {
            } catch (Exception ex) {
                throw new ActionException(ex);
                throw new ActionException(ex);
            }
            }
@@ -1157,7 +1178,7 @@ public class RemoteViews implements Parcelable, Filter {
            }
            }
        }
        }


        private Class getParameterType() {
        private Class<?> getParameterType() {
            switch (this.type) {
            switch (this.type) {
                case BOOLEAN:
                case BOOLEAN:
                    return boolean.class;
                    return boolean.class;
@@ -1197,37 +1218,16 @@ public class RemoteViews implements Parcelable, Filter {
            final View view = root.findViewById(viewId);
            final View view = root.findViewById(viewId);
            if (view == null) return;
            if (view == null) return;


            Class param = getParameterType();
            Class<?> param = getParameterType();
            if (param == null) {
            if (param == null) {
                throw new ActionException("bad type: " + this.type);
                throw new ActionException("bad type: " + this.type);
            }
            }


            Class klass = view.getClass();
            Method method;
            try {
                method = klass.getMethod(this.methodName, getParameterType());
            }
            catch (NoSuchMethodException ex) {
                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
                        + this.methodName + "(" + param.getName() + ")");
            }

            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
                throw new ActionException("view: " + klass.getName()
                        + " can't use method with RemoteViews: "
                        + this.methodName + "(" + param.getName() + ")");
            }

            try {
            try {
                //noinspection ConstantIfStatement
                getMethod(view, this.methodName, param).invoke(view, wrapArg(this.value));
                if (false) {
            } catch (ActionException e) {
                    Log.d(LOG_TAG, "view: " + klass.getName() + " calling method: "
                throw e;
                        + this.methodName + "(" + param.getName() + ") with "
            } catch (Exception ex) {
                        + (this.value == null ? "null" : this.value.getClass().getName()));
                }
                method.invoke(view, this.value);
            }
            catch (Exception ex) {
                throw new ActionException(ex);
                throw new ActionException(ex);
            }
            }
        }
        }
@@ -1323,7 +1323,7 @@ public class RemoteViews implements Parcelable, Filter {
        }
        }


        public String getActionName() {
        public String getActionName() {
            return "ViewGroupAction" + this.nestedViews == null ? "Remove" : "Add";
            return "ViewGroupAction" + (nestedViews == null ? "Remove" : "Add");
        }
        }


        public int mergeBehavior() {
        public int mergeBehavior() {
@@ -1370,7 +1370,6 @@ public class RemoteViews implements Parcelable, Filter {


        @Override
        @Override
        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
            final Context context = root.getContext();
            final TextView target = (TextView) root.findViewById(viewId);
            final TextView target = (TextView) root.findViewById(viewId);
            if (target == null) return;
            if (target == null) return;
            if (isRelative) {
            if (isRelative) {
@@ -1415,7 +1414,6 @@ public class RemoteViews implements Parcelable, Filter {


        @Override
        @Override
        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
            final Context context = root.getContext();
            final TextView target = (TextView) root.findViewById(viewId);
            final TextView target = (TextView) root.findViewById(viewId);
            if (target == null) return;
            if (target == null) return;
            target.setTextSize(units, size);
            target.setTextSize(units, size);
@@ -1462,7 +1460,6 @@ public class RemoteViews implements Parcelable, Filter {


        @Override
        @Override
        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
            final Context context = root.getContext();
            final View target = root.findViewById(viewId);
            final View target = root.findViewById(viewId);
            if (target == null) return;
            if (target == null) return;
            target.setPadding(left, top, right, bottom);
            target.setPadding(left, top, right, bottom);
@@ -1494,6 +1491,7 @@ public class RemoteViews implements Parcelable, Filter {
            return mMemoryUsage;
            return mMemoryUsage;
        }
        }


        @SuppressWarnings("deprecation")
        public void addBitmapMemory(Bitmap b) {
        public void addBitmapMemory(Bitmap b) {
            final Bitmap.Config c = b.getConfig();
            final Bitmap.Config c = b.getConfig();
            // If we don't know, be pessimistic and assume 4
            // If we don't know, be pessimistic and assume 4
@@ -1597,7 +1595,7 @@ public class RemoteViews implements Parcelable, Filter {
        if (mode == MODE_NORMAL) {
        if (mode == MODE_NORMAL) {
            mPackage = parcel.readString();
            mPackage = parcel.readString();
            mLayoutId = parcel.readInt();
            mLayoutId = parcel.readInt();
            mIsWidgetCollectionChild = parcel.readInt() == 1 ? true : false;
            mIsWidgetCollectionChild = parcel.readInt() == 1;


            int count = parcel.readInt();
            int count = parcel.readInt();
            if (count > 0) {
            if (count > 0) {