19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport android.app.ActivityOptions;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent;
211480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohenimport android.appwidget.AppWidgetHostView;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
23fa82f22f1d8c4c828bdf9b670006be4f4fec772eDianne Hackbornimport android.content.Intent;
24fa82f22f1d8c4c828bdf9b670006be4f4fec772eDianne Hackbornimport android.content.IntentSender;
25ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohenimport android.content.pm.ApplicationInfo;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException;
275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohenimport android.content.res.Configuration;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PorterDuff;
307597065d6b0877ffc460b443fdb1595965ccd7b2Joe Onoratoimport android.graphics.Rect;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
33ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohenimport android.os.Build;
34d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringertimport android.os.Bundle;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
37a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkeyimport android.os.StrictMode;
386d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkeyimport android.os.UserHandle;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
42dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport android.view.LayoutInflater.Filter;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.RemotableViewMethod;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View.OnClickListener;
46dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport android.view.ViewGroup;
47a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohenimport android.widget.AdapterView.OnItemClickListener;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.ElementType;
50dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.Retention;
51dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.RetentionPolicy;
52dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.Target;
53dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.reflect.Method;
54dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.util.ArrayList;
55fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohenimport java.util.HashMap;
56dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A class that describes a view hierarchy that can be displayed in
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * another process. The hierarchy is inflated from a layout resource
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file, and this class provides some basic operations for modifying
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the content of the inflated hierarchy.
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RemoteViews implements Parcelable, Filter {
64e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String LOG_TAG = "RemoteViews";
66e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6881f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     * The intent extra that contains the appWidgetId.
6981f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     * @hide
7081f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     */
7181f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung    static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId";
7281f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung
7381f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung    /**
746d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey     * User that these views should be applied as. Requires
756d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} when
766d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey     * crossing user boundaries.
776d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey     */
786d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    private UserHandle mUser = android.os.Process.myUserHandle();
796d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey
806d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    /**
81e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * The package name of the package containing the layout
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * resource. (Added to the parcel)
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
843030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne    private final String mPackage;
85e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The resource ID of the layout file. (Added to the parcel)
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
893030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne    private final int mLayoutId;
90a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * An array of actions to perform on the view tree once it has been
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inflated
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ArrayList<Action> mActions;
96e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
973ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
983ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * A class to keep track of memory usage by this RemoteViews
993ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
1003ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    private MemoryUsageCounter mMemoryUsageCounter;
1013ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
1025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
1035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Maps bitmaps to unique indicies to avoid Bitmap duplication.
1045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
1055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private BitmapCache mBitmapCache;
1065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
1075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
1085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Indicates whether or not this RemoteViews object is contained as a child of any other
1095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * RemoteViews.
1105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
1115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private boolean mIsRoot = true;
1125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
1135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
1145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Constants to whether or not this RemoteViews is composed of a landscape and portrait
1155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * RemoteViews.
1165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
1175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private static final int MODE_NORMAL = 0;
1185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private static final int MODE_HAS_LANDSCAPE_AND_PORTRAIT = 1;
1195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
1205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
1215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Used in conjunction with the special constructor
1225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * {@link #RemoteViews(RemoteViews, RemoteViews)} to keep track of the landscape and portrait
1235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * RemoteViews.
1245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
1255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews mLandscape = null;
1265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews mPortrait = null;
1275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
129ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * This flag indicates whether this RemoteViews object is being created from a
130ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * RemoteViewsService for use as a child of a widget collection. This flag is used
131ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * to determine whether or not certain features are available, in particular,
132ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * setting on click extras and setting on click pending intents. The former is enabled,
133ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * and the latter disabled when this flag is true.
134ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     */
1351927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    private boolean mIsWidgetCollectionChild = false;
1361927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
1371927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = new OnClickHandler();
138ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
139ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    /**
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This annotation indicates that a subclass of View is alllowed to be used
141a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy     * with the {@link RemoteViews} mechanism.
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Target({ ElementType.TYPE })
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Retention(RetentionPolicy.RUNTIME)
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public @interface RemoteView {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Exception to send when something goes wrong executing an action
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class ActionException extends RuntimeException {
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ActionException(Exception ex) {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(ex);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ActionException(String message) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(message);
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
160a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
1611927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    /** @hide */
1621927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    public static class OnClickHandler {
1631927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        public boolean onClickHandler(View view, PendingIntent pendingIntent,
164ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                Intent fillInIntent) {
165ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            try {
166ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
167dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                Context context = view.getContext();
168dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
169dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                        0, 0,
170dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                        view.getMeasuredWidth(), view.getMeasuredHeight());
171ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                context.startIntentSender(
172ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                        pendingIntent.getIntentSender(), fillInIntent,
173ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                        Intent.FLAG_ACTIVITY_NEW_TASK,
174dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                        Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
175ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            } catch (IntentSender.SendIntentException e) {
176ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                android.util.Log.e(LOG_TAG, "Cannot send pending intent: ", e);
177ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                return false;
178ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            } catch (Exception e) {
179ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                android.util.Log.e(LOG_TAG, "Cannot send pending intent due to " +
180ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                        "unknown exception: ", e);
181ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                return false;
182ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            }
183ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            return true;
184ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung        }
1851927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    }
1861927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
1871927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    /**
1881927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     * Base class for all actions that can be performed on an
1891927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     * inflated view.
1901927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     *
1911927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     *  SUBCLASSES MUST BE IMMUTABLE SO CLONE WORKS!!!!!
1921927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     */
1931927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    private abstract static class Action implements Parcelable {
194a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public abstract void apply(View root, ViewGroup rootParent,
195a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                OnClickHandler handler) throws ActionException;
1961927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
197fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public static final int MERGE_REPLACE = 0;
198fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public static final int MERGE_APPEND = 1;
199fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public static final int MERGE_IGNORE = 2;
200fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
2011927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        public int describeContents() {
2021927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn            return 0;
2031927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        }
2041927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
2051927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        /**
2061927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn         * Overridden by each class to report on it's own memory usage
2071927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn         */
2081927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
2091927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn            // We currently only calculate Bitmap memory usage, so by default, don't do anything
2101927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn            // here
2111927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn            return;
2121927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        }
2135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
2145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void setBitmapCache(BitmapCache bitmapCache) {
2155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // Do nothing
2165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
217fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
218fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
219fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return MERGE_REPLACE;
220fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
221fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
222fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public abstract String getActionName();
223fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
224fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getUniqueKey() {
225fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return (getActionName() + viewId);
226fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
227fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
228fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        int viewId;
229fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen    }
230fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
231bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen    /**
232bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     * Merges the passed RemoteViews actions with this RemoteViews actions according to
233bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     * action-specific merge rules.
234bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     *
235bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     * @param newRv
236bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     *
237bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     * @hide
238bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     */
239fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen    public void mergeRemoteViews(RemoteViews newRv) {
2403ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        if (newRv == null) return;
241fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // We first copy the new RemoteViews, as the process of merging modifies the way the actions
242fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // reference the bitmap cache. We don't want to modify the object as it may need to
243fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // be merged and applied multiple times.
2443ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        RemoteViews copy = newRv.clone();
245fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
246fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        HashMap<String, Action> map = new HashMap<String, Action>();
247fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        if (mActions == null) {
248fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            mActions = new ArrayList<Action>();
249fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
250fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
251fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        int count = mActions.size();
252fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        for (int i = 0; i < count; i++) {
253fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            Action a = mActions.get(i);
254fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            map.put(a.getUniqueKey(), a);
255fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
256fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
257fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        ArrayList<Action> newActions = copy.mActions;
258fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        if (newActions == null) return;
259fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        count = newActions.size();
260fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        for (int i = 0; i < count; i++) {
261fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            Action a = newActions.get(i);
262fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            String key = newActions.get(i).getUniqueKey();
2633ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen            int mergeBehavior = newActions.get(i).mergeBehavior();
264fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (map.containsKey(key) && mergeBehavior == Action.MERGE_REPLACE) {
265fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                mActions.remove(map.get(key));
266fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                map.remove(key);
267fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            }
268fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
269fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // If the merge behavior is ignore, we don't bother keeping the extra action
270fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (mergeBehavior == Action.MERGE_REPLACE || mergeBehavior == Action.MERGE_APPEND) {
271fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                mActions.add(a);
272fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            }
273fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
274fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
275fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // Because pruning can remove the need for bitmaps, we reconstruct the bitmap cache
276fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        mBitmapCache = new BitmapCache();
277fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        setBitmapCache(mBitmapCache);
278a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy    }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2801480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    private class SetEmptyView extends Action {
2811480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        int viewId;
2821480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        int emptyViewId;
2831480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2841480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        public final static int TAG = 6;
2851480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2861480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        SetEmptyView(int viewId, int emptyViewId) {
2871480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            this.viewId = viewId;
2881480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            this.emptyViewId = emptyViewId;
2891480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        }
2901480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2911480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        SetEmptyView(Parcel in) {
2921480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            this.viewId = in.readInt();
2931480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            this.emptyViewId = in.readInt();
2941480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        }
2951480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2961480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        public void writeToParcel(Parcel out, int flags) {
2971480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            out.writeInt(TAG);
2981480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            out.writeInt(this.viewId);
2991480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            out.writeInt(this.emptyViewId);
3001480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        }
3011480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
3021480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        @Override
303a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
3041480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            final View view = root.findViewById(viewId);
3051480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            if (!(view instanceof AdapterView<?>)) return;
3061480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
3071480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            AdapterView<?> adapterView = (AdapterView<?>) view;
3081480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
3091480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            final View emptyView = root.findViewById(emptyViewId);
3101480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            if (emptyView == null) return;
3111480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
3121480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            adapterView.setEmptyView(emptyView);
3131480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        }
314fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
315fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
316fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetEmptyView";
317fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
3181480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    }
3191480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
32035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    private class SetOnClickFillInIntent extends Action {
32135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        public SetOnClickFillInIntent(int id, Intent fillInIntent) {
32235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            this.viewId = id;
32335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            this.fillInIntent = fillInIntent;
32435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        }
32535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
32635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        public SetOnClickFillInIntent(Parcel parcel) {
32735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            viewId = parcel.readInt();
32835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            fillInIntent = Intent.CREATOR.createFromParcel(parcel);
32935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        }
33035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
33135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        public void writeToParcel(Parcel dest, int flags) {
33235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            dest.writeInt(TAG);
33335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            dest.writeInt(viewId);
33435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            fillInIntent.writeToParcel(dest, 0 /* no flags */);
33535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        }
33635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
33735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        @Override
338a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) {
33935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            final View target = root.findViewById(viewId);
3402b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
34135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
34235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            if (!mIsWidgetCollectionChild) {
34350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.e(LOG_TAG, "The method setOnClickFillInIntent is available " +
34435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        "only from RemoteViewsFactory (ie. on collection items).");
34535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                return;
34635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            }
347a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen            if (target == root) {
348a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                target.setTagInternal(com.android.internal.R.id.fillInIntent, fillInIntent);
349a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen            } else if (target != null && fillInIntent != null) {
35035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                OnClickListener listener = new OnClickListener() {
35135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                    public void onClick(View v) {
35235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        // Insure that this view is a child of an AdapterView
35335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        View parent = (View) v.getParent();
35485a08f1bf2bf3a3120abf03fa4d3fad99d6876f9Adam Cohen                        while (parent != null && !(parent instanceof AdapterView<?>)
35535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                                && !(parent instanceof AppWidgetHostView)) {
35635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            parent = (View) parent.getParent();
35735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        }
35835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
35985a08f1bf2bf3a3120abf03fa4d3fad99d6876f9Adam Cohen                        if (parent instanceof AppWidgetHostView || parent == null) {
36035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            // Somehow they've managed to get this far without having
36135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            // and AdapterView as a parent.
36250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                            Log.e(LOG_TAG, "Collection item doesn't have AdapterView parent");
36335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            return;
36435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        }
36535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
36635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        // Insure that a template pending intent has been set on an ancestor
36735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        if (!(parent.getTag() instanceof PendingIntent)) {
36850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                            Log.e(LOG_TAG, "Attempting setOnClickFillInIntent without" +
369a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                    " calling setPendingIntentTemplate on parent.");
37035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            return;
37135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        }
37235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
37335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        PendingIntent pendingIntent = (PendingIntent) parent.getTag();
37435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
37535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        final float appScale = v.getContext().getResources()
376a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                .getCompatibilityInfo().applicationScale;
37735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        final int[] pos = new int[2];
37835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        v.getLocationOnScreen(pos);
37935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
38035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        final Rect rect = new Rect();
38135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        rect.left = (int) (pos[0] * appScale + 0.5f);
38235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        rect.top = (int) (pos[1] * appScale + 0.5f);
38335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
38435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
38535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
38635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        fillInIntent.setSourceBounds(rect);
387a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                        handler.onClickHandler(v, pendingIntent, fillInIntent);
38835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                    }
38935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
39035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                };
39135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                target.setOnClickListener(listener);
39235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            }
39335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        }
39435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
395fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
396fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetOnClickFillInIntent";
397fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
398fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
39935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        Intent fillInIntent;
40035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
40135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        public final static int TAG = 9;
40235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    }
40335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
404ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    private class SetPendingIntentTemplate extends Action {
405ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        public SetPendingIntentTemplate(int id, PendingIntent pendingIntentTemplate) {
406ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            this.viewId = id;
407ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            this.pendingIntentTemplate = pendingIntentTemplate;
408ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        }
409ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
410ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        public SetPendingIntentTemplate(Parcel parcel) {
411ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            viewId = parcel.readInt();
412ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            pendingIntentTemplate = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
413ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        }
414ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
415ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        public void writeToParcel(Parcel dest, int flags) {
416ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            dest.writeInt(TAG);
417ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            dest.writeInt(viewId);
418ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            pendingIntentTemplate.writeToParcel(dest, 0 /* no flags */);
419ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        }
420ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
421ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        @Override
422a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) {
423ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            final View target = root.findViewById(viewId);
4242b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
425ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
426ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            // If the view isn't an AdapterView, setting a PendingIntent template doesn't make sense
427ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            if (target instanceof AdapterView<?>) {
428a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                AdapterView<?> av = (AdapterView<?>) target;
429ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen                // The PendingIntent template is stored in the view's tag.
430a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                OnItemClickListener listener = new OnItemClickListener() {
431a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                    public void onItemClick(AdapterView<?> parent, View view,
432a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            int position, long id) {
433a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                        // The view should be a frame layout
434a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                        if (view instanceof ViewGroup) {
435a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            ViewGroup vg = (ViewGroup) view;
436a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
437a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            // AdapterViews contain their children in a frame
438a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            // so we need to go one layer deeper here.
439a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            if (parent instanceof AdapterViewAnimator) {
440a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                vg = (ViewGroup) vg.getChildAt(0);
441a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            }
442a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            if (vg == null) return;
443a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
444a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            Intent fillInIntent = null;
445a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            int childCount = vg.getChildCount();
446a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            for (int i = 0; i < childCount; i++) {
447a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                Object tag = vg.getChildAt(i).getTag(com.android.internal.R.id.fillInIntent);
448a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                if (tag instanceof Intent) {
449a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                    fillInIntent = (Intent) tag;
450a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                    break;
451a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                }
452a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            }
453a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            if (fillInIntent == null) return;
454a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
455a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            final float appScale = view.getContext().getResources()
456a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                    .getCompatibilityInfo().applicationScale;
457a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            final int[] pos = new int[2];
458a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            view.getLocationOnScreen(pos);
459a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
460a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            final Rect rect = new Rect();
461a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            rect.left = (int) (pos[0] * appScale + 0.5f);
462a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            rect.top = (int) (pos[1] * appScale + 0.5f);
463a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            rect.right = (int) ((pos[0] + view.getWidth()) * appScale + 0.5f);
464a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            rect.bottom = (int) ((pos[1] + view.getHeight()) * appScale + 0.5f);
465a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
466a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            final Intent intent = new Intent();
467a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            intent.setSourceBounds(rect);
468a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                            handler.onClickHandler(view, pendingIntentTemplate, fillInIntent);
469a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                        }
470a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                    }
471a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                };
472a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                av.setOnItemClickListener(listener);
473a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                av.setTag(pendingIntentTemplate);
474ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            } else {
47550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.e(LOG_TAG, "Cannot setPendingIntentTemplate on a view which is not" +
47635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        "an AdapterView (id: " + viewId + ")");
477ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen                return;
478ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            }
479ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        }
480ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
481fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
482fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetPendingIntentTemplate";
483fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
484fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
485ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        PendingIntent pendingIntentTemplate;
486ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
487ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        public final static int TAG = 8;
488ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    }
489ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
49050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen    private class SetRemoteViewsAdapterList extends Action {
491b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen        public SetRemoteViewsAdapterList(int id, ArrayList<RemoteViews> list, int viewTypeCount) {
49250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            this.viewId = id;
49350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            this.list = list;
494b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen            this.viewTypeCount = viewTypeCount;
49550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        }
49650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
49750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        public SetRemoteViewsAdapterList(Parcel parcel) {
49850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            viewId = parcel.readInt();
499b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen            viewTypeCount = parcel.readInt();
50050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            int count = parcel.readInt();
50150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            list = new ArrayList<RemoteViews>();
50250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
50350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            for (int i = 0; i < count; i++) {
50450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                RemoteViews rv = RemoteViews.CREATOR.createFromParcel(parcel);
50550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                list.add(rv);
50650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            }
50750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        }
50850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
50950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        public void writeToParcel(Parcel dest, int flags) {
51050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            dest.writeInt(TAG);
51150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            dest.writeInt(viewId);
512b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen            dest.writeInt(viewTypeCount);
51350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
51450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            if (list == null || list.size() == 0) {
51550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                dest.writeInt(0);
51650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            } else {
51750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                int count = list.size();
51850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                dest.writeInt(count);
51950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                for (int i = 0; i < count; i++) {
52050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                    RemoteViews rv = list.get(i);
52150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                    rv.writeToParcel(dest, flags);
52250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                }
52350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            }
52450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        }
52550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
52650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        @Override
52750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
52850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            final View target = root.findViewById(viewId);
52950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            if (target == null) return;
53050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
53150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            // Ensure that we are applying to an AppWidget root
53250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            if (!(rootParent instanceof AppWidgetHostView)) {
53350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.e(LOG_TAG, "SetRemoteViewsAdapterIntent action can only be used for " +
53450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                        "AppWidgets (root id: " + viewId + ")");
53550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                return;
53650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            }
53750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            // Ensure that we are calling setRemoteAdapter on an AdapterView that supports it
53850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            if (!(target instanceof AbsListView) && !(target instanceof AdapterViewAnimator)) {
53950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.e(LOG_TAG, "Cannot setRemoteViewsAdapter on a view which is not " +
54050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                        "an AbsListView or AdapterViewAnimator (id: " + viewId + ")");
54150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                return;
54250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            }
54350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
54450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            if (target instanceof AbsListView) {
54550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                AbsListView v = (AbsListView) target;
54650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Adapter a = v.getAdapter();
547b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen                if (a instanceof RemoteViewsListAdapter && viewTypeCount <= a.getViewTypeCount()) {
54850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                    ((RemoteViewsListAdapter) a).setViewsList(list);
54950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                } else {
550b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen                    v.setAdapter(new RemoteViewsListAdapter(v.getContext(), list, viewTypeCount));
55150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                }
55250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            } else if (target instanceof AdapterViewAnimator) {
55350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                AdapterViewAnimator v = (AdapterViewAnimator) target;
55450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Adapter a = v.getAdapter();
555b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen                if (a instanceof RemoteViewsListAdapter && viewTypeCount <= a.getViewTypeCount()) {
55650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                    ((RemoteViewsListAdapter) a).setViewsList(list);
55750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                } else {
558b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen                    v.setAdapter(new RemoteViewsListAdapter(v.getContext(), list, viewTypeCount));
55950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                }
56050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            }
56150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        }
56250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
56350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        public String getActionName() {
56450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen            return "SetRemoteViewsAdapterList";
56550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        }
56650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
567b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen        int viewTypeCount;
56850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        ArrayList<RemoteViews> list;
56950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen        public final static int TAG = 15;
57050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen    }
57150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
572037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    private class SetRemoteViewsAdapterIntent extends Action {
573037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public SetRemoteViewsAdapterIntent(int id, Intent intent) {
574037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            this.viewId = id;
575037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            this.intent = intent;
576037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
577037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
578037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public SetRemoteViewsAdapterIntent(Parcel parcel) {
579037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            viewId = parcel.readInt();
580037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent = Intent.CREATOR.createFromParcel(parcel);
581037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
582037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
583037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public void writeToParcel(Parcel dest, int flags) {
584037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            dest.writeInt(TAG);
585037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            dest.writeInt(viewId);
586037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent.writeToParcel(dest, flags);
587037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
588037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
589037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        @Override
590a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
591037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            final View target = root.findViewById(viewId);
592037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (target == null) return;
593037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
594037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Ensure that we are applying to an AppWidget root
595037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (!(rootParent instanceof AppWidgetHostView)) {
59650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.e(LOG_TAG, "SetRemoteViewsAdapterIntent action can only be used for " +
597037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                        "AppWidgets (root id: " + viewId + ")");
598037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                return;
599037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
600037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Ensure that we are calling setRemoteAdapter on an AdapterView that supports it
601037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (!(target instanceof AbsListView) && !(target instanceof AdapterViewAnimator)) {
60250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.e(LOG_TAG, "Cannot setRemoteViewsAdapter on a view which is not " +
603037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                        "an AbsListView or AdapterViewAnimator (id: " + viewId + ")");
604037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                return;
605037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
606037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
607037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Embed the AppWidget Id for use in RemoteViewsAdapter when connecting to the intent
608037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // RemoteViewsService
609037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            AppWidgetHostView host = (AppWidgetHostView) rootParent;
610037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId());
611037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (target instanceof AbsListView) {
612037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                AbsListView v = (AbsListView) target;
613037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                v.setRemoteViewsAdapter(intent);
614a6a4cbc18f7e5a3831d787d3f398e02c5eae6512Adam Cohen                v.setRemoteViewsOnClickHandler(handler);
615037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            } else if (target instanceof AdapterViewAnimator) {
616037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                AdapterViewAnimator v = (AdapterViewAnimator) target;
617037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                v.setRemoteViewsAdapter(intent);
618a6a4cbc18f7e5a3831d787d3f398e02c5eae6512Adam Cohen                v.setRemoteViewsOnClickHandler(handler);
619037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
620037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
621037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
622fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
623fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetRemoteViewsAdapterIntent";
624fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
625fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
626037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        Intent intent;
627037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
628037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public final static int TAG = 10;
629037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    }
630037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to launch the provided {@link PendingIntent}.
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class SetOnClickPendingIntent extends Action {
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetOnClickPendingIntent(int id, PendingIntent pendingIntent) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = id;
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.pendingIntent = pendingIntent;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
641ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetOnClickPendingIntent(Parcel parcel) {
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            viewId = parcel.readInt();
644c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
645c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // We check a flag to determine if the parcel contains a PendingIntent.
646c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (parcel.readInt() != 0) {
647c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
648c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
650ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel dest, int flags) {
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(TAG);
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(viewId);
654c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
655c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // We use a flag to indicate whether the parcel contains a valid object.
656c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            dest.writeInt(pendingIntent != null ? 1 : 0);
657c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (pendingIntent != null) {
658c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                pendingIntent.writeToParcel(dest, 0 /* no flags */);
659c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            }
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
661ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
663a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) {
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View target = root.findViewById(viewId);
6652b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
666ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
667ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            // If the view is an AdapterView, setting a PendingIntent on click doesn't make much
668ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            // sense, do they mean to set a PendingIntent template for the AdapterView's children?
669ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            if (mIsWidgetCollectionChild) {
67050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.w(LOG_TAG, "Cannot setOnClickPendingIntent for collection item " +
671c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        "(id: " + viewId + ")");
672ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                ApplicationInfo appInfo = root.getContext().getApplicationInfo();
673ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen
674ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                // We let this slide for HC and ICS so as to not break compatibility. It should have
675ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                // been disabled from the outset, but was left open by accident.
676ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                if (appInfo != null &&
677ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                        appInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
678ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                    return;
679ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                }
680ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            }
681ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
682c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (target != null) {
683c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                // If the pendingIntent is null, we clear the onClickListener
684c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                OnClickListener listener = null;
685c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                if (pendingIntent != null) {
686c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    listener = new OnClickListener() {
687c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        public void onClick(View v) {
688c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            // Find target view location in screen coordinates and
689c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            // fill into PendingIntent before sending.
690c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final float appScale = v.getContext().getResources()
691c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                                    .getCompatibilityInfo().applicationScale;
692c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final int[] pos = new int[2];
693c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            v.getLocationOnScreen(pos);
694e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
695c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final Rect rect = new Rect();
696c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.left = (int) (pos[0] * appScale + 0.5f);
697c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.top = (int) (pos[1] * appScale + 0.5f);
698c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
699c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
700e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
701c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final Intent intent = new Intent();
702c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            intent.setSourceBounds(rect);
703a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                            handler.onClickHandler(v, pendingIntent, intent);
704c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        }
705c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    };
706c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                }
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                target.setOnClickListener(listener);
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
710c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
711fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
712fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetOnClickPendingIntent";
713fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
714fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PendingIntent pendingIntent;
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final static int TAG = 1;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given view.
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These operations will be performed on the {@link Drawable} returned by the
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * target {@link View#getBackground()} by default.  If targetBackground is false,
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * we assume the target is an {@link ImageView} and try applying the operations
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to {@link ImageView#getDrawable()}.
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * You can omit specific calls by marking their values with null or -1.
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class SetDrawableParameters extends Action {
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetDrawableParameters(int id, boolean targetBackground, int alpha,
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int colorFilter, PorterDuff.Mode mode, int level) {
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = id;
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.targetBackground = targetBackground;
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.alpha = alpha;
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.colorFilter = colorFilter;
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.filterMode = mode;
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.level = level;
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
742e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetDrawableParameters(Parcel parcel) {
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            viewId = parcel.readInt();
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            targetBackground = parcel.readInt() != 0;
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            alpha = parcel.readInt();
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            colorFilter = parcel.readInt();
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean hasMode = parcel.readInt() != 0;
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (hasMode) {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filterMode = PorterDuff.Mode.valueOf(parcel.readString());
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filterMode = null;
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            level = parcel.readInt();
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
756e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel dest, int flags) {
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(TAG);
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(viewId);
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(targetBackground ? 1 : 0);
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(alpha);
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(colorFilter);
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (filterMode != null) {
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeInt(1);
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeString(filterMode.toString());
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeInt(0);
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(level);
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
771e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
773a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View target = root.findViewById(viewId);
7752b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
776e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Pick the correct drawable to modify for this view
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable targetDrawable = null;
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (targetBackground) {
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                targetDrawable = target.getBackground();
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (target instanceof ImageView) {
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ImageView imageView = (ImageView) target;
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                targetDrawable = imageView.getDrawable();
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
785e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
786a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            if (targetDrawable != null) {
787a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                // Perform modifications only if values are set correctly
788a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (alpha != -1) {
789a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setAlpha(alpha);
790a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
791a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (colorFilter != -1 && filterMode != null) {
792a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setColorFilter(colorFilter, filterMode);
793a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
794a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (level != -1) {
795a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setLevel(level);
796a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7993ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
800fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
801fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetDrawableParameters";
802fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
803fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean targetBackground;
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int alpha;
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int colorFilter;
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PorterDuff.Mode filterMode;
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int level;
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final static int TAG = 3;
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
812e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
8132dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    private class ReflectionActionWithoutParams extends Action {
8142dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        String methodName;
8152dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8162dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        public final static int TAG = 5;
8172dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8182dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        ReflectionActionWithoutParams(int viewId, String methodName) {
8192dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.viewId = viewId;
8202dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.methodName = methodName;
8212dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
8222dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8232dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        ReflectionActionWithoutParams(Parcel in) {
8242dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.viewId = in.readInt();
8252dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.methodName = in.readString();
8262dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
8272dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8282dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        public void writeToParcel(Parcel out, int flags) {
8292dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeInt(TAG);
8302dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeInt(this.viewId);
8312dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeString(this.methodName);
8322dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
8332dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8342dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        @Override
835a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
8362dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            final View view = root.findViewById(viewId);
8372b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (view == null) return;
8382dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8392dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            Class klass = view.getClass();
8402dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            Method method;
8412dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            try {
8422dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                method = klass.getMethod(this.methodName);
8432dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            } catch (NoSuchMethodException ex) {
8442dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
8452dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
8462dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
8472dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8482dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
8492dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException("view: " + klass.getName()
8502dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + " can't use method with RemoteViews: "
8512dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
8522dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
8532dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8542dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            try {
8552dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                //noinspection ConstantIfStatement
8562dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                if (false) {
85750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                    Log.d(LOG_TAG, "view: " + klass.getName() + " calling method: "
8582dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
8592dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                }
8602dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                method.invoke(view);
8612dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            } catch (Exception ex) {
8622dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException(ex);
8632dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
8642dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
865fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
866fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
867fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // we don't need to build up showNext or showPrevious calls
868fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (methodName.equals("showNext") || methodName.equals("showPrevious")) {
869fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_IGNORE;
870fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            } else {
871fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_REPLACE;
872fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            }
873fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
874fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
875fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
876fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ReflectionActionWithoutParams";
877fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
8782dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
8792dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
8805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private static class BitmapCache {
8815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        ArrayList<Bitmap> mBitmaps;
8825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public BitmapCache() {
8845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmaps = new ArrayList<Bitmap>();
8855d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8875d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public BitmapCache(Parcel source) {
8885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = source.readInt();
8895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmaps = new ArrayList<Bitmap>();
8905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
8915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Bitmap b = Bitmap.CREATOR.createFromParcel(source);
8925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmaps.add(b);
8935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8955d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public int getBitmapId(Bitmap b) {
8975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (b == null) {
8985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return -1;
8995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
9005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                if (mBitmaps.contains(b)) {
9015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    return mBitmaps.indexOf(b);
9025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                } else {
9035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mBitmaps.add(b);
9045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    return (mBitmaps.size() - 1);
9055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
9065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
9075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public Bitmap getBitmapForId(int id) {
9105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (id == -1 || id >= mBitmaps.size()) {
9115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return null;
9125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
9135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mBitmaps.get(id);
9145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
9155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void writeBitmapsToParcel(Parcel dest, int flags) {
9185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = mBitmaps.size();
9195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(count);
9205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
9215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmaps.get(i).writeToParcel(dest, flags);
9225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
9235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void assimilate(BitmapCache bitmapCache) {
9265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            ArrayList<Bitmap> bitmapsToBeAdded = bitmapCache.mBitmaps;
9275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = bitmapsToBeAdded.size();
9285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
9295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Bitmap b = bitmapsToBeAdded.get(i);
9305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                if (!mBitmaps.contains(b)) {
9315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mBitmaps.add(b);
9325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
9335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
9345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void addBitmapMemory(MemoryUsageCounter memoryCounter) {
9375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < mBitmaps.size(); i++) {
9385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                memoryCounter.addBitmapMemory(mBitmaps.get(i));
9395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
9405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
9425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private class BitmapReflectionAction extends Action {
9445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int bitmapId;
9455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        Bitmap bitmap;
9465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        String methodName;
9475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        BitmapReflectionAction(int viewId, String methodName, Bitmap bitmap) {
9495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.bitmap = bitmap;
9505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.viewId = viewId;
9515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.methodName = methodName;
9525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = mBitmapCache.getBitmapId(bitmap);
9535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        BitmapReflectionAction(Parcel in) {
9565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            viewId = in.readInt();
9575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            methodName = in.readString();
9585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = in.readInt();
9595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmap = mBitmapCache.getBitmapForId(bitmapId);
9605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
9635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void writeToParcel(Parcel dest, int flags) {
9645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(TAG);
9655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(viewId);
9665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeString(methodName);
9675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(bitmapId);
9685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
971a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent,
972a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                OnClickHandler handler) throws ActionException {
9735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            ReflectionAction ra = new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP,
9745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bitmap);
975a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn            ra.apply(root, rootParent, handler);
9765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9785d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
9795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void setBitmapCache(BitmapCache bitmapCache) {
9805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = bitmapCache.getBitmapId(bitmap);
9815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
983fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
984fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "BitmapReflectionAction";
985fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
986fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
9875d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public final static int TAG = 12;
9885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
9895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Base class for the reflection actions.
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class ReflectionAction extends Action {
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int TAG = 2;
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BOOLEAN = 1;
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BYTE = 2;
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int SHORT = 3;
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int INT = 4;
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int LONG = 5;
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int FLOAT = 6;
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int DOUBLE = 7;
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int CHAR = 8;
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int STRING = 9;
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int CHAR_SEQUENCE = 10;
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int URI = 11;
1007fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // BITMAP actions are never stored in the list of actions. They are only used locally
1008fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // to implement BitmapReflectionAction, which eliminates duplicates using BitmapCache.
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BITMAP = 12;
1010d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert        static final int BUNDLE = 13;
1011499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        static final int INTENT = 14;
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String methodName;
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int type;
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object value;
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ReflectionAction(int viewId, String methodName, int type, Object value) {
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = viewId;
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.methodName = methodName;
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.type = type;
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.value = value;
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ReflectionAction(Parcel in) {
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = in.readInt();
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.methodName = in.readString();
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.type = in.readInt();
1028a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            //noinspection ConstantIfStatement
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (false) {
103050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.d(LOG_TAG, "read viewId=0x" + Integer.toHexString(this.viewId)
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " methodName=" + this.methodName + " type=" + this.type);
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1033c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
1034c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // For some values that may have been null, we first check a flag to see if they were
1035c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // written to the parcel.
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readInt() != 0;
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readByte();
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = (short)in.readInt();
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readInt();
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readLong();
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readFloat();
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readDouble();
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = (char)in.readInt();
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readString();
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
1068c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
1069c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Uri.CREATOR.createFromParcel(in);
1070c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
1073c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
1074c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Bitmap.CREATOR.createFromParcel(in);
1075c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1077d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
1078d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    this.value = in.readBundle();
1079d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    break;
1080499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
1081c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
1082c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Intent.CREATOR.createFromParcel(in);
1083c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
1084499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    break;
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel out, int flags) {
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(TAG);
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(this.viewId);
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeString(this.methodName);
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(this.type);
1095a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            //noinspection ConstantIfStatement
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (false) {
109750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                Log.d(LOG_TAG, "write viewId=0x" + Integer.toHexString(this.viewId)
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " methodName=" + this.methodName + " type=" + this.type);
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1100c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
1101c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // For some values which are null, we record an integer flag to indicate whether
1102c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // we have written a valid value to the parcel.
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
1105a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Boolean) this.value ? 1 : 0);
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
1108a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeByte((Byte) this.value);
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
1111a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Short) this.value);
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
1114a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Integer) this.value);
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
1117a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeLong((Long) this.value);
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
1120a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeFloat((Float) this.value);
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
1123a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeDouble((Double) this.value);
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    out.writeInt((int)((Character)this.value).charValue());
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    out.writeString((String)this.value);
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
1132e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller                    TextUtils.writeToParcel((CharSequence)this.value, out, flags);
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
1135c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1136c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1137c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Uri)this.value).writeToParcel(out, flags);
1138c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
1141c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1142c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1143c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Bitmap)this.value).writeToParcel(out, flags);
1144c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1146d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
1147d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    out.writeBundle((Bundle) this.value);
1148d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    break;
1149499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
1150c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1151c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1152c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Intent)this.value).writeToParcel(out, flags);
1153c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
1154499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    break;
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private Class getParameterType() {
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return boolean.class;
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return byte.class;
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return short.class;
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return int.class;
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return long.class;
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return float.class;
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return double.class;
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return char.class;
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return String.class;
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return CharSequence.class;
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return Uri.class;
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return Bitmap.class;
1186d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
1187d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    return Bundle.class;
1188499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
1189499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    return Intent.class;
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return null;
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1196a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View view = root.findViewById(viewId);
11982b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (view == null) return;
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Class param = getParameterType();
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (param == null) {
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("bad type: " + this.type);
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Class klass = view.getClass();
1206a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            Method method;
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                method = klass.getMethod(this.methodName, getParameterType());
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            catch (NoSuchMethodException ex) {
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ")");
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("view: " + klass.getName()
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " can't use method with RemoteViews: "
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ")");
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
1222a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                //noinspection ConstantIfStatement
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (false) {
122450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                    Log.d(LOG_TAG, "view: " + klass.getName() + " calling method: "
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ") with "
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + (this.value == null ? "null" : this.value.getClass().getName()));
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                method.invoke(view, this.value);
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            catch (Exception ex) {
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException(ex);
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12343ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
1235fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
1236fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // smoothScrollBy is cumulative, everything else overwites.
1237fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (methodName.equals("smoothScrollBy")) {
1238fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_APPEND;
1239fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            } else {
1240fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_REPLACE;
12413ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
12423ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
1243fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1244fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1245fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // Each type of reflection action corresponds to a setter, so each should be seen as
1246fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // unique from the standpoint of merging.
1247fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ReflectionAction" + this.methodName + this.type;
1248fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private void configureRemoteViewsAsChild(RemoteViews rv) {
12525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache.assimilate(rv.mBitmapCache);
12535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        rv.setBitmapCache(mBitmapCache);
12545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        rv.setNotRoot();
12555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
12565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
12575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    void setNotRoot() {
12585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mIsRoot = false;
12595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
12605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
12611162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
12621162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
12631162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * given {@link RemoteViews}, or calling {@link ViewGroup#removeAllViews()}
12641162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * when null. This allows users to build "nested" {@link RemoteViews}.
12651162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
12661162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    private class ViewGroupAction extends Action {
12671162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public ViewGroupAction(int viewId, RemoteViews nestedViews) {
12681162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            this.viewId = viewId;
12691162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            this.nestedViews = nestedViews;
1270c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen            if (nestedViews != null) {
1271c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen                configureRemoteViewsAsChild(nestedViews);
1272c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen            }
12731162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
12741162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public ViewGroupAction(Parcel parcel, BitmapCache bitmapCache) {
12761162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            viewId = parcel.readInt();
12775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            boolean nestedViewsNull = parcel.readInt() == 0;
12785d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (!nestedViewsNull) {
12795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews = new RemoteViews(parcel, bitmapCache);
12805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
12815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews = null;
12825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
12831162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
12841162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12851162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public void writeToParcel(Parcel dest, int flags) {
12861162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            dest.writeInt(TAG);
12871162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            dest.writeInt(viewId);
12885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (nestedViews != null) {
12895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                dest.writeInt(1);
12905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews.writeToParcel(dest, flags);
12915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
12925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                // signifies null
12935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                dest.writeInt(0);
12945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
12951162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
12961162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12971162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        @Override
1298a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
12991162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            final Context context = root.getContext();
13001162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            final ViewGroup target = (ViewGroup) root.findViewById(viewId);
13012b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
13021162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            if (nestedViews != null) {
13031162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                // Inflate nested views and add as children
1304a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                target.addView(nestedViews.apply(context, target, handler));
13052b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            } else {
13061162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                // Clear all children when nested views omitted
13071162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                target.removeAllViews();
13081162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            }
13091162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
13101162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
13113ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        @Override
13123ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
13133ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            if (nestedViews != null) {
13145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                counter.increment(nestedViews.estimateMemoryUsage());
13155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
13165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
13175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
13185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
13195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void setBitmapCache(BitmapCache bitmapCache) {
13205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (nestedViews != null) {
13215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews.setBitmapCache(bitmapCache);
13223ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
13233ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
13243ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
1325fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1326fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ViewGroupAction" + this.nestedViews == null ? "Remove" : "Add";
1327fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1328fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1329fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
1330fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return MERGE_APPEND;
1331fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1332fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
13331162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        RemoteViews nestedViews;
13341162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
13351162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public final static int TAG = 4;
13361162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1339820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * Helper action to set compound drawables on a TextView. Supports relative
1340820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * (s/t/e/b) or cardinal (l/t/r/b) arrangement.
1341820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1342820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    private class TextViewDrawableAction extends Action {
1343820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public TextViewDrawableAction(int viewId, boolean isRelative, int d1, int d2, int d3, int d4) {
1344820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.viewId = viewId;
1345820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.isRelative = isRelative;
1346820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d1 = d1;
1347820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d2 = d2;
1348820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d3 = d3;
1349820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d4 = d4;
1350820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1351820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1352820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public TextViewDrawableAction(Parcel parcel) {
1353820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            viewId = parcel.readInt();
1354820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            isRelative = (parcel.readInt() != 0);
1355820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d1 = parcel.readInt();
1356820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d2 = parcel.readInt();
1357820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d3 = parcel.readInt();
1358820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d4 = parcel.readInt();
1359820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1360820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1361820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public void writeToParcel(Parcel dest, int flags) {
1362820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(TAG);
1363820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(viewId);
1364820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(isRelative ? 1 : 0);
1365820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d1);
1366820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d2);
1367820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d3);
1368820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d4);
1369820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1370820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1371820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        @Override
1372a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
1373820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            final Context context = root.getContext();
1374820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            final TextView target = (TextView) root.findViewById(viewId);
1375820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            if (target == null) return;
1376820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            if (isRelative) {
1377820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler                target.setCompoundDrawablesRelativeWithIntrinsicBounds(d1, d2, d3, d4);
1378820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            } else {
1379820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler                target.setCompoundDrawablesWithIntrinsicBounds(d1, d2, d3, d4);
1380820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            }
1381820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1382820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1383fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1384fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "TextViewDrawableAction";
1385fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1386fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1387820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        boolean isRelative = false;
1388820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        int d1, d2, d3, d4;
1389820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1390820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public final static int TAG = 11;
1391820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1392820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1393820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
139499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * Helper action to set text size on a TextView in any supported units.
13957264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     */
13967264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    private class TextViewSizeAction extends Action {
13977264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public TextViewSizeAction(int viewId, int units, float size) {
13987264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.viewId = viewId;
13997264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.units = units;
14007264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.size = size;
14017264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
14027264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
14037264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public TextViewSizeAction(Parcel parcel) {
14047264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            viewId = parcel.readInt();
14057264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            units = parcel.readInt();
14067264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            size  = parcel.readFloat();
14077264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
14087264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
14097264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public void writeToParcel(Parcel dest, int flags) {
14107264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(TAG);
14117264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(viewId);
14127264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(units);
14137264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeFloat(size);
14147264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
14157264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
14167264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        @Override
1417a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
14187264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            final Context context = root.getContext();
14197264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            final TextView target = (TextView) root.findViewById(viewId);
14207264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            if (target == null) return;
14217264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            target.setTextSize(units, size);
14227264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
14237264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
1424fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1425fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "TextViewSizeAction";
1426fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1427fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
14287264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        int units;
14297264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        float size;
14307264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
14317264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public final static int TAG = 13;
14327264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    }
14337264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
14347264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    /**
143599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * Helper action to set padding on a View.
143699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     */
143799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    private class ViewPaddingAction extends Action {
143899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public ViewPaddingAction(int viewId, int left, int top, int right, int bottom) {
143999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.viewId = viewId;
144099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.left = left;
144199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.top = top;
144299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.right = right;
144399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.bottom = bottom;
144499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
144599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
144699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public ViewPaddingAction(Parcel parcel) {
144799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            viewId = parcel.readInt();
144899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            left = parcel.readInt();
144999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            top = parcel.readInt();
145099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            right = parcel.readInt();
145199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            bottom = parcel.readInt();
145299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
145399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
145499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public void writeToParcel(Parcel dest, int flags) {
145599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(TAG);
145699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(viewId);
145799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(left);
145899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(top);
145999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(right);
146099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(bottom);
146199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
146299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
146399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        @Override
1464a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
146599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            final Context context = root.getContext();
146699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            final View target = root.findViewById(viewId);
146799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            if (target == null) return;
146899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            target.setPadding(left, top, right, bottom);
146999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
147099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
1471fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1472fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ViewPaddingAction";
1473fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1474fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
147599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        int left, top, right, bottom;
147699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
147799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public final static int TAG = 14;
147899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    }
147999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
148099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    /**
14813ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Simple class used to keep track of memory usage in a RemoteViews.
14823ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     *
14833ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
14843ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    private class MemoryUsageCounter {
14853ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        public void clear() {
14865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsage = 0;
14873ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
14883ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void increment(int numBytes) {
14905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsage += numBytes;
14913ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
14923ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public int getMemoryUsage() {
14945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            return mMemoryUsage;
14953ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
14963ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void addBitmapMemory(Bitmap b) {
14985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            final Bitmap.Config c = b.getConfig();
14995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // If we don't know, be pessimistic and assume 4
15005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int bpp = 4;
15015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (c != null) {
15025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                switch (c) {
15035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ALPHA_8:
15045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 1;
15055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
15065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case RGB_565:
15075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ARGB_4444:
15085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 2;
15095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
15105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ARGB_8888:
15115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 4;
15125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
15135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
15145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
15155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            increment(b.getWidth() * b.getHeight() * bpp);
15165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
15175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int mMemoryUsage;
15193ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
15203ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
15213ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new RemoteViews object that will display the views contained
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the specified layout file.
1524e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param packageName Name of the package that contains the layout resource
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layoutId The id of the layout resource
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RemoteViews(String packageName, int layoutId) {
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPackage = packageName;
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayoutId = layoutId;
15315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = new BitmapCache();
15323ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
15333ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // setup the memory usage statistics
15343ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter = new MemoryUsageCounter();
15353ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        recalculateMemoryUsage();
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15386d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    /** {@hide} */
15396d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    public void setUser(UserHandle user) {
15406d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey        mUser = user;
15416d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    }
15426d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey
15435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private boolean hasLandscapeAndPortraitLayouts() {
15445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return (mLandscape != null) && (mPortrait != null);
15455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
15465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15476d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    /**
15485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Create a new RemoteViews object that will inflate as the specified
15495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * landspace or portrait RemoteViews, depending on the current configuration.
15505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     *
15515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @param landscape The RemoteViews to inflate in landscape configuration
15525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @param portrait The RemoteViews to inflate in portrait configuration
15535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
15545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    public RemoteViews(RemoteViews landscape, RemoteViews portrait) {
15555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (landscape == null || portrait == null) {
15565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("Both RemoteViews must be non-null");
15575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
15585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (landscape.getPackage().compareTo(portrait.getPackage()) != 0) {
15595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("Both RemoteViews must share the same package");
15605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
15615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mPackage = portrait.getPackage();
15625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mLayoutId = portrait.getLayoutId();
15635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mLandscape = landscape;
15655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mPortrait = portrait;
15665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // setup the memory usage statistics
15685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mMemoryUsageCounter = new MemoryUsageCounter();
15695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = new BitmapCache();
15715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        configureRemoteViewsAsChild(landscape);
15725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        configureRemoteViewsAsChild(portrait);
15735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        recalculateMemoryUsage();
15755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
15765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Reads a RemoteViews object from a parcel.
1579e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parcel
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RemoteViews(Parcel parcel) {
15835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        this(parcel, null);
15845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
1585ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
15865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews(Parcel parcel, BitmapCache bitmapCache) {
15875d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int mode = parcel.readInt();
15885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // We only store a bitmap cache in the root of the RemoteViews.
15905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (bitmapCache == null) {
15915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmapCache = new BitmapCache(parcel);
15925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
15935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            setBitmapCache(bitmapCache);
15945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            setNotRoot();
15955d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
15965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (mode == MODE_NORMAL) {
15985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPackage = parcel.readString();
15995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLayoutId = parcel.readInt();
16005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mIsWidgetCollectionChild = parcel.readInt() == 1 ? true : false;
16015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
16025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = parcel.readInt();
16035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (count > 0) {
16045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mActions = new ArrayList<Action>(count);
16055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i=0; i<count; i++) {
16065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    int tag = parcel.readInt();
16075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    switch (tag) {
16085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetOnClickPendingIntent.TAG:
16095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetOnClickPendingIntent(parcel));
16105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetDrawableParameters.TAG:
16125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetDrawableParameters(parcel));
16135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ReflectionAction.TAG:
16155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ReflectionAction(parcel));
16165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ViewGroupAction.TAG:
16185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ViewGroupAction(parcel, mBitmapCache));
16195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ReflectionActionWithoutParams.TAG:
16215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ReflectionActionWithoutParams(parcel));
16225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetEmptyView.TAG:
16245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetEmptyView(parcel));
16255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetPendingIntentTemplate.TAG:
16275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetPendingIntentTemplate(parcel));
16285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetOnClickFillInIntent.TAG:
16305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetOnClickFillInIntent(parcel));
16315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetRemoteViewsAdapterIntent.TAG:
16335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetRemoteViewsAdapterIntent(parcel));
16345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case TextViewDrawableAction.TAG:
16365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new TextViewDrawableAction(parcel));
16375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
16387264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                    case TextViewSizeAction.TAG:
16397264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                        mActions.add(new TextViewSizeAction(parcel));
16407264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                        break;
164199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                    case ViewPaddingAction.TAG:
164299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                        mActions.add(new ViewPaddingAction(parcel));
164399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                        break;
16445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case BitmapReflectionAction.TAG:
16455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new BitmapReflectionAction(parcel));
16465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
164750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                    case SetRemoteViewsAdapterList.TAG:
164850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                        mActions.add(new SetRemoteViewsAdapterList(parcel));
164950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen                        break;
16505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    default:
16515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        throw new ActionException("Tag " + tag + " not found");
16525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    }
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
16555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
16565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // MODE_HAS_LANDSCAPE_AND_PORTRAIT
16575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape = new RemoteViews(parcel, mBitmapCache);
16585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait = new RemoteViews(parcel, mBitmapCache);
16595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPackage = mPortrait.getPackage();
16605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLayoutId = mPortrait.getLayoutId();
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16623ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16633ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // setup the memory usage statistics
16643ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter = new MemoryUsageCounter();
16653ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        recalculateMemoryUsage();
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16683ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16693ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen    public RemoteViews clone() {
16703ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        Parcel p = Parcel.obtain();
16713ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        writeToParcel(p, 0);
16723ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        p.setDataPosition(0);
16733ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        return new RemoteViews(p);
167418e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato    }
167518e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getPackage() {
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mPackage;
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
16815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Reutrns the layout id of the root layout associated with this RemoteViews. In the case
16825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * that the RemoteViews has both a landscape and portrait root, this will return the layout
16835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * id associated with the portrait layout.
16845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     *
16855d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @return the layout id.
16865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getLayoutId() {
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayoutId;
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16913ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /*
1692ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * This flag indicates whether this RemoteViews object is being created from a
1693ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * RemoteViewsService for use as a child of a widget collection. This flag is used
1694ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * to determine whether or not certain features are available, in particular,
1695ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * setting on click extras and setting on click pending intents. The former is enabled,
1696ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * and the latter disabled when this flag is true.
1697ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     */
1698ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    void setIsWidgetCollectionChild(boolean isWidgetCollectionChild) {
1699ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        mIsWidgetCollectionChild = isWidgetCollectionChild;
1700ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    }
1701ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
1702ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    /**
17033ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Updates the memory usage statistics.
17043ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
17053ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    private void recalculateMemoryUsage() {
17063ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter.clear();
17073ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
17085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
17095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // Accumulate the memory usage for each action
17105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
17115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                final int count = mActions.size();
17125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i= 0; i < count; ++i) {
17135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mActions.get(i).updateMemoryUsageEstimate(mMemoryUsageCounter);
17145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
17155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
17165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
17175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.addBitmapMemory(mMemoryUsageCounter);
17183ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
17195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
17205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsageCounter.increment(mLandscape.estimateMemoryUsage());
17215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsageCounter.increment(mPortrait.estimateMemoryUsage());
17225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmapCache.addBitmapMemory(mMemoryUsageCounter);
17235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
17245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
17255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
17265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
17275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Recursively sets BitmapCache in the hierarchy and update the bitmap ids.
17285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
17295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private void setBitmapCache(BitmapCache bitmapCache) {
17305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = bitmapCache;
17315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
17325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
17335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                final int count = mActions.size();
17345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i= 0; i < count; ++i) {
17355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mActions.get(i).setBitmapCache(bitmapCache);
17365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
17375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
17385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
17395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape.setBitmapCache(bitmapCache);
17405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait.setBitmapCache(bitmapCache);
17413ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
17423ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
17433ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
17443ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
17453ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Returns an estimate of the bitmap heap memory usage for this RemoteViews.
17463ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
1747311c79c3e93589c6fc720fe6c58ed522af591376Adam Cohen    /** @hide */
1748311c79c3e93589c6fc720fe6c58ed522af591376Adam Cohen    public int estimateMemoryUsage() {
17495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return mMemoryUsageCounter.getMemoryUsage();
17503ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
17513ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
17523ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Add an action to be executed on the remote side when apply is called.
1754e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param a The action to add
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addAction(Action a) {
17585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
17595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("RemoteViews specifying separate landscape and portrait" +
17605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    " layouts cannot be modified. Instead, fully configure the landscape and" +
17615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    " portrait layouts individually before constructing the combined layout.");
17625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mActions == null) {
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mActions = new ArrayList<Action>();
17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mActions.add(a);
17673ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
17683ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // update the memory usage stats
17693ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        a.updateMemoryUsageEstimate(mMemoryUsageCounter);
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17711162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
17721162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
17731162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
17741162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * given {@link RemoteViews}. This allows users to build "nested"
17751162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * {@link RemoteViews}. In cases where consumers of {@link RemoteViews} may
17761162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * recycle layouts, use {@link #removeAllViews(int)} to clear any existing
17771162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * children.
17781162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *
17791162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param viewId The id of the parent {@link ViewGroup} to add child into.
17801162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param nestedView {@link RemoteViews} that describes the child.
17811162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
17821162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    public void addView(int viewId, RemoteViews nestedView) {
17831162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        addAction(new ViewGroupAction(viewId, nestedView));
17841162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
17851162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
17861162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
17871162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#removeAllViews()}.
17881162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *
17891162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param viewId The id of the parent {@link ViewGroup} to remove all
17901162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *            children from.
17911162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
17921162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    public void removeAllViews(int viewId) {
17931162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        addAction(new ViewGroupAction(viewId, null));
17941162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
17951162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17970b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#showNext()}
17982dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     *
17990b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call {@link AdapterViewAnimator#showNext()}
18002dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     */
18012dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    public void showNext(int viewId) {
18022dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        addAction(new ReflectionActionWithoutParams(viewId, "showNext"));
18032dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
18042dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
18052dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    /**
18060b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#showPrevious()}
18072dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     *
18080b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call {@link AdapterViewAnimator#showPrevious()}
18092dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     */
18102dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    public void showPrevious(int viewId) {
18112dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        addAction(new ReflectionActionWithoutParams(viewId, "showPrevious"));
18122dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
18132dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
18142dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    /**
18150b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#setDisplayedChild(int)}
18160b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     *
18170b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call
18180b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     *               {@link AdapterViewAnimator#setDisplayedChild(int)}
18190b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     */
18200b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    public void setDisplayedChild(int viewId, int childIndex) {
18210b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen        setInt(viewId, "setDisplayedChild", childIndex);
18220b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    }
18230b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen
18240b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    /**
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling View.setVisibility
1826e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose visibility should change
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param visibility The new visibility for the view
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setViewVisibility(int viewId, int visibility) {
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setVisibility", visibility);
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1833ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling TextView.setText
1836e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose text should change
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text The new text for the view
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTextViewText(int viewId, CharSequence text) {
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setCharSequence(viewId, "setText", text);
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18437264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
18447264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    /**
18457264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * Equivalent to calling {@link TextView#setTextSize(int, float)}
1846e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18477264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param viewId The id of the view whose text size should change
18487264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param units The units of size (e.g. COMPLEX_UNIT_SP)
18497264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param size The size of the text
18507264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     */
18517264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    public void setTextViewTextSize(int viewId, int units, float size) {
18527264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        addAction(new TextViewSizeAction(viewId, units, size));
18537264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    }
18547264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1856e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * Equivalent to calling
1857820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * {@link TextView#setCompoundDrawablesWithIntrinsicBounds(int, int, int, int)}.
1858820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     *
1859820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param viewId The id of the view whose text should change
1860820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param left The id of a drawable to place to the left of the text, or 0
1861820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param top The id of a drawable to place above the text, or 0
1862820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param right The id of a drawable to place to the right of the text, or 0
1863e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param bottom The id of a drawable to place below the text, or 0
1864820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1865820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    public void setTextViewCompoundDrawables(int viewId, int left, int top, int right, int bottom) {
1866820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        addAction(new TextViewDrawableAction(viewId, false, left, top, right, bottom));
1867820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1868820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1869820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
1870e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * Equivalent to calling {@link
1871820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)}.
1872820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     *
1873820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param viewId The id of the view whose text should change
1874e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param start The id of a drawable to place before the text (relative to the
1875820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * layout direction), or 0
1876820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param top The id of a drawable to place above the text, or 0
1877820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param end The id of a drawable to place after the text, or 0
187866388dcb09018933ccd1d38eae563f0890ba4f06Fabrice Di Meglio     * @param bottom The id of a drawable to place below the text, or 0
1879820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1880820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    public void setTextViewCompoundDrawablesRelative(int viewId, int start, int top, int end, int bottom) {
1881820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        addAction(new TextViewDrawableAction(viewId, true, start, top, end, bottom));
1882820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1883820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1884820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageResource
1886e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose drawable should change
18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param srcId The new resource id for the drawable
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1890e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller    public void setImageViewResource(int viewId, int srcId) {
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setImageResource", srcId);
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageURI
1896e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose drawable should change
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The Uri for the image
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setImageViewUri(int viewId, Uri uri) {
19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setUri(viewId, "setImageURI", uri);
19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageBitmap
1906e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
190793dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view whose bitmap should change
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap The new Bitmap for the drawable
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setImageViewBitmap(int viewId, Bitmap bitmap) {
19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBitmap(viewId, "setImageBitmap", bitmap);
19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19151480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * Equivalent to calling AdapterView.setEmptyView
19161480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     *
19171480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * @param viewId The id of the view on which to set the empty view
19181480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * @param emptyViewId The view id of the empty view
19191480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     */
19201480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    public void setEmptyView(int viewId, int emptyViewId) {
19211480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        addAction(new SetEmptyView(viewId, emptyViewId));
19221480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    }
19231480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
19241480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    /**
19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link Chronometer#setBase Chronometer.setBase},
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Chronometer#setFormat Chronometer.setFormat},
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link Chronometer#start Chronometer.start()} or
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Chronometer#stop Chronometer.stop()}.
1929e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
193093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link Chronometer} to change
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param base The time at which the timer would have read 0:00.  This
19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             time should be based off of
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}.
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param format The Chronometer format string, or null to
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               simply display the timer value.
19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param started True if you want the clock to be started, false if not.
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setChronometer(int viewId, long base, String format, boolean started) {
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setLong(viewId, "setBase", base);
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setString(viewId, "setFormat", format);
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBoolean(viewId, "setStarted", started);
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1943e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link ProgressBar#setMax ProgressBar.setMax},
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ProgressBar#setProgress ProgressBar.setProgress}, and
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ProgressBar#setIndeterminate ProgressBar.setIndeterminate}
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If indeterminate is true, then the values for max and progress are ignored.
1950e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
195193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link ProgressBar} to change
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param max The 100% value for the progress bar
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param progress The current value of the progress bar.
1954e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param indeterminate True if the progress bar is indeterminate,
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                false if not.
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1957e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller    public void setProgressBar(int viewId, int max, int progress,
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean indeterminate) {
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBoolean(viewId, "setIndeterminate", indeterminate);
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!indeterminate) {
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setInt(viewId, "setMax", max);
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setInt(viewId, "setProgress", progress);
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1965e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to launch the provided {@link PendingIntent}.
1970e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
197135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When setting the on-click action of items within collections (eg. {@link ListView},
197235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * {@link StackView} etc.), this method will not work. Instead, use {@link
197335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setPendingIntentTemplate(int, PendingIntent) in conjunction with
197435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setOnClickFillInIntent(int, Intent).
197535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view that will trigger the {@link PendingIntent} when clicked
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pendingIntent The {@link PendingIntent} to send when user clicks
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) {
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new SetOnClickPendingIntent(viewId, pendingIntent));
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
198435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very
198535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * costly to set PendingIntents on the individual items, and is hence not permitted. Instead
198635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * this method should be used to set a single PendingIntent template on the collection, and
198735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * individual items can differentiate their on-click behavior using
198835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * {@link RemoteViews#setOnClickFillInIntent(int, Intent)}.
1989ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *
1990ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * @param viewId The id of the collection who's children will use this PendingIntent template
1991ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *          when clicked
1992ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * @param pendingIntentTemplate The {@link PendingIntent} to be combined with extras specified
1993ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *          by a child of viewId and executed when that child is clicked
1994ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     */
1995ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    public void setPendingIntentTemplate(int viewId, PendingIntent pendingIntentTemplate) {
1996ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        addAction(new SetPendingIntentTemplate(viewId, pendingIntentTemplate));
1997ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    }
1998ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
1999ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    /**
200035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very
200135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * costly to set PendingIntents on the individual items, and is hence not permitted. Instead
200235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * a single PendingIntent template can be set on the collection, see {@link
200335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setPendingIntentTemplate(int, PendingIntent)}, and the individual on-click
200435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * action of a given item can be distinguished by setting a fillInIntent on that item. The
200535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * fillInIntent is then combined with the PendingIntent template in order to determine the final
200635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * intent which will be executed when the item is clicked. This works as follows: any fields
200735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * which are left blank in the PendingIntent template, but are provided by the fillInIntent
200835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * will be overwritten, and the resulting PendingIntent will be used.
200935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
201035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
201135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * of the PendingIntent template will then be filled in with the associated fields that are
201235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * set in fillInIntent. See {@link Intent#fillIn(Intent, int)} for more details.
201335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
201435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * @param viewId The id of the view on which to set the fillInIntent
201535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * @param fillInIntent The intent which will be combined with the parent's PendingIntent
201635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *        in order to determine the on-click behavior of the view specified by viewId
201735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     */
201835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    public void setOnClickFillInIntent(int viewId, Intent fillInIntent) {
201935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        addAction(new SetOnClickFillInIntent(viewId, fillInIntent));
202035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    }
202135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
202235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    /**
20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * view.
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * You can omit specific calls by marking their values with null or -1.
2030e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view that contains the target
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link Drawable}
20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param targetBackground If true, apply these parameters to the
20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link Drawable} returned by
20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link android.view.View#getBackground()}. Otherwise, assume
20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the target view is an {@link ImageView} and apply them to
20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link ImageView#getDrawable()}.
20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param alpha Specify an alpha value for the drawable, or -1 to leave
20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colorFilter Specify a color for a
20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link android.graphics.ColorFilter} for this drawable, or -1
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            to leave unchanged.
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Specify a PorterDuff mode for this drawable, or null to leave
20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param level Specify the level for the drawable, or -1 to leave
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDrawableParameters(int viewId, boolean targetBackground, int alpha,
20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int colorFilter, PorterDuff.Mode mode, int level) {
20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new SetDrawableParameters(viewId, targetBackground, alpha,
20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                colorFilter, mode, level));
20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link android.widget.TextView#setTextColor(int)}.
2056e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
205793dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view whose text color should change
20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param color Sets the text color for all the states (normal, selected,
20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            focused) to be this color.
20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTextColor(int viewId, int color) {
20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setTextColor", color);
20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2065592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
20663b4ca103f8cdc6b959f3b2ac68f6cb27002e7b77Adam Cohen     * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
2067499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
2068037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @param appWidgetId The id of the app widget which contains the specified view. (This
2069037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *      parameter is ignored in this deprecated method)
207050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * @param viewId The id of the {@link AdapterView}
207181f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     * @param intent The intent of the service which will be
207281f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     *            providing data to the RemoteViewsAdapter
2073037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @deprecated This method has been deprecated. See
2074037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *      {@link android.widget.RemoteViews#setRemoteAdapter(int, Intent)}
207581f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     */
2076037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    @Deprecated
207781f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung    public void setRemoteAdapter(int appWidgetId, int viewId, Intent intent) {
2078037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        setRemoteAdapter(viewId, intent);
2079037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    }
2080037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
2081037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    /**
2082037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
2083037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * Can only be used for App Widgets.
2084037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *
208550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * @param viewId The id of the {@link AdapterView}
2086037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @param intent The intent of the service which will be
2087037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *            providing data to the RemoteViewsAdapter
2088037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     */
2089037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    public void setRemoteAdapter(int viewId, Intent intent) {
2090037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        addAction(new SetRemoteViewsAdapterIntent(viewId, intent));
2091499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2092499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2093499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
209450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * Creates a simple Adapter for the viewId specified. The viewId must point to an AdapterView,
209550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * ie. {@link ListView}, {@link GridView}, {@link StackView} or {@link AdapterViewAnimator}.
209650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * This is a simpler but less flexible approach to populating collection widgets. Its use is
209750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * encouraged for most scenarios, as long as the total memory within the list of RemoteViews
209850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * is relatively small (ie. doesn't contain large or numerous Bitmaps, see {@link
209950f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * RemoteViews#setImageViewBitmap}). In the case of numerous images, the use of API is still
210050f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * possible by setting image URIs instead of Bitmaps, see {@link RemoteViews#setImageViewUri}.
210150f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     *
210250f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * This API is supported in the compatibility library for previous API levels, see
210350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * RemoteViewsCompat.
210450f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     *
210550f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * @param viewId The id of the {@link AdapterView}
210650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     * @param list The list of RemoteViews which will populate the view specified by viewId.
2107b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen     * @param viewTypeCount The maximum number of unique layout id's used to construct the list of
2108b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen     *      RemoteViews. This count cannot change during the life-cycle of a given widget, so this
2109b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen     *      parameter should account for the maximum possible number of types that may appear in the
2110b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen     *      See {@link Adapter#getViewTypeCount()}.
211133f3aab220e083a4af975786e941cf42d380871fAdam Cohen     *
211233f3aab220e083a4af975786e941cf42d380871fAdam Cohen     * @hide
211350f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen     */
2114b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen    public void setRemoteAdapter(int viewId, ArrayList<RemoteViews> list, int viewTypeCount) {
2115b00d9f0e07993d47d49cfa2cf8d7026b8c5b0f2eAdam Cohen        addAction(new SetRemoteViewsAdapterList(viewId, list, viewTypeCount));
211650f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen    }
211750f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen
211850f3d1bae884eb9545d3db24362271c20f0d8d64Adam Cohen    /**
2119499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
2120499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
212193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view to change
2122499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * @param position Scroll to this adapter position
2123499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2124499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setScrollPosition(int viewId, int position) {
2125499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        setInt(viewId, "smoothScrollToPosition", position);
2126499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2127499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2128499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
2129499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
2130499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
213193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view to change
213295362595ed4a42aec87b4d166092b30c8139d220Winson Chung     * @param offset Scroll by this adapter position offset
2133499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2134499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setRelativeScrollPosition(int viewId, int offset) {
2135499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        setInt(viewId, "smoothScrollByOffset", offset);
2136499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2137499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2138499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
2139d5353b475001f19e3cbc9c1a4165c9e6038a812fDaniel Sandler     * Equivalent to calling {@link android.view.View#setPadding(int, int, int, int)}.
214099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     *
214199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param viewId The id of the view to change
214299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param left the left padding in pixels
214399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param top the top padding in pixels
214499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param right the right padding in pixels
214599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param bottom the bottom padding in pixels
214699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     */
214799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    public void setViewPadding(int viewId, int left, int top, int right, int bottom) {
214899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        addAction(new ViewPaddingAction(viewId, left, top, right, bottom));
214999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    }
215099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
215199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    /**
2152592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one boolean on a view in the layout for this RemoteViews.
2153592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
215493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2155592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2156592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2157592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBoolean(int viewId, String methodName, boolean value) {
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BOOLEAN, value));
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2162592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2163592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one byte on a view in the layout for this RemoteViews.
2164592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
216593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2166592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2167592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2168592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setByte(int viewId, String methodName, byte value) {
21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BYTE, value));
21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2173592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2174592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one short on a view in the layout for this RemoteViews.
2175592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
217693dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2177592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2178592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2179592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setShort(int viewId, String methodName, short value) {
21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.SHORT, value));
21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2184592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2185592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one int on a view in the layout for this RemoteViews.
2186592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
218793dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2188592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2189592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2190592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInt(int viewId, String methodName, int value) {
21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INT, value));
21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2195592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2196592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one long on a view in the layout for this RemoteViews.
2197592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
219893dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2199592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2200592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2201592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
22029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLong(int viewId, String methodName, long value) {
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.LONG, value));
22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2206592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2207592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one float on a view in the layout for this RemoteViews.
2208592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
220993dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2210592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2211592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2212592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFloat(int viewId, String methodName, float value) {
22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.FLOAT, value));
22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2217592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2218592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one double on a view in the layout for this RemoteViews.
2219592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
222093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2221592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2222592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2223592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDouble(int viewId, String methodName, double value) {
22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.DOUBLE, value));
22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2228592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2229592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one char on a view in the layout for this RemoteViews.
2230592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
223193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2232592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2233592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2234592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setChar(int viewId, String methodName, char value) {
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR, value));
22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2240592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one String on a view in the layout for this RemoteViews.
2241592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
224293dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2243592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2244592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2245592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
22469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setString(int viewId, String methodName, String value) {
22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.STRING, value));
22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2250592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2251592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one CharSequence on a view in the layout for this RemoteViews.
2252592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
225393dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2254592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2255592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2256592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCharSequence(int viewId, String methodName, CharSequence value) {
22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE, value));
22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2261592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2262592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one Uri on a view in the layout for this RemoteViews.
2263592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
226493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2265592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2266592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2267592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setUri(int viewId, String methodName, Uri value) {
2269a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey        if (value != null) {
2270a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey            // Resolve any filesystem path before sending remotely
2271a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey            value = value.getCanonicalUri();
2272a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey            if (StrictMode.vmFileUriExposureEnabled()) {
2273a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey                value.checkFileUriExposed("RemoteViews.setUri()");
2274a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey            }
2275a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey        }
22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.URI, value));
22779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2280592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one Bitmap on a view in the layout for this RemoteViews.
2281592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @more
2282592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * <p class="note">The bitmap will be flattened into the parcel if this object is
2283592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * sent across processes, so it may end up using a lot of memory, and may be fairly slow.</p>
2284592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
228593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2286592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2287592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2288592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBitmap(int viewId, String methodName, Bitmap value) {
22905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        addAction(new BitmapReflectionAction(viewId, methodName, value));
22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2294d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * Call a method taking one Bundle on a view in the layout for this RemoteViews.
2295d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     *
229693dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2297d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * @param methodName The name of the method to call.
2298d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * @param value The value to pass to the method.
2299d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     */
2300d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    public void setBundle(int viewId, String methodName, Bundle value) {
2301d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BUNDLE, value));
2302d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    }
2303d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert
2304d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    /**
230593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * Call a method taking one Intent on a view in the layout for this RemoteViews.
2306499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
230793dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
230893dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param methodName The name of the method to call.
230993dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param value The {@link android.content.Intent} to pass the method.
2310499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2311499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setIntent(int viewId, String methodName, Intent value) {
2312499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INTENT, value));
2313499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2314499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2315499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
231633aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * Equivalent to calling View.setContentDescription(CharSequence).
2317e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov     *
231833aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param viewId The id of the view whose content description should change.
231933aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param contentDescription The new content description for the view.
2320e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov     */
2321e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    public void setContentDescription(int viewId, CharSequence contentDescription) {
2322e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov        setCharSequence(viewId, "setContentDescription", contentDescription);
2323e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    }
2324e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov
232533aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    /**
232633aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * Equivalent to calling View.setLabelFor(int).
232733aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     *
232833aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param viewId The id of the view whose property to set.
232933aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param labeledId The id of a view for which this view serves as a label.
233033aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     */
233133aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    public void setLabelFor(int viewId, int labeledId) {
233233aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov        setInt(viewId, "setLabelFor", labeledId);
233333aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    }
233433aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov
23355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews getRemoteViewsToApply(Context context) {
23365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
23375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int orientation = context.getResources().getConfiguration().orientation;
23385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
23395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mLandscape;
23405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
23415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mPortrait;
23425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
23445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return this;
23455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
23465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
2347e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    /**
23489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Inflates the view hierarchy represented by this object and applies
23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * all of the actions.
2350e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
23519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><strong>Caller beware: this may throw</strong>
2352e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Default context to use
23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent Parent that the resulting view hierarchy will be attached to. This method
23559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * does <strong>not</strong> attach the hierarchy. The caller should do so when appropriate.
23569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The inflated view hierarchy
23579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
23589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View apply(Context context, ViewGroup parent) {
2359e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller        return apply(context, parent, null);
23601927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    }
23611927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
2362a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    /** @hide */
2363a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    public View apply(Context context, ViewGroup parent, OnClickHandler handler) {
23645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        RemoteViews rvToApply = getRemoteViewsToApply(context);
23655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
2366a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        View result;
23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Context c = prepareContext(context);
23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2370a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        LayoutInflater inflater = (LayoutInflater)
2371a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inflater = inflater.cloneInContext(c);
23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inflater.setFilter(this);
23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        result = inflater.inflate(rvToApply.getLayoutId(), parent, false);
23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2378a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        rvToApply.performApply(result, parent, handler);
23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
23849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Applies all of the actions to the provided view.
23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><strong>Caller beware: this may throw</strong>
2387e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param v The view to apply the actions to.  This should be the result of
23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #apply(Context,ViewGroup)} call.
23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void reapply(Context context, View v) {
2392e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller        reapply(context, v, null);
2393a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    }
2394a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn
2395a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    /** @hide */
2396a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    public void reapply(Context context, View v, OnClickHandler handler) {
23975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        RemoteViews rvToApply = getRemoteViewsToApply(context);
23985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
23995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // In the case that a view has this RemoteViews applied in one orientation, is persisted
24005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // across orientation change, and has the RemoteViews re-applied in the new orientation,
24015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // we throw an exception, since the layouts may be completely unrelated.
24025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
24035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (v.getId() != rvToApply.getLayoutId()) {
24045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" +
24055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        " that does not share the same root layout id.");
24065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
24075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
24085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        prepareContext(context);
2410a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        rvToApply.performApply(v, (ViewGroup) v.getParent(), handler);
24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2413a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    private void performApply(View v, ViewGroup parent, OnClickHandler handler) {
24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mActions != null) {
2415e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller            handler = handler == null ? DEFAULT_ON_CLICK_HANDLER : handler;
24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mActions.size();
24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
24189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Action a = mActions.get(i);
2419a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                a.apply(v, parent, handler);
24209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context prepareContext(Context context) {
2425a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        Context c;
24269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String packageName = mPackage;
24279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (packageName != null) {
24299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
24306d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey                c = context.createPackageContextAsUser(
24316d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey                        packageName, Context.CONTEXT_RESTRICTED, mUser);
24329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (NameNotFoundException e) {
24339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.e(LOG_TAG, "Package name " + packageName + " not found");
24349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c = context;
24359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
24379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c = context;
24389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;
24419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* (non-Javadoc)
24449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used to restrict the views which can be inflated
2445e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
24469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.view.LayoutInflater.Filter#onLoadClass(java.lang.Class)
24479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2448e6ac8b9aade9443ab8456c8f7a47cdfba3b70266Gilles Debunne    public boolean onLoadClass(Class clazz) {
24499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return clazz.isAnnotationPresent(RemoteView.class);
24509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
24529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int describeContents() {
24539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
24549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToParcel(Parcel dest, int flags) {
24575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
24585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(MODE_NORMAL);
24595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // We only write the bitmap cache if we are the root RemoteViews, as this cache
24605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // is shared by all children.
24615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
24625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.writeBitmapsToParcel(dest, flags);
24635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
24645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeString(mPackage);
24655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(mLayoutId);
24665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
24675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count;
24685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
24695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                count = mActions.size();
24705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
24715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                count = 0;
24725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
24735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(count);
24745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i=0; i<count; i++) {
24755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Action a = mActions.get(i);
24765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                a.writeToParcel(dest, 0);
24775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
24789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
24795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(MODE_HAS_LANDSCAPE_AND_PORTRAIT);
24805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // We only write the bitmap cache if we are the root RemoteViews, as this cache
24815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // is shared by all children.
24825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
24835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.writeBitmapsToParcel(dest, flags);
24845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
24855d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape.writeToParcel(dest, flags);
24865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait.writeToParcel(dest, flags);
24879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
24919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parcelable.Creator that instantiates RemoteViews objects
24929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
24939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final Parcelable.Creator<RemoteViews> CREATOR = new Parcelable.Creator<RemoteViews>() {
24949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public RemoteViews createFromParcel(Parcel parcel) {
24959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new RemoteViews(parcel);
24969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public RemoteViews[] newArray(int size) {
24999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new RemoteViews[size];
25009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
25029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2503