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;
376d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkeyimport android.os.UserHandle;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
41dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport android.view.LayoutInflater.Filter;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.RemotableViewMethod;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View.OnClickListener;
45dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport android.view.ViewGroup;
46a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohenimport android.widget.AdapterView.OnItemClickListener;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
48dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.ElementType;
49dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.Retention;
50dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.RetentionPolicy;
51dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.Target;
52dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.reflect.Method;
53dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.util.ArrayList;
54fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohenimport java.util.HashMap;
55dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
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) {
34335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                Log.e("RemoteViews", "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.
36235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            Log.e("RemoteViews", "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)) {
36835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            Log.e("RemoteViews", "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 {
475ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen                Log.e("RemoteViews", "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
490037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    private class SetRemoteViewsAdapterIntent extends Action {
491037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public SetRemoteViewsAdapterIntent(int id, Intent intent) {
492037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            this.viewId = id;
493037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            this.intent = intent;
494037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
495037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
496037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public SetRemoteViewsAdapterIntent(Parcel parcel) {
497037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            viewId = parcel.readInt();
498037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent = Intent.CREATOR.createFromParcel(parcel);
499037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
500037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
501037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public void writeToParcel(Parcel dest, int flags) {
502037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            dest.writeInt(TAG);
503037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            dest.writeInt(viewId);
504037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent.writeToParcel(dest, flags);
505037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
506037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
507037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        @Override
508a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
509037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            final View target = root.findViewById(viewId);
510037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (target == null) return;
511037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
512037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Ensure that we are applying to an AppWidget root
513037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (!(rootParent instanceof AppWidgetHostView)) {
514037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                Log.e("RemoteViews", "SetRemoteViewsAdapterIntent action can only be used for " +
515037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                        "AppWidgets (root id: " + viewId + ")");
516037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                return;
517037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
518037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Ensure that we are calling setRemoteAdapter on an AdapterView that supports it
519037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (!(target instanceof AbsListView) && !(target instanceof AdapterViewAnimator)) {
520037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                Log.e("RemoteViews", "Cannot setRemoteViewsAdapter on a view which is not " +
521037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                        "an AbsListView or AdapterViewAnimator (id: " + viewId + ")");
522037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                return;
523037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
524037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
525037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Embed the AppWidget Id for use in RemoteViewsAdapter when connecting to the intent
526037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // RemoteViewsService
527037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            AppWidgetHostView host = (AppWidgetHostView) rootParent;
528037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId());
529037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (target instanceof AbsListView) {
530037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                AbsListView v = (AbsListView) target;
531037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                v.setRemoteViewsAdapter(intent);
532a6a4cbc18f7e5a3831d787d3f398e02c5eae6512Adam Cohen                v.setRemoteViewsOnClickHandler(handler);
533037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            } else if (target instanceof AdapterViewAnimator) {
534037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                AdapterViewAnimator v = (AdapterViewAnimator) target;
535037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                v.setRemoteViewsAdapter(intent);
536a6a4cbc18f7e5a3831d787d3f398e02c5eae6512Adam Cohen                v.setRemoteViewsOnClickHandler(handler);
537037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
538037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
539037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
540fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
541fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetRemoteViewsAdapterIntent";
542fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
543fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
544037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        Intent intent;
545037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
546037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public final static int TAG = 10;
547037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    }
548037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to launch the provided {@link PendingIntent}.
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class SetOnClickPendingIntent extends Action {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetOnClickPendingIntent(int id, PendingIntent pendingIntent) {
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = id;
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.pendingIntent = pendingIntent;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
559ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetOnClickPendingIntent(Parcel parcel) {
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            viewId = parcel.readInt();
562c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
563c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // We check a flag to determine if the parcel contains a PendingIntent.
564c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (parcel.readInt() != 0) {
565c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
566c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            }
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
568ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel dest, int flags) {
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(TAG);
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(viewId);
572c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
573c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // We use a flag to indicate whether the parcel contains a valid object.
574c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            dest.writeInt(pendingIntent != null ? 1 : 0);
575c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (pendingIntent != null) {
576c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                pendingIntent.writeToParcel(dest, 0 /* no flags */);
577c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            }
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
579ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
581a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View target = root.findViewById(viewId);
5832b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
584ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
585ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            // If the view is an AdapterView, setting a PendingIntent on click doesn't make much
586ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            // sense, do they mean to set a PendingIntent template for the AdapterView's children?
587ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            if (mIsWidgetCollectionChild) {
588636fd528f7ad51f565a390226d9f469f8c675ccfDianne Hackborn                Log.w("RemoteViews", "Cannot setOnClickPendingIntent for collection item " +
589c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        "(id: " + viewId + ")");
590ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                ApplicationInfo appInfo = root.getContext().getApplicationInfo();
591ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen
592ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                // We let this slide for HC and ICS so as to not break compatibility. It should have
593ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                // been disabled from the outset, but was left open by accident.
594ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                if (appInfo != null &&
595ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                        appInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
596ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                    return;
597ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                }
598ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            }
599ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
600c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (target != null) {
601c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                // If the pendingIntent is null, we clear the onClickListener
602c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                OnClickListener listener = null;
603c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                if (pendingIntent != null) {
604c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    listener = new OnClickListener() {
605c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        public void onClick(View v) {
606c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            // Find target view location in screen coordinates and
607c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            // fill into PendingIntent before sending.
608c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final float appScale = v.getContext().getResources()
609c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                                    .getCompatibilityInfo().applicationScale;
610c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final int[] pos = new int[2];
611c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            v.getLocationOnScreen(pos);
612e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
613c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final Rect rect = new Rect();
614c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.left = (int) (pos[0] * appScale + 0.5f);
615c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.top = (int) (pos[1] * appScale + 0.5f);
616c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
617c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
618e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
619c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final Intent intent = new Intent();
620c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            intent.setSourceBounds(rect);
621a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                            handler.onClickHandler(v, pendingIntent, intent);
622c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        }
623c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    };
624c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                target.setOnClickListener(listener);
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
628c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
629fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
630fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetOnClickPendingIntent";
631fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
632fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PendingIntent pendingIntent;
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final static int TAG = 1;
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given view.
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These operations will be performed on the {@link Drawable} returned by the
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * target {@link View#getBackground()} by default.  If targetBackground is false,
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * we assume the target is an {@link ImageView} and try applying the operations
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to {@link ImageView#getDrawable()}.
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * You can omit specific calls by marking their values with null or -1.
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class SetDrawableParameters extends Action {
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetDrawableParameters(int id, boolean targetBackground, int alpha,
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int colorFilter, PorterDuff.Mode mode, int level) {
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = id;
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.targetBackground = targetBackground;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.alpha = alpha;
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.colorFilter = colorFilter;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.filterMode = mode;
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.level = level;
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
660e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetDrawableParameters(Parcel parcel) {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            viewId = parcel.readInt();
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            targetBackground = parcel.readInt() != 0;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            alpha = parcel.readInt();
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            colorFilter = parcel.readInt();
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean hasMode = parcel.readInt() != 0;
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (hasMode) {
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filterMode = PorterDuff.Mode.valueOf(parcel.readString());
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filterMode = null;
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            level = parcel.readInt();
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
674e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel dest, int flags) {
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(TAG);
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(viewId);
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(targetBackground ? 1 : 0);
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(alpha);
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(colorFilter);
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (filterMode != null) {
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeInt(1);
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeString(filterMode.toString());
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeInt(0);
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(level);
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
689e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
691a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View target = root.findViewById(viewId);
6932b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
694e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Pick the correct drawable to modify for this view
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable targetDrawable = null;
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (targetBackground) {
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                targetDrawable = target.getBackground();
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (target instanceof ImageView) {
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ImageView imageView = (ImageView) target;
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                targetDrawable = imageView.getDrawable();
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
703e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
704a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            if (targetDrawable != null) {
705a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                // Perform modifications only if values are set correctly
706a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (alpha != -1) {
707a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setAlpha(alpha);
708a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
709a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (colorFilter != -1 && filterMode != null) {
710a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setColorFilter(colorFilter, filterMode);
711a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
712a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (level != -1) {
713a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setLevel(level);
714a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7173ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
718fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
719fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetDrawableParameters";
720fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
721fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean targetBackground;
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int alpha;
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int colorFilter;
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PorterDuff.Mode filterMode;
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int level;
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final static int TAG = 3;
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
730e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
7312dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    private class ReflectionActionWithoutParams extends Action {
7322dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        String methodName;
7332dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7342dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        public final static int TAG = 5;
7352dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7362dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        ReflectionActionWithoutParams(int viewId, String methodName) {
7372dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.viewId = viewId;
7382dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.methodName = methodName;
7392dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
7402dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7412dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        ReflectionActionWithoutParams(Parcel in) {
7422dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.viewId = in.readInt();
7432dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.methodName = in.readString();
7442dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
7452dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7462dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        public void writeToParcel(Parcel out, int flags) {
7472dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeInt(TAG);
7482dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeInt(this.viewId);
7492dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeString(this.methodName);
7502dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
7512dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7522dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        @Override
753a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
7542dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            final View view = root.findViewById(viewId);
7552b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (view == null) return;
7562dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7572dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            Class klass = view.getClass();
7582dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            Method method;
7592dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            try {
7602dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                method = klass.getMethod(this.methodName);
7612dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            } catch (NoSuchMethodException ex) {
7622dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
7632dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
7642dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
7652dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7662dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
7672dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException("view: " + klass.getName()
7682dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + " can't use method with RemoteViews: "
7692dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
7702dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
7712dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7722dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            try {
7732dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                //noinspection ConstantIfStatement
7742dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                if (false) {
7752dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                    Log.d("RemoteViews", "view: " + klass.getName() + " calling method: "
7762dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
7772dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                }
7782dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                method.invoke(view);
7792dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            } catch (Exception ex) {
7802dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException(ex);
7812dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
7822dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
783fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
784fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
785fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // we don't need to build up showNext or showPrevious calls
786fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (methodName.equals("showNext") || methodName.equals("showPrevious")) {
787fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_IGNORE;
788fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            } else {
789fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_REPLACE;
790fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            }
791fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
792fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
793fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
794fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ReflectionActionWithoutParams";
795fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
7962dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
7972dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private static class BitmapCache {
7995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        ArrayList<Bitmap> mBitmaps;
8005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public BitmapCache() {
8025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmaps = new ArrayList<Bitmap>();
8035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public BitmapCache(Parcel source) {
8065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = source.readInt();
8075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmaps = new ArrayList<Bitmap>();
8085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
8095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Bitmap b = Bitmap.CREATOR.createFromParcel(source);
8105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmaps.add(b);
8115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public int getBitmapId(Bitmap b) {
8155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (b == null) {
8165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return -1;
8175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
8185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                if (mBitmaps.contains(b)) {
8195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    return mBitmaps.indexOf(b);
8205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                } else {
8215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mBitmaps.add(b);
8225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    return (mBitmaps.size() - 1);
8235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
8245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public Bitmap getBitmapForId(int id) {
8285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (id == -1 || id >= mBitmaps.size()) {
8295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return null;
8305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
8315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mBitmaps.get(id);
8325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void writeBitmapsToParcel(Parcel dest, int flags) {
8365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = mBitmaps.size();
8375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(count);
8385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
8395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmaps.get(i).writeToParcel(dest, flags);
8405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void assimilate(BitmapCache bitmapCache) {
8445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            ArrayList<Bitmap> bitmapsToBeAdded = bitmapCache.mBitmaps;
8455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = bitmapsToBeAdded.size();
8465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
8475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Bitmap b = bitmapsToBeAdded.get(i);
8485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                if (!mBitmaps.contains(b)) {
8495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mBitmaps.add(b);
8505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
8515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void addBitmapMemory(MemoryUsageCounter memoryCounter) {
8555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < mBitmaps.size(); i++) {
8565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                memoryCounter.addBitmapMemory(mBitmaps.get(i));
8575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
8605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private class BitmapReflectionAction extends Action {
8625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int bitmapId;
8635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        Bitmap bitmap;
8645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        String methodName;
8655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        BitmapReflectionAction(int viewId, String methodName, Bitmap bitmap) {
8675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.bitmap = bitmap;
8685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.viewId = viewId;
8695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.methodName = methodName;
8705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = mBitmapCache.getBitmapId(bitmap);
8715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        BitmapReflectionAction(Parcel in) {
8745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            viewId = in.readInt();
8755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            methodName = in.readString();
8765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = in.readInt();
8775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmap = mBitmapCache.getBitmapForId(bitmapId);
8785d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
8815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void writeToParcel(Parcel dest, int flags) {
8825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(TAG);
8835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(viewId);
8845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeString(methodName);
8855d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(bitmapId);
8865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8875d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
889a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent,
890a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                OnClickHandler handler) throws ActionException {
8915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            ReflectionAction ra = new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP,
8925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bitmap);
893a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn            ra.apply(root, rootParent, handler);
8945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8955d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
8975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void setBitmapCache(BitmapCache bitmapCache) {
8985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = bitmapCache.getBitmapId(bitmap);
8995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
9005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
901fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
902fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "BitmapReflectionAction";
903fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
904fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
9055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public final static int TAG = 12;
9065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
9075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Base class for the reflection actions.
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class ReflectionAction extends Action {
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int TAG = 2;
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BOOLEAN = 1;
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BYTE = 2;
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int SHORT = 3;
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int INT = 4;
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int LONG = 5;
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int FLOAT = 6;
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int DOUBLE = 7;
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int CHAR = 8;
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int STRING = 9;
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int CHAR_SEQUENCE = 10;
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int URI = 11;
925fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // BITMAP actions are never stored in the list of actions. They are only used locally
926fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // to implement BitmapReflectionAction, which eliminates duplicates using BitmapCache.
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BITMAP = 12;
928d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert        static final int BUNDLE = 13;
929499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        static final int INTENT = 14;
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String methodName;
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int type;
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object value;
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ReflectionAction(int viewId, String methodName, int type, Object value) {
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = viewId;
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.methodName = methodName;
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.type = type;
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.value = value;
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ReflectionAction(Parcel in) {
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = in.readInt();
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.methodName = in.readString();
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.type = in.readInt();
946a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            //noinspection ConstantIfStatement
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (false) {
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.d("RemoteViews", "read viewId=0x" + Integer.toHexString(this.viewId)
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " methodName=" + this.methodName + " type=" + this.type);
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
951c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
952c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // For some values that may have been null, we first check a flag to see if they were
953c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // written to the parcel.
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readInt() != 0;
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readByte();
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = (short)in.readInt();
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readInt();
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readLong();
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readFloat();
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readDouble();
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = (char)in.readInt();
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readString();
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
986c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
987c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Uri.CREATOR.createFromParcel(in);
988c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
991c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
992c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Bitmap.CREATOR.createFromParcel(in);
993c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
995d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
996d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    this.value = in.readBundle();
997d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    break;
998499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
999c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
1000c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Intent.CREATOR.createFromParcel(in);
1001c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
1002499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    break;
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel out, int flags) {
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(TAG);
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(this.viewId);
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeString(this.methodName);
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(this.type);
1013a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            //noinspection ConstantIfStatement
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (false) {
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.d("RemoteViews", "write viewId=0x" + Integer.toHexString(this.viewId)
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " methodName=" + this.methodName + " type=" + this.type);
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1018c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
1019c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // For some values which are null, we record an integer flag to indicate whether
1020c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // we have written a valid value to the parcel.
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
1023a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Boolean) this.value ? 1 : 0);
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
1026a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeByte((Byte) this.value);
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
1029a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Short) this.value);
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
1032a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Integer) this.value);
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
1035a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeLong((Long) this.value);
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
1038a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeFloat((Float) this.value);
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
1041a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeDouble((Double) this.value);
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    out.writeInt((int)((Character)this.value).charValue());
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    out.writeString((String)this.value);
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
1050e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller                    TextUtils.writeToParcel((CharSequence)this.value, out, flags);
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
1053c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1054c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1055c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Uri)this.value).writeToParcel(out, flags);
1056c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
1059c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1060c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1061c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Bitmap)this.value).writeToParcel(out, flags);
1062c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1064d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
1065d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    out.writeBundle((Bundle) this.value);
1066d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    break;
1067499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
1068c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1069c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1070c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Intent)this.value).writeToParcel(out, flags);
1071c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
1072499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    break;
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private Class getParameterType() {
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return boolean.class;
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return byte.class;
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return short.class;
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return int.class;
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return long.class;
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return float.class;
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return double.class;
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return char.class;
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return String.class;
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return CharSequence.class;
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return Uri.class;
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return Bitmap.class;
1104d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
1105d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    return Bundle.class;
1106499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
1107499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    return Intent.class;
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return null;
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1114a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View view = root.findViewById(viewId);
11162b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (view == null) return;
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Class param = getParameterType();
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (param == null) {
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("bad type: " + this.type);
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Class klass = view.getClass();
1124a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            Method method;
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                method = klass.getMethod(this.methodName, getParameterType());
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            catch (NoSuchMethodException ex) {
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ")");
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("view: " + klass.getName()
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " can't use method with RemoteViews: "
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ")");
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
1140a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                //noinspection ConstantIfStatement
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (false) {
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.d("RemoteViews", "view: " + klass.getName() + " calling method: "
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ") with "
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + (this.value == null ? "null" : this.value.getClass().getName()));
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                method.invoke(view, this.value);
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            catch (Exception ex) {
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException(ex);
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11523ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
1153fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
1154fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // smoothScrollBy is cumulative, everything else overwites.
1155fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (methodName.equals("smoothScrollBy")) {
1156fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_APPEND;
1157fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            } else {
1158fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_REPLACE;
11593ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
11603ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
1161fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1162fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1163fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // Each type of reflection action corresponds to a setter, so each should be seen as
1164fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // unique from the standpoint of merging.
1165fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ReflectionAction" + this.methodName + this.type;
1166fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private void configureRemoteViewsAsChild(RemoteViews rv) {
11705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache.assimilate(rv.mBitmapCache);
11715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        rv.setBitmapCache(mBitmapCache);
11725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        rv.setNotRoot();
11735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
11745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
11755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    void setNotRoot() {
11765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mIsRoot = false;
11775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
11785d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
11791162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
11801162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
11811162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * given {@link RemoteViews}, or calling {@link ViewGroup#removeAllViews()}
11821162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * when null. This allows users to build "nested" {@link RemoteViews}.
11831162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
11841162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    private class ViewGroupAction extends Action {
11851162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public ViewGroupAction(int viewId, RemoteViews nestedViews) {
11861162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            this.viewId = viewId;
11871162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            this.nestedViews = nestedViews;
1188c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen            if (nestedViews != null) {
1189c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen                configureRemoteViewsAsChild(nestedViews);
1190c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen            }
11911162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
11921162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
11935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public ViewGroupAction(Parcel parcel, BitmapCache bitmapCache) {
11941162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            viewId = parcel.readInt();
11955d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            boolean nestedViewsNull = parcel.readInt() == 0;
11965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (!nestedViewsNull) {
11975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews = new RemoteViews(parcel, bitmapCache);
11985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
11995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews = null;
12005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
12011162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
12021162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12031162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public void writeToParcel(Parcel dest, int flags) {
12041162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            dest.writeInt(TAG);
12051162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            dest.writeInt(viewId);
12065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (nestedViews != null) {
12075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                dest.writeInt(1);
12085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews.writeToParcel(dest, flags);
12095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
12105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                // signifies null
12115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                dest.writeInt(0);
12125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
12131162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
12141162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12151162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        @Override
1216a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
12171162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            final Context context = root.getContext();
12181162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            final ViewGroup target = (ViewGroup) root.findViewById(viewId);
12192b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
12201162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            if (nestedViews != null) {
12211162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                // Inflate nested views and add as children
1222a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                target.addView(nestedViews.apply(context, target, handler));
12232b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            } else {
12241162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                // Clear all children when nested views omitted
12251162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                target.removeAllViews();
12261162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            }
12271162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
12281162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12293ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        @Override
12303ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
12313ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            if (nestedViews != null) {
12325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                counter.increment(nestedViews.estimateMemoryUsage());
12335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
12345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
12355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
12365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
12375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void setBitmapCache(BitmapCache bitmapCache) {
12385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (nestedViews != null) {
12395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews.setBitmapCache(bitmapCache);
12403ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
12413ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
12423ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
1243fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1244fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ViewGroupAction" + this.nestedViews == null ? "Remove" : "Add";
1245fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1246fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1247fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
1248fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return MERGE_APPEND;
1249fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1250fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
12511162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        RemoteViews nestedViews;
12521162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12531162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public final static int TAG = 4;
12541162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1257820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * Helper action to set compound drawables on a TextView. Supports relative
1258820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * (s/t/e/b) or cardinal (l/t/r/b) arrangement.
1259820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1260820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    private class TextViewDrawableAction extends Action {
1261820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public TextViewDrawableAction(int viewId, boolean isRelative, int d1, int d2, int d3, int d4) {
1262820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.viewId = viewId;
1263820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.isRelative = isRelative;
1264820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d1 = d1;
1265820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d2 = d2;
1266820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d3 = d3;
1267820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d4 = d4;
1268820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1269820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1270820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public TextViewDrawableAction(Parcel parcel) {
1271820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            viewId = parcel.readInt();
1272820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            isRelative = (parcel.readInt() != 0);
1273820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d1 = parcel.readInt();
1274820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d2 = parcel.readInt();
1275820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d3 = parcel.readInt();
1276820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d4 = parcel.readInt();
1277820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1278820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1279820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public void writeToParcel(Parcel dest, int flags) {
1280820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(TAG);
1281820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(viewId);
1282820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(isRelative ? 1 : 0);
1283820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d1);
1284820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d2);
1285820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d3);
1286820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d4);
1287820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1288820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1289820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        @Override
1290a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
1291820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            final Context context = root.getContext();
1292820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            final TextView target = (TextView) root.findViewById(viewId);
1293820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            if (target == null) return;
1294820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            if (isRelative) {
1295820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler                target.setCompoundDrawablesRelativeWithIntrinsicBounds(d1, d2, d3, d4);
1296820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            } else {
1297820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler                target.setCompoundDrawablesWithIntrinsicBounds(d1, d2, d3, d4);
1298820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            }
1299820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1300820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1301fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1302fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "TextViewDrawableAction";
1303fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1304fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1305820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        boolean isRelative = false;
1306820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        int d1, d2, d3, d4;
1307820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1308820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public final static int TAG = 11;
1309820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1310820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1311820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
131299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * Helper action to set text size on a TextView in any supported units.
13137264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     */
13147264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    private class TextViewSizeAction extends Action {
13157264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public TextViewSizeAction(int viewId, int units, float size) {
13167264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.viewId = viewId;
13177264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.units = units;
13187264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.size = size;
13197264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
13207264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13217264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public TextViewSizeAction(Parcel parcel) {
13227264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            viewId = parcel.readInt();
13237264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            units = parcel.readInt();
13247264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            size  = parcel.readFloat();
13257264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
13267264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13277264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public void writeToParcel(Parcel dest, int flags) {
13287264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(TAG);
13297264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(viewId);
13307264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(units);
13317264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeFloat(size);
13327264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
13337264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13347264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        @Override
1335a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
13367264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            final Context context = root.getContext();
13377264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            final TextView target = (TextView) root.findViewById(viewId);
13387264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            if (target == null) return;
13397264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            target.setTextSize(units, size);
13407264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
13417264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
1342fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1343fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "TextViewSizeAction";
1344fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1345fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
13467264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        int units;
13477264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        float size;
13487264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13497264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public final static int TAG = 13;
13507264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    }
13517264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13527264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    /**
135399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * Helper action to set padding on a View.
135499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     */
135599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    private class ViewPaddingAction extends Action {
135699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public ViewPaddingAction(int viewId, int left, int top, int right, int bottom) {
135799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.viewId = viewId;
135899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.left = left;
135999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.top = top;
136099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.right = right;
136199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.bottom = bottom;
136299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
136399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
136499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public ViewPaddingAction(Parcel parcel) {
136599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            viewId = parcel.readInt();
136699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            left = parcel.readInt();
136799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            top = parcel.readInt();
136899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            right = parcel.readInt();
136999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            bottom = parcel.readInt();
137099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
137199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
137299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public void writeToParcel(Parcel dest, int flags) {
137399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(TAG);
137499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(viewId);
137599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(left);
137699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(top);
137799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(right);
137899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(bottom);
137999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
138099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
138199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        @Override
1382a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
138399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            final Context context = root.getContext();
138499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            final View target = root.findViewById(viewId);
138599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            if (target == null) return;
138699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            target.setPadding(left, top, right, bottom);
138799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
138899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
1389fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1390fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ViewPaddingAction";
1391fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1392fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
139399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        int left, top, right, bottom;
139499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
139599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public final static int TAG = 14;
139699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    }
139799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
139899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    /**
13993ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Simple class used to keep track of memory usage in a RemoteViews.
14003ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     *
14013ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
14023ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    private class MemoryUsageCounter {
14033ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        public void clear() {
14045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsage = 0;
14053ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
14063ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void increment(int numBytes) {
14085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsage += numBytes;
14093ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
14103ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public int getMemoryUsage() {
14125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            return mMemoryUsage;
14133ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
14143ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void addBitmapMemory(Bitmap b) {
14165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            final Bitmap.Config c = b.getConfig();
14175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // If we don't know, be pessimistic and assume 4
14185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int bpp = 4;
14195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (c != null) {
14205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                switch (c) {
14215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ALPHA_8:
14225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 1;
14235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
14245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case RGB_565:
14255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ARGB_4444:
14265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 2;
14275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
14285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ARGB_8888:
14295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 4;
14305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
14315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
14325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
14335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            increment(b.getWidth() * b.getHeight() * bpp);
14345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
14355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int mMemoryUsage;
14373ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
14383ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14393ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new RemoteViews object that will display the views contained
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the specified layout file.
1442e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param packageName Name of the package that contains the layout resource
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layoutId The id of the layout resource
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RemoteViews(String packageName, int layoutId) {
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPackage = packageName;
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayoutId = layoutId;
14495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = new BitmapCache();
14503ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14513ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // setup the memory usage statistics
14523ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter = new MemoryUsageCounter();
14533ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        recalculateMemoryUsage();
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14566d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    /** {@hide} */
14576d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    public void setUser(UserHandle user) {
14586d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey        mUser = user;
14596d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    }
14606d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey
14615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private boolean hasLandscapeAndPortraitLayouts() {
14625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return (mLandscape != null) && (mPortrait != null);
14635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
14645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14656d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey    /**
14665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Create a new RemoteViews object that will inflate as the specified
14675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * landspace or portrait RemoteViews, depending on the current configuration.
14685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     *
14695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @param landscape The RemoteViews to inflate in landscape configuration
14705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @param portrait The RemoteViews to inflate in portrait configuration
14715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
14725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    public RemoteViews(RemoteViews landscape, RemoteViews portrait) {
14735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (landscape == null || portrait == null) {
14745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("Both RemoteViews must be non-null");
14755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
14765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (landscape.getPackage().compareTo(portrait.getPackage()) != 0) {
14775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("Both RemoteViews must share the same package");
14785d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
14795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mPackage = portrait.getPackage();
14805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mLayoutId = portrait.getLayoutId();
14815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mLandscape = landscape;
14835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mPortrait = portrait;
14845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14855d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // setup the memory usage statistics
14865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mMemoryUsageCounter = new MemoryUsageCounter();
14875d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = new BitmapCache();
14895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        configureRemoteViewsAsChild(landscape);
14905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        configureRemoteViewsAsChild(portrait);
14915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        recalculateMemoryUsage();
14935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
14945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Reads a RemoteViews object from a parcel.
1497e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parcel
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RemoteViews(Parcel parcel) {
15015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        this(parcel, null);
15025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
1503ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
15045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews(Parcel parcel, BitmapCache bitmapCache) {
15055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int mode = parcel.readInt();
15065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // We only store a bitmap cache in the root of the RemoteViews.
15085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (bitmapCache == null) {
15095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmapCache = new BitmapCache(parcel);
15105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
15115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            setBitmapCache(bitmapCache);
15125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            setNotRoot();
15135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
15145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (mode == MODE_NORMAL) {
15165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPackage = parcel.readString();
15175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLayoutId = parcel.readInt();
15185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mIsWidgetCollectionChild = parcel.readInt() == 1 ? true : false;
15195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = parcel.readInt();
15215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (count > 0) {
15225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mActions = new ArrayList<Action>(count);
15235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i=0; i<count; i++) {
15245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    int tag = parcel.readInt();
15255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    switch (tag) {
15265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetOnClickPendingIntent.TAG:
15275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetOnClickPendingIntent(parcel));
15285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetDrawableParameters.TAG:
15305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetDrawableParameters(parcel));
15315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ReflectionAction.TAG:
15335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ReflectionAction(parcel));
15345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ViewGroupAction.TAG:
15365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ViewGroupAction(parcel, mBitmapCache));
15375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ReflectionActionWithoutParams.TAG:
15395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ReflectionActionWithoutParams(parcel));
15405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetEmptyView.TAG:
15425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetEmptyView(parcel));
15435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetPendingIntentTemplate.TAG:
15455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetPendingIntentTemplate(parcel));
15465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetOnClickFillInIntent.TAG:
15485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetOnClickFillInIntent(parcel));
15495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetRemoteViewsAdapterIntent.TAG:
15515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetRemoteViewsAdapterIntent(parcel));
15525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case TextViewDrawableAction.TAG:
15545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new TextViewDrawableAction(parcel));
15555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15567264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                    case TextViewSizeAction.TAG:
15577264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                        mActions.add(new TextViewSizeAction(parcel));
15587264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                        break;
155999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                    case ViewPaddingAction.TAG:
156099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                        mActions.add(new ViewPaddingAction(parcel));
156199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                        break;
15625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case BitmapReflectionAction.TAG:
15635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new BitmapReflectionAction(parcel));
15645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    default:
15665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        throw new ActionException("Tag " + tag + " not found");
15675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    }
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
15715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // MODE_HAS_LANDSCAPE_AND_PORTRAIT
15725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape = new RemoteViews(parcel, mBitmapCache);
15735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait = new RemoteViews(parcel, mBitmapCache);
15745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPackage = mPortrait.getPackage();
15755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLayoutId = mPortrait.getLayoutId();
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15773ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
15783ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // setup the memory usage statistics
15793ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter = new MemoryUsageCounter();
15803ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        recalculateMemoryUsage();
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15833ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
15843ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen    public RemoteViews clone() {
15853ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        Parcel p = Parcel.obtain();
15863ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        writeToParcel(p, 0);
15873ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        p.setDataPosition(0);
15883ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen        return new RemoteViews(p);
158918e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato    }
159018e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getPackage() {
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mPackage;
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15955d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
15965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Reutrns the layout id of the root layout associated with this RemoteViews. In the case
15975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * that the RemoteViews has both a landscape and portrait root, this will return the layout
15985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * id associated with the portrait layout.
15995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     *
16005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @return the layout id.
16015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getLayoutId() {
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayoutId;
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16063ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /*
1607ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * This flag indicates whether this RemoteViews object is being created from a
1608ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * RemoteViewsService for use as a child of a widget collection. This flag is used
1609ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * to determine whether or not certain features are available, in particular,
1610ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * setting on click extras and setting on click pending intents. The former is enabled,
1611ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * and the latter disabled when this flag is true.
1612ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     */
1613ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    void setIsWidgetCollectionChild(boolean isWidgetCollectionChild) {
1614ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        mIsWidgetCollectionChild = isWidgetCollectionChild;
1615ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    }
1616ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
1617ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    /**
16183ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Updates the memory usage statistics.
16193ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
16203ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    private void recalculateMemoryUsage() {
16213ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter.clear();
16223ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
16245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // Accumulate the memory usage for each action
16255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
16265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                final int count = mActions.size();
16275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i= 0; i < count; ++i) {
16285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mActions.get(i).updateMemoryUsageEstimate(mMemoryUsageCounter);
16295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
16305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
16315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
16325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.addBitmapMemory(mMemoryUsageCounter);
16333ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
16345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
16355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsageCounter.increment(mLandscape.estimateMemoryUsage());
16365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsageCounter.increment(mPortrait.estimateMemoryUsage());
16375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmapCache.addBitmapMemory(mMemoryUsageCounter);
16385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
16395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
16405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
16415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
16425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Recursively sets BitmapCache in the hierarchy and update the bitmap ids.
16435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
16445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private void setBitmapCache(BitmapCache bitmapCache) {
16455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = bitmapCache;
16465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
16475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
16485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                final int count = mActions.size();
16495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i= 0; i < count; ++i) {
16505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mActions.get(i).setBitmapCache(bitmapCache);
16515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
16525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
16535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
16545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape.setBitmapCache(bitmapCache);
16555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait.setBitmapCache(bitmapCache);
16563ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
16573ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
16583ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16593ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
16603ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Returns an estimate of the bitmap heap memory usage for this RemoteViews.
16613ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
1662311c79c3e93589c6fc720fe6c58ed522af591376Adam Cohen    /** @hide */
1663311c79c3e93589c6fc720fe6c58ed522af591376Adam Cohen    public int estimateMemoryUsage() {
16645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return mMemoryUsageCounter.getMemoryUsage();
16653ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
16663ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16673ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Add an action to be executed on the remote side when apply is called.
1669e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param a The action to add
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addAction(Action a) {
16735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
16745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("RemoteViews specifying separate landscape and portrait" +
16755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    " layouts cannot be modified. Instead, fully configure the landscape and" +
16765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    " portrait layouts individually before constructing the combined layout.");
16775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mActions == null) {
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mActions = new ArrayList<Action>();
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mActions.add(a);
16823ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16833ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // update the memory usage stats
16843ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        a.updateMemoryUsageEstimate(mMemoryUsageCounter);
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16861162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
16871162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
16881162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
16891162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * given {@link RemoteViews}. This allows users to build "nested"
16901162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * {@link RemoteViews}. In cases where consumers of {@link RemoteViews} may
16911162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * recycle layouts, use {@link #removeAllViews(int)} to clear any existing
16921162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * children.
16931162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *
16941162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param viewId The id of the parent {@link ViewGroup} to add child into.
16951162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param nestedView {@link RemoteViews} that describes the child.
16961162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
16971162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    public void addView(int viewId, RemoteViews nestedView) {
16981162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        addAction(new ViewGroupAction(viewId, nestedView));
16991162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
17001162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
17011162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
17021162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#removeAllViews()}.
17031162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *
17041162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param viewId The id of the parent {@link ViewGroup} to remove all
17051162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *            children from.
17061162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
17071162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    public void removeAllViews(int viewId) {
17081162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        addAction(new ViewGroupAction(viewId, null));
17091162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
17101162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17120b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#showNext()}
17132dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     *
17140b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call {@link AdapterViewAnimator#showNext()}
17152dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     */
17162dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    public void showNext(int viewId) {
17172dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        addAction(new ReflectionActionWithoutParams(viewId, "showNext"));
17182dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
17192dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
17202dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    /**
17210b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#showPrevious()}
17222dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     *
17230b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call {@link AdapterViewAnimator#showPrevious()}
17242dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     */
17252dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    public void showPrevious(int viewId) {
17262dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        addAction(new ReflectionActionWithoutParams(viewId, "showPrevious"));
17272dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
17282dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
17292dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    /**
17300b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#setDisplayedChild(int)}
17310b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     *
17320b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call
17330b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     *               {@link AdapterViewAnimator#setDisplayedChild(int)}
17340b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     */
17350b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    public void setDisplayedChild(int viewId, int childIndex) {
17360b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen        setInt(viewId, "setDisplayedChild", childIndex);
17370b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    }
17380b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen
17390b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    /**
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling View.setVisibility
1741e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose visibility should change
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param visibility The new visibility for the view
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setViewVisibility(int viewId, int visibility) {
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setVisibility", visibility);
17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1748ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling TextView.setText
1751e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose text should change
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text The new text for the view
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTextViewText(int viewId, CharSequence text) {
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setCharSequence(viewId, "setText", text);
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17587264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
17597264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    /**
17607264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * Equivalent to calling {@link TextView#setTextSize(int, float)}
1761e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
17627264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param viewId The id of the view whose text size should change
17637264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param units The units of size (e.g. COMPLEX_UNIT_SP)
17647264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param size The size of the text
17657264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     */
17667264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    public void setTextViewTextSize(int viewId, int units, float size) {
17677264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        addAction(new TextViewSizeAction(viewId, units, size));
17687264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    }
17697264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1771e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * Equivalent to calling
1772820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * {@link TextView#setCompoundDrawablesWithIntrinsicBounds(int, int, int, int)}.
1773820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     *
1774820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param viewId The id of the view whose text should change
1775820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param left The id of a drawable to place to the left of the text, or 0
1776820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param top The id of a drawable to place above the text, or 0
1777820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param right The id of a drawable to place to the right of the text, or 0
1778e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param bottom The id of a drawable to place below the text, or 0
1779820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1780820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    public void setTextViewCompoundDrawables(int viewId, int left, int top, int right, int bottom) {
1781820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        addAction(new TextViewDrawableAction(viewId, false, left, top, right, bottom));
1782820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1783820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1784820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
1785e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * Equivalent to calling {@link
1786820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)}.
1787820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     *
1788820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param viewId The id of the view whose text should change
1789e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param start The id of a drawable to place before the text (relative to the
1790820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * layout direction), or 0
1791820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param top The id of a drawable to place above the text, or 0
1792820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param end The id of a drawable to place after the text, or 0
179366388dcb09018933ccd1d38eae563f0890ba4f06Fabrice Di Meglio     * @param bottom The id of a drawable to place below the text, or 0
1794820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1795820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    public void setTextViewCompoundDrawablesRelative(int viewId, int start, int top, int end, int bottom) {
1796820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        addAction(new TextViewDrawableAction(viewId, true, start, top, end, bottom));
1797820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1798820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1799820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageResource
1801e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose drawable should change
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param srcId The new resource id for the drawable
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1805e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller    public void setImageViewResource(int viewId, int srcId) {
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setImageResource", srcId);
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageURI
1811e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose drawable should change
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The Uri for the image
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setImageViewUri(int viewId, Uri uri) {
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setUri(viewId, "setImageURI", uri);
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageBitmap
1821e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
182293dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view whose bitmap should change
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap The new Bitmap for the drawable
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setImageViewBitmap(int viewId, Bitmap bitmap) {
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBitmap(viewId, "setImageBitmap", bitmap);
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18301480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * Equivalent to calling AdapterView.setEmptyView
18311480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     *
18321480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * @param viewId The id of the view on which to set the empty view
18331480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * @param emptyViewId The view id of the empty view
18341480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     */
18351480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    public void setEmptyView(int viewId, int emptyViewId) {
18361480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        addAction(new SetEmptyView(viewId, emptyViewId));
18371480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    }
18381480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
18391480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    /**
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link Chronometer#setBase Chronometer.setBase},
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Chronometer#setFormat Chronometer.setFormat},
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link Chronometer#start Chronometer.start()} or
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Chronometer#stop Chronometer.stop()}.
1844e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
184593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link Chronometer} to change
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param base The time at which the timer would have read 0:00.  This
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             time should be based off of
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}.
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param format The Chronometer format string, or null to
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               simply display the timer value.
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param started True if you want the clock to be started, false if not.
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setChronometer(int viewId, long base, String format, boolean started) {
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setLong(viewId, "setBase", base);
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setString(viewId, "setFormat", format);
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBoolean(viewId, "setStarted", started);
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1858e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link ProgressBar#setMax ProgressBar.setMax},
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ProgressBar#setProgress ProgressBar.setProgress}, and
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ProgressBar#setIndeterminate ProgressBar.setIndeterminate}
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If indeterminate is true, then the values for max and progress are ignored.
1865e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
186693dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link ProgressBar} to change
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param max The 100% value for the progress bar
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param progress The current value of the progress bar.
1869e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param indeterminate True if the progress bar is indeterminate,
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                false if not.
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1872e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller    public void setProgressBar(int viewId, int max, int progress,
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean indeterminate) {
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBoolean(viewId, "setIndeterminate", indeterminate);
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!indeterminate) {
18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setInt(viewId, "setMax", max);
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setInt(viewId, "setProgress", progress);
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1880e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to launch the provided {@link PendingIntent}.
1885e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
188635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When setting the on-click action of items within collections (eg. {@link ListView},
188735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * {@link StackView} etc.), this method will not work. Instead, use {@link
188835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setPendingIntentTemplate(int, PendingIntent) in conjunction with
188935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setOnClickFillInIntent(int, Intent).
189035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view that will trigger the {@link PendingIntent} when clicked
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pendingIntent The {@link PendingIntent} to send when user clicks
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) {
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new SetOnClickPendingIntent(viewId, pendingIntent));
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
189935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very
190035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * costly to set PendingIntents on the individual items, and is hence not permitted. Instead
190135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * this method should be used to set a single PendingIntent template on the collection, and
190235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * individual items can differentiate their on-click behavior using
190335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * {@link RemoteViews#setOnClickFillInIntent(int, Intent)}.
1904ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *
1905ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * @param viewId The id of the collection who's children will use this PendingIntent template
1906ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *          when clicked
1907ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * @param pendingIntentTemplate The {@link PendingIntent} to be combined with extras specified
1908ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *          by a child of viewId and executed when that child is clicked
1909ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     */
1910ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    public void setPendingIntentTemplate(int viewId, PendingIntent pendingIntentTemplate) {
1911ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        addAction(new SetPendingIntentTemplate(viewId, pendingIntentTemplate));
1912ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    }
1913ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
1914ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    /**
191535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very
191635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * costly to set PendingIntents on the individual items, and is hence not permitted. Instead
191735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * a single PendingIntent template can be set on the collection, see {@link
191835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setPendingIntentTemplate(int, PendingIntent)}, and the individual on-click
191935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * action of a given item can be distinguished by setting a fillInIntent on that item. The
192035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * fillInIntent is then combined with the PendingIntent template in order to determine the final
192135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * intent which will be executed when the item is clicked. This works as follows: any fields
192235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * which are left blank in the PendingIntent template, but are provided by the fillInIntent
192335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * will be overwritten, and the resulting PendingIntent will be used.
192435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
192535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
192635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * of the PendingIntent template will then be filled in with the associated fields that are
192735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * set in fillInIntent. See {@link Intent#fillIn(Intent, int)} for more details.
192835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
192935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * @param viewId The id of the view on which to set the fillInIntent
193035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * @param fillInIntent The intent which will be combined with the parent's PendingIntent
193135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *        in order to determine the on-click behavior of the view specified by viewId
193235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     */
193335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    public void setOnClickFillInIntent(int viewId, Intent fillInIntent) {
193435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        addAction(new SetOnClickFillInIntent(viewId, fillInIntent));
193535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    }
193635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
193735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    /**
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * view.
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * You can omit specific calls by marking their values with null or -1.
1945e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view that contains the target
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link Drawable}
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param targetBackground If true, apply these parameters to the
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link Drawable} returned by
19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link android.view.View#getBackground()}. Otherwise, assume
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the target view is an {@link ImageView} and apply them to
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link ImageView#getDrawable()}.
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param alpha Specify an alpha value for the drawable, or -1 to leave
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colorFilter Specify a color for a
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link android.graphics.ColorFilter} for this drawable, or -1
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            to leave unchanged.
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Specify a PorterDuff mode for this drawable, or null to leave
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param level Specify the level for the drawable, or -1 to leave
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDrawableParameters(int viewId, boolean targetBackground, int alpha,
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int colorFilter, PorterDuff.Mode mode, int level) {
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new SetDrawableParameters(viewId, targetBackground, alpha,
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                colorFilter, mode, level));
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link android.widget.TextView#setTextColor(int)}.
1971e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
197293dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view whose text color should change
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param color Sets the text color for all the states (normal, selected,
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            focused) to be this color.
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTextColor(int viewId, int color) {
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setTextColor", color);
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1980592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
1981499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
1982499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
1983037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @param appWidgetId The id of the app widget which contains the specified view. (This
1984037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *      parameter is ignored in this deprecated method)
198593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link AbsListView}
198681f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     * @param intent The intent of the service which will be
198781f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     *            providing data to the RemoteViewsAdapter
1988037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @deprecated This method has been deprecated. See
1989037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *      {@link android.widget.RemoteViews#setRemoteAdapter(int, Intent)}
199081f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     */
1991037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    @Deprecated
199281f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung    public void setRemoteAdapter(int appWidgetId, int viewId, Intent intent) {
1993037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        setRemoteAdapter(viewId, intent);
1994037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    }
1995037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
1996037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    /**
1997037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
1998037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * Can only be used for App Widgets.
1999037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *
200093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link AbsListView}
2001037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @param intent The intent of the service which will be
2002037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *            providing data to the RemoteViewsAdapter
2003037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     */
2004037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    public void setRemoteAdapter(int viewId, Intent intent) {
2005037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        addAction(new SetRemoteViewsAdapterIntent(viewId, intent));
2006499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2007499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2008499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
2009499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
2010499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
201193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view to change
2012499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * @param position Scroll to this adapter position
2013499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2014499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setScrollPosition(int viewId, int position) {
2015499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        setInt(viewId, "smoothScrollToPosition", position);
2016499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2017499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2018499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
2019499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
2020499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
202193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view to change
202295362595ed4a42aec87b4d166092b30c8139d220Winson Chung     * @param offset Scroll by this adapter position offset
2023499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2024499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setRelativeScrollPosition(int viewId, int offset) {
2025499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        setInt(viewId, "smoothScrollByOffset", offset);
2026499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2027499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2028499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
2029d5353b475001f19e3cbc9c1a4165c9e6038a812fDaniel Sandler     * Equivalent to calling {@link android.view.View#setPadding(int, int, int, int)}.
203099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     *
203199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param viewId The id of the view to change
203299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param left the left padding in pixels
203399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param top the top padding in pixels
203499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param right the right padding in pixels
203599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param bottom the bottom padding in pixels
203699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     */
203799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    public void setViewPadding(int viewId, int left, int top, int right, int bottom) {
203899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        addAction(new ViewPaddingAction(viewId, left, top, right, bottom));
203999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    }
204099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
204199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    /**
2042592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one boolean on a view in the layout for this RemoteViews.
2043592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
204493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2045592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2046592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2047592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBoolean(int viewId, String methodName, boolean value) {
20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BOOLEAN, value));
20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2052592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2053592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one byte on a view in the layout for this RemoteViews.
2054592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
205593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2056592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2057592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2058592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setByte(int viewId, String methodName, byte value) {
20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BYTE, value));
20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2063592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2064592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one short on a view in the layout for this RemoteViews.
2065592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
206693dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2067592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2068592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2069592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setShort(int viewId, String methodName, short value) {
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.SHORT, value));
20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2074592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2075592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one int on a view in the layout for this RemoteViews.
2076592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
207793dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2078592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2079592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2080592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInt(int viewId, String methodName, int value) {
20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INT, value));
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2085592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2086592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one long on a view in the layout for this RemoteViews.
2087592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
208893dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2089592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2090592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2091592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLong(int viewId, String methodName, long value) {
20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.LONG, value));
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2096592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2097592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one float on a view in the layout for this RemoteViews.
2098592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
209993dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2100592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2101592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2102592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFloat(int viewId, String methodName, float value) {
21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.FLOAT, value));
21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2107592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2108592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one double on a view in the layout for this RemoteViews.
2109592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
211093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2111592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2112592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2113592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDouble(int viewId, String methodName, double value) {
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.DOUBLE, value));
21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2118592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2119592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one char on a view in the layout for this RemoteViews.
2120592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
212193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2122592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2123592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2124592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setChar(int viewId, String methodName, char value) {
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR, value));
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2130592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one String on a view in the layout for this RemoteViews.
2131592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
213293dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2133592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2134592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2135592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setString(int viewId, String methodName, String value) {
21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.STRING, value));
21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2140592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2141592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one CharSequence on a view in the layout for this RemoteViews.
2142592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
214393dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2144592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2145592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2146592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCharSequence(int viewId, String methodName, CharSequence value) {
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE, value));
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2151592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2152592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one Uri 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 setUri(int viewId, String methodName, Uri value) {
215965c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey        // Resolve any filesystem path before sending remotely
216065c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey        value = value.getCanonicalUri();
21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.URI, value));
21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2164592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2165592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one Bitmap on a view in the layout for this RemoteViews.
2166592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @more
2167592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * <p class="note">The bitmap will be flattened into the parcel if this object is
2168592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * sent across processes, so it may end up using a lot of memory, and may be fairly slow.</p>
2169592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
217093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2171592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2172592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2173592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBitmap(int viewId, String methodName, Bitmap value) {
21755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        addAction(new BitmapReflectionAction(viewId, methodName, value));
21769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2179d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * Call a method taking one Bundle on a view in the layout for this RemoteViews.
2180d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     *
218193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2182d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * @param methodName The name of the method to call.
2183d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * @param value The value to pass to the method.
2184d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     */
2185d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    public void setBundle(int viewId, String methodName, Bundle value) {
2186d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BUNDLE, value));
2187d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    }
2188d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert
2189d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    /**
219093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * Call a method taking one Intent on a view in the layout for this RemoteViews.
2191499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
219293dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
219393dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param methodName The name of the method to call.
219493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param value The {@link android.content.Intent} to pass the method.
2195499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2196499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setIntent(int viewId, String methodName, Intent value) {
2197499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INTENT, value));
2198499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2199499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2200499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
220133aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * Equivalent to calling View.setContentDescription(CharSequence).
2202e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov     *
220333aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param viewId The id of the view whose content description should change.
220433aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param contentDescription The new content description for the view.
2205e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov     */
2206e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    public void setContentDescription(int viewId, CharSequence contentDescription) {
2207e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov        setCharSequence(viewId, "setContentDescription", contentDescription);
2208e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    }
2209e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov
221033aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    /**
221133aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * Equivalent to calling View.setLabelFor(int).
221233aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     *
221333aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param viewId The id of the view whose property to set.
221433aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param labeledId The id of a view for which this view serves as a label.
221533aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     */
221633aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    public void setLabelFor(int viewId, int labeledId) {
221733aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov        setInt(viewId, "setLabelFor", labeledId);
221833aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    }
221933aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov
22205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews getRemoteViewsToApply(Context context) {
22215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
22225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int orientation = context.getResources().getConfiguration().orientation;
22235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
22245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mLandscape;
22255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
22265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mPortrait;
22275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
22285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
22295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return this;
22305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
22315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
2232e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    /**
22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Inflates the view hierarchy represented by this object and applies
22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * all of the actions.
2235e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><strong>Caller beware: this may throw</strong>
2237e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Default context to use
22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent Parent that the resulting view hierarchy will be attached to. This method
22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * does <strong>not</strong> attach the hierarchy. The caller should do so when appropriate.
22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The inflated view hierarchy
22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View apply(Context context, ViewGroup parent) {
2244e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller        return apply(context, parent, null);
22451927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    }
22461927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
2247a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    /** @hide */
2248a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    public View apply(Context context, ViewGroup parent, OnClickHandler handler) {
22495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        RemoteViews rvToApply = getRemoteViewsToApply(context);
22505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
2251a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        View result;
22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Context c = prepareContext(context);
22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2255a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        LayoutInflater inflater = (LayoutInflater)
2256a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inflater = inflater.cloneInContext(c);
22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inflater.setFilter(this);
22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        result = inflater.inflate(rvToApply.getLayoutId(), parent, false);
22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2263a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        rvToApply.performApply(result, parent, handler);
22649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
22699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Applies all of the actions to the provided view.
22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><strong>Caller beware: this may throw</strong>
2272e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
22739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param v The view to apply the actions to.  This should be the result of
22749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #apply(Context,ViewGroup)} call.
22759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void reapply(Context context, View v) {
2277e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller        reapply(context, v, null);
2278a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    }
2279a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn
2280a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    /** @hide */
2281a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    public void reapply(Context context, View v, OnClickHandler handler) {
22825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        RemoteViews rvToApply = getRemoteViewsToApply(context);
22835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
22845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // In the case that a view has this RemoteViews applied in one orientation, is persisted
22855d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // across orientation change, and has the RemoteViews re-applied in the new orientation,
22865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // we throw an exception, since the layouts may be completely unrelated.
22875d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
22885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (v.getId() != rvToApply.getLayoutId()) {
22895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" +
22905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        " that does not share the same root layout id.");
22915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
22925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
22935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        prepareContext(context);
2295a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        rvToApply.performApply(v, (ViewGroup) v.getParent(), handler);
22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2298a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    private void performApply(View v, ViewGroup parent, OnClickHandler handler) {
22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mActions != null) {
2300e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller            handler = handler == null ? DEFAULT_ON_CLICK_HANDLER : handler;
23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mActions.size();
23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Action a = mActions.get(i);
2304a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                a.apply(v, parent, handler);
23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context prepareContext(Context context) {
2310a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        Context c;
23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String packageName = mPackage;
23129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (packageName != null) {
23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
23156d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey                c = context.createPackageContextAsUser(
23166d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey                        packageName, Context.CONTEXT_RESTRICTED, mUser);
23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (NameNotFoundException e) {
23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.e(LOG_TAG, "Package name " + packageName + " not found");
23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c = context;
23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c = context;
23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;
23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* (non-Javadoc)
23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used to restrict the views which can be inflated
2330e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.view.LayoutInflater.Filter#onLoadClass(java.lang.Class)
23329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2333e6ac8b9aade9443ab8456c8f7a47cdfba3b70266Gilles Debunne    public boolean onLoadClass(Class clazz) {
23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return clazz.isAnnotationPresent(RemoteView.class);
23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int describeContents() {
23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToParcel(Parcel dest, int flags) {
23425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
23435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(MODE_NORMAL);
23445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // We only write the bitmap cache if we are the root RemoteViews, as this cache
23455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // is shared by all children.
23465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
23475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.writeBitmapsToParcel(dest, flags);
23485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeString(mPackage);
23505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(mLayoutId);
23515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
23525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count;
23535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
23545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                count = mActions.size();
23555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
23565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                count = 0;
23575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(count);
23595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i=0; i<count; i++) {
23605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Action a = mActions.get(i);
23615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                a.writeToParcel(dest, 0);
23625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
23645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(MODE_HAS_LANDSCAPE_AND_PORTRAIT);
23655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // We only write the bitmap cache if we are the root RemoteViews, as this cache
23665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // is shared by all children.
23675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
23685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.writeBitmapsToParcel(dest, flags);
23695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape.writeToParcel(dest, flags);
23715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait.writeToParcel(dest, flags);
23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parcelable.Creator that instantiates RemoteViews objects
23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final Parcelable.Creator<RemoteViews> CREATOR = new Parcelable.Creator<RemoteViews>() {
23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public RemoteViews createFromParcel(Parcel parcel) {
23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new RemoteViews(parcel);
23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public RemoteViews[] newArray(int size) {
23849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new RemoteViews[size];
23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2388