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

Commit 2dd21978 authored by Adam Cohen's avatar Adam Cohen
Browse files

-> Enabled partial updates to app widgets through AppWidgetManager.

   Partial updates are not cached by the AppWidgetService.
-> Added the ability to insert commands with no parameters into
   RemoteViews objects.
-> Added showNext() and showPrevious() methods to RemoteViews.
-> Made showNext() / showPrevious() of AdapterViewFlipper remotable.

Change-Id: Ic5491bb374424a54728c4ca92b94b1f00dfb87ff
parent 0c316eeb
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -36167,6 +36167,36 @@
<parameter name="viewId" type="int">
</parameter>
</method>
<method name="partiallyUpdateAppWidget"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="appWidgetIds" type="int[]">
</parameter>
<parameter name="views" type="android.widget.RemoteViews">
</parameter>
</method>
<method name="partiallyUpdateAppWidget"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="appWidgetId" type="int">
</parameter>
<parameter name="views" type="android.widget.RemoteViews">
</parameter>
</method>
<method name="updateAppWidget"
 return="void"
 abstract="false"
@@ -228211,6 +228241,32 @@
<parameter name="visibility" type="int">
</parameter>
</method>
<method name="showNext"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="viewId" type="int">
</parameter>
</method>
<method name="showPrevious"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="viewId" type="int">
</parameter>
</method>
<method name="writeToParcel"
 return="void"
 abstract="false"
+61 −0
Original line number Diff line number Diff line
@@ -233,6 +233,10 @@ public class AppWidgetManager {
    /**
     * Set the RemoteViews to use for the specified appWidgetIds.
     *
     * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
     * contain a complete representation of the widget. For performing partial widget updates, see
     * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}.
     *
     * <p>
     * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
     * and outside of the handler.
@@ -253,6 +257,10 @@ public class AppWidgetManager {
    /**
     * Set the RemoteViews to use for the specified appWidgetId.
     *
     * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
     * contain a complete representation of the widget. For performing partial widget updates, see
     * {@link #partiallyUpdateAppWidget(int, RemoteViews)}.
     *
     * <p>
     * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
     * and outside of the handler.
@@ -265,6 +273,59 @@ public class AppWidgetManager {
        updateAppWidget(new int[] { appWidgetId }, views);
    }

    /**
     * Perform an incremental update or command on the widget(s) specified by appWidgetIds.
     *
     * This update  differs from {@link #updateAppWidget(int[], RemoteViews)} in that the
     * RemoteViews object which is passed is understood to be an incomplete representation of the 
     * widget, and hence is not cached by the AppWidgetService. Note that because these updates are 
     * not cached, any state that they modify that is not restored by restoreInstanceState will not
     * persist in the case that the widgets are restored using the cached version in
     * AppWidgetService.
     *
     * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
     * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
     *
     * <p>
     * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
     * and outside of the handler.
     * This method will only work when called from the uid that owns the AppWidget provider.
     *
     * @param appWidgetIds     The AppWidget instances for which to set the RemoteViews.
     * @param views            The RemoteViews object containing the incremental update / command.
     */
    public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) {
        try {
            sService.partiallyUpdateAppWidgetIds(appWidgetIds, views);
        } catch (RemoteException e) {
            throw new RuntimeException("system server dead?", e);
        }
    }

    /**
     * Perform an incremental update or command on the widget specified by appWidgetId.
     *
     * This update  differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews
     * object which is passed is understood to be an incomplete representation of the widget, and
     * hence is not cached by the AppWidgetService. Note that because these updates are not cached,
     * any state that they modify that is not restored by restoreInstanceState will not persist in
     * the case that the widgets are restored using the cached version in AppWidgetService.
     *
     * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
     * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
     *
     * <p>
     * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
     * and outside of the handler.
     * This method will only work when called from the uid that owns the AppWidget provider.
     *
     * @param appWidgetId      The AppWidget instance for which to set the RemoteViews.
     * @param views            The RemoteViews object containing the incremental update / command.
     */
    public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) {
        partiallyUpdateAppWidget(new int[] { appWidgetId }, views);
    }

    /**
     * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider.
     *
+33 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.RemotableViewMethod;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.RemoteViews.RemoteView;
@@ -136,6 +137,38 @@ public class AdapterViewFlipper extends AdapterViewAnimator {
        updateRunning();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @RemotableViewMethod
    public void showNext() {
        // if the flipper is currently flipping automatically, and showNext() is called
        // we should we should make sure to reset the timer
        if (mRunning) {
            mHandler.removeMessages(FLIP_MSG);
            Message msg = mHandler.obtainMessage(FLIP_MSG);
            mHandler.sendMessageDelayed(msg, mFlipInterval);
        }
        super.showNext();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @RemotableViewMethod
    public void showPrevious() {
        // if the flipper is currently flipping automatically, and showPrevious() is called
        // we should we should make sure to reset the timer
        if (mRunning) {
            mHandler.removeMessages(FLIP_MSG);
            Message msg = mHandler.obtainMessage(FLIP_MSG);
            mHandler.sendMessageDelayed(msg, mFlipInterval);
        }
        super.showPrevious();
    }

    /**
     * How long to wait before flipping to the next view
     *
@@ -229,8 +262,6 @@ public class AdapterViewFlipper extends AdapterViewAnimator {
            if (msg.what == FLIP_MSG) {
                if (mRunning) {
                    showNext();
                    msg = obtainMessage(FLIP_MSG);
                    sendMessageDelayed(msg, mFlipInterval);
                }
            }
        }
+78 −0
Original line number Diff line number Diff line
@@ -266,6 +266,63 @@ public class RemoteViews implements Parcelable, Filter {
        public final static int TAG = 3;
    }
    
    private class ReflectionActionWithoutParams extends Action {
        int viewId;
        String methodName;

        public final static int TAG = 5;

        ReflectionActionWithoutParams(int viewId, String methodName) {
            this.viewId = viewId;
            this.methodName = methodName;
        }

        ReflectionActionWithoutParams(Parcel in) {
            this.viewId = in.readInt();
            this.methodName = in.readString();
        }

        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(TAG);
            out.writeInt(this.viewId);
            out.writeString(this.methodName);
        }

        @Override
        public void apply(View root) {
            final View view = root.findViewById(viewId);
            if (view == null) {
                throw new ActionException("can't find view: 0x" + Integer.toHexString(viewId));
            }

            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 {
                //noinspection ConstantIfStatement
                if (false) {
                    Log.d("RemoteViews", "view: " + klass.getName() + " calling method: "
                        + this.methodName + "()");
                }
                method.invoke(view);
            } catch (Exception ex) {
                throw new ActionException(ex);
            }
        }
    }

    /**
     * Base class for the reflection actions.
     */
@@ -571,6 +628,9 @@ public class RemoteViews implements Parcelable, Filter {
                case ViewGroupAction.TAG:
                    mActions.add(new ViewGroupAction(parcel));
                    break;
                case ReflectionActionWithoutParams.TAG:
                    mActions.add(new ReflectionActionWithoutParams(parcel));
                    break;
                default:
                    throw new ActionException("Tag " + tag + " not found");
                }
@@ -631,6 +691,24 @@ public class RemoteViews implements Parcelable, Filter {
        addAction(new ViewGroupAction(viewId, null));
    }

    /**
     * Equivalent to calling {@link AdapterViewFlipper#showNext()}
     *
     * @param viewId The id of the view on which to call {@link AdapterViewFlipper#showNext()}
     */
    public void showNext(int viewId) {
        addAction(new ReflectionActionWithoutParams(viewId, "showNext"));
    }

    /**
     * Equivalent to calling {@link AdapterViewFlipper#showPrevious()}
     *
     * @param viewId The id of the view on which to call {@link AdapterViewFlipper#showPrevious()}
     */
    public void showPrevious(int viewId) {
        addAction(new ReflectionActionWithoutParams(viewId, "showPrevious"));
    }

    /**
     * Equivalent to calling View.setVisibility
     * 
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ interface IAppWidgetService {
    // for AppWidgetManager
    //
    void updateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views);
    void partiallyUpdateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views);
    void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views);
    void notifyAppWidgetViewDataChanged(in int[] appWidgetIds, in RemoteViews views, int viewId);
    List<AppWidgetProviderInfo> getInstalledProviders();
Loading