RemoteViews.java revision bd1e0076c66084da702a789db90e77c6ca645fe2
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;
26ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohenimport android.content.pm.PackageManager;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException;
285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohenimport android.content.res.Configuration;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PorterDuff;
317597065d6b0877ffc460b443fdb1595965ccd7b2Joe Onoratoimport android.graphics.Rect;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
34ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohenimport android.os.Build;
35d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringertimport android.os.Bundle;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
407264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandlerimport android.util.TypedValue;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
42dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport android.view.LayoutInflater.Filter;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.RemotableViewMethod;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View.OnClickListener;
46dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport android.view.ViewGroup;
47a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohenimport android.widget.AdapterView.OnItemClickListener;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
49dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.ElementType;
50dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.Retention;
51dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.RetentionPolicy;
52dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.annotation.Target;
53dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.lang.reflect.Method;
54dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chungimport java.util.ArrayList;
55fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohenimport java.util.HashMap;
56dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A class that describes a view hierarchy that can be displayed in
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * another process. The hierarchy is inflated from a layout resource
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file, and this class provides some basic operations for modifying
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the content of the inflated hierarchy.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RemoteViews implements Parcelable, Filter {
65e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String LOG_TAG = "RemoteViews";
67e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6981f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     * The intent extra that contains the appWidgetId.
7081f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     * @hide
7181f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     */
7281f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung    static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId";
7381f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung
7481f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung    /**
75e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * The package name of the package containing the layout
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * resource. (Added to the parcel)
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
783030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne    private final String mPackage;
79e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The resource ID of the layout file. (Added to the parcel)
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
833030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne    private final int mLayoutId;
84a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * An array of actions to perform on the view tree once it has been
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inflated
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ArrayList<Action> mActions;
90e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
913ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
923ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * A class to keep track of memory usage by this RemoteViews
933ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
943ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    private MemoryUsageCounter mMemoryUsageCounter;
953ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Maps bitmaps to unique indicies to avoid Bitmap duplication.
985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private BitmapCache mBitmapCache;
1005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
1015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
1025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Indicates whether or not this RemoteViews object is contained as a child of any other
1035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * RemoteViews.
1045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
1055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private boolean mIsRoot = true;
1065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
1075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
1085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Constants to whether or not this RemoteViews is composed of a landscape and portrait
1095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * RemoteViews.
1105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
1115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private static final int MODE_NORMAL = 0;
1125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private static final int MODE_HAS_LANDSCAPE_AND_PORTRAIT = 1;
1135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
1145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
1155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Used in conjunction with the special constructor
1165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * {@link #RemoteViews(RemoteViews, RemoteViews)} to keep track of the landscape and portrait
1175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * RemoteViews.
1185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
1195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews mLandscape = null;
1205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews mPortrait = null;
1215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
123ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * This flag indicates whether this RemoteViews object is being created from a
124ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * RemoteViewsService for use as a child of a widget collection. This flag is used
125ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * to determine whether or not certain features are available, in particular,
126ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * setting on click extras and setting on click pending intents. The former is enabled,
127ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * and the latter disabled when this flag is true.
128ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     */
1291927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    private boolean mIsWidgetCollectionChild = false;
1301927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
1311927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = new OnClickHandler();
132ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
133ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    /**
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This annotation indicates that a subclass of View is alllowed to be used
135a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy     * with the {@link RemoteViews} mechanism.
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Target({ ElementType.TYPE })
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Retention(RetentionPolicy.RUNTIME)
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public @interface RemoteView {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Exception to send when something goes wrong executing an action
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class ActionException extends RuntimeException {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ActionException(Exception ex) {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(ex);
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ActionException(String message) {
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(message);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
154a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
1551927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    /** @hide */
1561927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    public static class OnClickHandler {
1571927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        public boolean onClickHandler(View view, PendingIntent pendingIntent,
158ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                Intent fillInIntent) {
159ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            try {
160ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
161dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                Context context = view.getContext();
162dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
163dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                        0, 0,
164dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                        view.getMeasuredWidth(), view.getMeasuredHeight());
165ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                context.startIntentSender(
166ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                        pendingIntent.getIntentSender(), fillInIntent,
167ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                        Intent.FLAG_ACTIVITY_NEW_TASK,
168dc6f79bf4374f2fcea2b9d4d0aa7f2e39cc42456Winson Chung                        Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
169ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            } catch (IntentSender.SendIntentException e) {
170ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                android.util.Log.e(LOG_TAG, "Cannot send pending intent: ", e);
171ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                return false;
172ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            } catch (Exception e) {
173ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                android.util.Log.e(LOG_TAG, "Cannot send pending intent due to " +
174ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                        "unknown exception: ", e);
175ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung                return false;
176ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            }
177ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung            return true;
178ae615981315d9318edb1d8bf2a0f607f90cc77acWinson Chung        }
1791927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    }
1801927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
1811927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    /**
1821927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     * Base class for all actions that can be performed on an
1831927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     * inflated view.
1841927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     *
1851927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     *  SUBCLASSES MUST BE IMMUTABLE SO CLONE WORKS!!!!!
1861927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn     */
1871927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    private abstract static class Action implements Parcelable {
188a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public abstract void apply(View root, ViewGroup rootParent,
189a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                OnClickHandler handler) throws ActionException;
1901927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
191fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public static final int MERGE_REPLACE = 0;
192fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public static final int MERGE_APPEND = 1;
193fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public static final int MERGE_IGNORE = 2;
194fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1951927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        public int describeContents() {
1961927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn            return 0;
1971927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        }
1981927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
1991927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        /**
2001927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn         * Overridden by each class to report on it's own memory usage
2011927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn         */
2021927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
2031927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn            // We currently only calculate Bitmap memory usage, so by default, don't do anything
2041927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn            // here
2051927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn            return;
2061927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn        }
2075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
2085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void setBitmapCache(BitmapCache bitmapCache) {
2095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // Do nothing
2105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
211fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
212fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
213fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return MERGE_REPLACE;
214fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
215fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
216fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public abstract String getActionName();
217fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
218fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getUniqueKey() {
219fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return (getActionName() + viewId);
220fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
221fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
222fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        int viewId;
223fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen    }
224fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
225bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen    /**
226bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     * Merges the passed RemoteViews actions with this RemoteViews actions according to
227bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     * action-specific merge rules.
228bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     *
229bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     * @param newRv
230bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     *
231bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     * @hide
232bd1e0076c66084da702a789db90e77c6ca645fe2Adam Cohen     */
233fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen    public void mergeRemoteViews(RemoteViews newRv) {
234fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // We first copy the new RemoteViews, as the process of merging modifies the way the actions
235fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // reference the bitmap cache. We don't want to modify the object as it may need to
236fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // be merged and applied multiple times.
237fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        Parcel p = Parcel.obtain();
238fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        newRv.writeToParcel(p, 0);
239fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        RemoteViews copy = new RemoteViews(p);
240fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
241fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        HashMap<String, Action> map = new HashMap<String, Action>();
242fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        if (mActions == null) {
243fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            mActions = new ArrayList<Action>();
244fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
245fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
246fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        int count = mActions.size();
247fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        for (int i = 0; i < count; i++) {
248fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            Action a = mActions.get(i);
249fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            map.put(a.getUniqueKey(), a);
250fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
251fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
252fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        ArrayList<Action> newActions = copy.mActions;
253fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        if (newActions == null) return;
254fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        count = newActions.size();
255fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        for (int i = 0; i < count; i++) {
256fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            Action a = newActions.get(i);
257fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            String key = newActions.get(i).getUniqueKey();
258fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            int mergeBehavior = map.get(key).mergeBehavior();
259fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (map.containsKey(key) && mergeBehavior == Action.MERGE_REPLACE) {
260fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                mActions.remove(map.get(key));
261fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                map.remove(key);
262fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            }
263fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
264fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // If the merge behavior is ignore, we don't bother keeping the extra action
265fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (mergeBehavior == Action.MERGE_REPLACE || mergeBehavior == Action.MERGE_APPEND) {
266fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                mActions.add(a);
267fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            }
268fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
269fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
270fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // Because pruning can remove the need for bitmaps, we reconstruct the bitmap cache
271fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        mBitmapCache = new BitmapCache();
272fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        setBitmapCache(mBitmapCache);
273a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2751480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    private class SetEmptyView extends Action {
2761480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        int viewId;
2771480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        int emptyViewId;
2781480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2791480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        public final static int TAG = 6;
2801480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2811480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        SetEmptyView(int viewId, int emptyViewId) {
2821480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            this.viewId = viewId;
2831480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            this.emptyViewId = emptyViewId;
2841480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        }
2851480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2861480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        SetEmptyView(Parcel in) {
2871480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            this.viewId = in.readInt();
2881480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            this.emptyViewId = in.readInt();
2891480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        }
2901480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2911480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        public void writeToParcel(Parcel out, int flags) {
2921480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            out.writeInt(TAG);
2931480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            out.writeInt(this.viewId);
2941480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            out.writeInt(this.emptyViewId);
2951480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        }
2961480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
2971480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        @Override
298a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
2991480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            final View view = root.findViewById(viewId);
3001480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            if (!(view instanceof AdapterView<?>)) return;
3011480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
3021480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            AdapterView<?> adapterView = (AdapterView<?>) view;
3031480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
3041480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            final View emptyView = root.findViewById(emptyViewId);
3051480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            if (emptyView == null) return;
3061480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
3071480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen            adapterView.setEmptyView(emptyView);
3081480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        }
309fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
310fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
311fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetEmptyView";
312fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
3131480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    }
3141480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
31535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    private class SetOnClickFillInIntent extends Action {
31635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        public SetOnClickFillInIntent(int id, Intent fillInIntent) {
31735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            this.viewId = id;
31835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            this.fillInIntent = fillInIntent;
31935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        }
32035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
32135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        public SetOnClickFillInIntent(Parcel parcel) {
32235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            viewId = parcel.readInt();
32335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            fillInIntent = Intent.CREATOR.createFromParcel(parcel);
32435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        }
32535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
32635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        public void writeToParcel(Parcel dest, int flags) {
32735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            dest.writeInt(TAG);
32835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            dest.writeInt(viewId);
32935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            fillInIntent.writeToParcel(dest, 0 /* no flags */);
33035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        }
33135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
33235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        @Override
333a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) {
33435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            final View target = root.findViewById(viewId);
3352b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
33635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
33735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            if (!mIsWidgetCollectionChild) {
33835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                Log.e("RemoteViews", "The method setOnClickFillInIntent is available " +
33935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        "only from RemoteViewsFactory (ie. on collection items).");
34035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                return;
34135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            }
342a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen            if (target == root) {
343a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                target.setTagInternal(com.android.internal.R.id.fillInIntent, fillInIntent);
344a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen            } else if (target != null && fillInIntent != null) {
34535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                OnClickListener listener = new OnClickListener() {
34635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                    public void onClick(View v) {
34735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        // Insure that this view is a child of an AdapterView
34835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        View parent = (View) v.getParent();
34935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        while (!(parent instanceof AdapterView<?>)
35035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                                && !(parent instanceof AppWidgetHostView)) {
35135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            parent = (View) parent.getParent();
35235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        }
35335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
35435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        if (parent instanceof AppWidgetHostView) {
35535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            // Somehow they've managed to get this far without having
35635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            // and AdapterView as a parent.
35735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            Log.e("RemoteViews", "Collection item doesn't have AdapterView parent");
35835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            return;
35935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        }
36035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
36135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        // Insure that a template pending intent has been set on an ancestor
36235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        if (!(parent.getTag() instanceof PendingIntent)) {
36335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            Log.e("RemoteViews", "Attempting setOnClickFillInIntent without" +
364a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                    " calling setPendingIntentTemplate on parent.");
36535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                            return;
36635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        }
36735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
36835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        PendingIntent pendingIntent = (PendingIntent) parent.getTag();
36935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
37035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        final float appScale = v.getContext().getResources()
371a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                .getCompatibilityInfo().applicationScale;
37235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        final int[] pos = new int[2];
37335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        v.getLocationOnScreen(pos);
37435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
37535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        final Rect rect = new Rect();
37635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        rect.left = (int) (pos[0] * appScale + 0.5f);
37735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        rect.top = (int) (pos[1] * appScale + 0.5f);
37835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
37935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
38035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
38135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        fillInIntent.setSourceBounds(rect);
382a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                        handler.onClickHandler(v, pendingIntent, fillInIntent);
38335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                    }
38435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
38535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                };
38635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                target.setOnClickListener(listener);
38735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen            }
38835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        }
38935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
390fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
391fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetOnClickFillInIntent";
392fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
393fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
39435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        Intent fillInIntent;
39535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
39635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        public final static int TAG = 9;
39735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    }
39835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
399ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    private class SetPendingIntentTemplate extends Action {
400ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        public SetPendingIntentTemplate(int id, PendingIntent pendingIntentTemplate) {
401ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            this.viewId = id;
402ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            this.pendingIntentTemplate = pendingIntentTemplate;
403ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        }
404ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
405ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        public SetPendingIntentTemplate(Parcel parcel) {
406ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            viewId = parcel.readInt();
407ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            pendingIntentTemplate = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
408ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        }
409ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
410ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        public void writeToParcel(Parcel dest, int flags) {
411ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            dest.writeInt(TAG);
412ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            dest.writeInt(viewId);
413ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            pendingIntentTemplate.writeToParcel(dest, 0 /* no flags */);
414ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        }
415ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
416ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        @Override
417a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) {
418ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            final View target = root.findViewById(viewId);
4192b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
420ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
421ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            // If the view isn't an AdapterView, setting a PendingIntent template doesn't make sense
422ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            if (target instanceof AdapterView<?>) {
423a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                AdapterView<?> av = (AdapterView<?>) target;
424ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen                // The PendingIntent template is stored in the view's tag.
425a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                OnItemClickListener listener = new OnItemClickListener() {
426a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                    public void onItemClick(AdapterView<?> parent, View view,
427a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            int position, long id) {
428a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                        // The view should be a frame layout
429a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                        if (view instanceof ViewGroup) {
430a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            ViewGroup vg = (ViewGroup) view;
431a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
432a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            // AdapterViews contain their children in a frame
433a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            // so we need to go one layer deeper here.
434a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            if (parent instanceof AdapterViewAnimator) {
435a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                vg = (ViewGroup) vg.getChildAt(0);
436a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            }
437a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            if (vg == null) return;
438a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
439a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            Intent fillInIntent = null;
440a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            int childCount = vg.getChildCount();
441a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            for (int i = 0; i < childCount; i++) {
442a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                Object tag = vg.getChildAt(i).getTag(com.android.internal.R.id.fillInIntent);
443a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                if (tag instanceof Intent) {
444a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                    fillInIntent = (Intent) tag;
445a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                    break;
446a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                }
447a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            }
448a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            if (fillInIntent == null) return;
449a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
450a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            final float appScale = view.getContext().getResources()
451a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                                    .getCompatibilityInfo().applicationScale;
452a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            final int[] pos = new int[2];
453a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            view.getLocationOnScreen(pos);
454a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
455a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            final Rect rect = new Rect();
456a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            rect.left = (int) (pos[0] * appScale + 0.5f);
457a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            rect.top = (int) (pos[1] * appScale + 0.5f);
458a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            rect.right = (int) ((pos[0] + view.getWidth()) * appScale + 0.5f);
459a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            rect.bottom = (int) ((pos[1] + view.getHeight()) * appScale + 0.5f);
460a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen
461a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            final Intent intent = new Intent();
462a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                            intent.setSourceBounds(rect);
463a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                            handler.onClickHandler(view, pendingIntentTemplate, fillInIntent);
464a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                        }
465a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                    }
466a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                };
467a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                av.setOnItemClickListener(listener);
468a32edd4b4c894f4fb3d9fd7e9d5b80321df79e20Adam Cohen                av.setTag(pendingIntentTemplate);
469ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            } else {
470ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen                Log.e("RemoteViews", "Cannot setPendingIntentTemplate on a view which is not" +
47135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen                        "an AdapterView (id: " + viewId + ")");
472ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen                return;
473ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            }
474ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        }
475ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
476fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
477fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetPendingIntentTemplate";
478fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
479fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
480ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        PendingIntent pendingIntentTemplate;
481ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
482ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        public final static int TAG = 8;
483ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    }
484ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
485037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    private class SetRemoteViewsAdapterIntent extends Action {
486037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public SetRemoteViewsAdapterIntent(int id, Intent intent) {
487037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            this.viewId = id;
488037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            this.intent = intent;
489037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
490037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
491037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public SetRemoteViewsAdapterIntent(Parcel parcel) {
492037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            viewId = parcel.readInt();
493037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent = Intent.CREATOR.createFromParcel(parcel);
494037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
495037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
496037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public void writeToParcel(Parcel dest, int flags) {
497037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            dest.writeInt(TAG);
498037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            dest.writeInt(viewId);
499037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent.writeToParcel(dest, flags);
500037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
501037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
502037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        @Override
503a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
504037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            final View target = root.findViewById(viewId);
505037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (target == null) return;
506037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
507037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Ensure that we are applying to an AppWidget root
508037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (!(rootParent instanceof AppWidgetHostView)) {
509037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                Log.e("RemoteViews", "SetRemoteViewsAdapterIntent action can only be used for " +
510037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                        "AppWidgets (root id: " + viewId + ")");
511037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                return;
512037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
513037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Ensure that we are calling setRemoteAdapter on an AdapterView that supports it
514037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (!(target instanceof AbsListView) && !(target instanceof AdapterViewAnimator)) {
515037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                Log.e("RemoteViews", "Cannot setRemoteViewsAdapter on a view which is not " +
516037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                        "an AbsListView or AdapterViewAnimator (id: " + viewId + ")");
517037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                return;
518037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
519037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
520037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // Embed the AppWidget Id for use in RemoteViewsAdapter when connecting to the intent
521037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            // RemoteViewsService
522037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            AppWidgetHostView host = (AppWidgetHostView) rootParent;
523037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId());
524037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            if (target instanceof AbsListView) {
525037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                AbsListView v = (AbsListView) target;
526037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                v.setRemoteViewsAdapter(intent);
527037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            } else if (target instanceof AdapterViewAnimator) {
528037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                AdapterViewAnimator v = (AdapterViewAnimator) target;
529037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung                v.setRemoteViewsAdapter(intent);
530037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung            }
531037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        }
532037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
533fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
534fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetRemoteViewsAdapterIntent";
535fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
536fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
537037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        Intent intent;
538037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
539037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        public final static int TAG = 10;
540037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    }
541037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to launch the provided {@link PendingIntent}.
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class SetOnClickPendingIntent extends Action {
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetOnClickPendingIntent(int id, PendingIntent pendingIntent) {
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = id;
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.pendingIntent = pendingIntent;
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
552ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetOnClickPendingIntent(Parcel parcel) {
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            viewId = parcel.readInt();
555c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
556c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // We check a flag to determine if the parcel contains a PendingIntent.
557c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (parcel.readInt() != 0) {
558c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
559c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            }
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
561ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel dest, int flags) {
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(TAG);
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(viewId);
565c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
566c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // We use a flag to indicate whether the parcel contains a valid object.
567c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            dest.writeInt(pendingIntent != null ? 1 : 0);
568c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (pendingIntent != null) {
569c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                pendingIntent.writeToParcel(dest, 0 /* no flags */);
570c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            }
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
572ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
574a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, final OnClickHandler handler) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View target = root.findViewById(viewId);
5762b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
577ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
578ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            // If the view is an AdapterView, setting a PendingIntent on click doesn't make much
579ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            // sense, do they mean to set a PendingIntent template for the AdapterView's children?
580ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            if (mIsWidgetCollectionChild) {
581636fd528f7ad51f565a390226d9f469f8c675ccfDianne Hackborn                Log.w("RemoteViews", "Cannot setOnClickPendingIntent for collection item " +
582c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        "(id: " + viewId + ")");
583ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                ApplicationInfo appInfo = root.getContext().getApplicationInfo();
584ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen
585ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                // We let this slide for HC and ICS so as to not break compatibility. It should have
586ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                // been disabled from the outset, but was left open by accident.
587ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                if (appInfo != null &&
588ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                        appInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
589ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                    return;
590ffc46a5c7c60c911fdaab48681c323c89b570dacAdam Cohen                }
591ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen            }
592ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
593c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            if (target != null) {
594c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                // If the pendingIntent is null, we clear the onClickListener
595c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                OnClickListener listener = null;
596c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                if (pendingIntent != null) {
597c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    listener = new OnClickListener() {
598c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        public void onClick(View v) {
599c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            // Find target view location in screen coordinates and
600c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            // fill into PendingIntent before sending.
601c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final float appScale = v.getContext().getResources()
602c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                                    .getCompatibilityInfo().applicationScale;
603c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final int[] pos = new int[2];
604c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            v.getLocationOnScreen(pos);
605e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
606c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final Rect rect = new Rect();
607c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.left = (int) (pos[0] * appScale + 0.5f);
608c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.top = (int) (pos[1] * appScale + 0.5f);
609c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
610c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
611e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
612c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            final Intent intent = new Intent();
613c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                            intent.setSourceBounds(rect);
614a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                            handler.onClickHandler(v, pendingIntent, intent);
615c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        }
616c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    };
617c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                }
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                target.setOnClickListener(listener);
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
621c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
622fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
623fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetOnClickPendingIntent";
624fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
625fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PendingIntent pendingIntent;
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final static int TAG = 1;
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given view.
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These operations will be performed on the {@link Drawable} returned by the
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * target {@link View#getBackground()} by default.  If targetBackground is false,
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * we assume the target is an {@link ImageView} and try applying the operations
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to {@link ImageView#getDrawable()}.
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * You can omit specific calls by marking their values with null or -1.
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class SetDrawableParameters extends Action {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetDrawableParameters(int id, boolean targetBackground, int alpha,
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int colorFilter, PorterDuff.Mode mode, int level) {
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = id;
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.targetBackground = targetBackground;
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.alpha = alpha;
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.colorFilter = colorFilter;
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.filterMode = mode;
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.level = level;
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
653e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SetDrawableParameters(Parcel parcel) {
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            viewId = parcel.readInt();
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            targetBackground = parcel.readInt() != 0;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            alpha = parcel.readInt();
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            colorFilter = parcel.readInt();
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean hasMode = parcel.readInt() != 0;
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (hasMode) {
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filterMode = PorterDuff.Mode.valueOf(parcel.readString());
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                filterMode = null;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            level = parcel.readInt();
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
667e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel dest, int flags) {
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(TAG);
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(viewId);
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(targetBackground ? 1 : 0);
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(alpha);
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(colorFilter);
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (filterMode != null) {
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeInt(1);
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeString(filterMode.toString());
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dest.writeInt(0);
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(level);
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
682e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
684a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View target = root.findViewById(viewId);
6862b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
687e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Pick the correct drawable to modify for this view
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Drawable targetDrawable = null;
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (targetBackground) {
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                targetDrawable = target.getBackground();
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (target instanceof ImageView) {
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ImageView imageView = (ImageView) target;
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                targetDrawable = imageView.getDrawable();
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
696e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
697a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            if (targetDrawable != null) {
698a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                // Perform modifications only if values are set correctly
699a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (alpha != -1) {
700a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setAlpha(alpha);
701a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
702a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (colorFilter != -1 && filterMode != null) {
703a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setColorFilter(colorFilter, filterMode);
704a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
705a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                if (level != -1) {
706a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    targetDrawable.setLevel(level);
707a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7103ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
711fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
712fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "SetDrawableParameters";
713fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
714fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean targetBackground;
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int alpha;
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int colorFilter;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PorterDuff.Mode filterMode;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int level;
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public final static int TAG = 3;
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
723e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
7242dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    private class ReflectionActionWithoutParams extends Action {
7252dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        String methodName;
7262dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7272dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        public final static int TAG = 5;
7282dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7292dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        ReflectionActionWithoutParams(int viewId, String methodName) {
7302dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.viewId = viewId;
7312dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.methodName = methodName;
7322dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
7332dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7342dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        ReflectionActionWithoutParams(Parcel in) {
7352dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.viewId = in.readInt();
7362dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            this.methodName = in.readString();
7372dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
7382dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7392dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        public void writeToParcel(Parcel out, int flags) {
7402dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeInt(TAG);
7412dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeInt(this.viewId);
7422dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            out.writeString(this.methodName);
7432dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
7442dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7452dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        @Override
746a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
7472dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            final View view = root.findViewById(viewId);
7482b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (view == null) return;
7492dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7502dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            Class klass = view.getClass();
7512dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            Method method;
7522dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            try {
7532dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                method = klass.getMethod(this.methodName);
7542dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            } catch (NoSuchMethodException ex) {
7552dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
7562dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
7572dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
7582dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7592dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
7602dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException("view: " + klass.getName()
7612dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + " can't use method with RemoteViews: "
7622dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
7632dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
7642dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7652dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            try {
7662dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                //noinspection ConstantIfStatement
7672dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                if (false) {
7682dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                    Log.d("RemoteViews", "view: " + klass.getName() + " calling method: "
7692dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                        + this.methodName + "()");
7702dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                }
7712dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                method.invoke(view);
7722dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            } catch (Exception ex) {
7732dd2197805edb4d9547b143deef2226413218f4cAdam Cohen                throw new ActionException(ex);
7742dd2197805edb4d9547b143deef2226413218f4cAdam Cohen            }
7752dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        }
776fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
777fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
778fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // we don't need to build up showNext or showPrevious calls
779fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (methodName.equals("showNext") || methodName.equals("showPrevious")) {
780fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_IGNORE;
781fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            } else {
782fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_REPLACE;
783fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            }
784fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
785fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
786fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
787fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ReflectionActionWithoutParams";
788fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
7892dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
7902dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
7915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private static class BitmapCache {
7925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        ArrayList<Bitmap> mBitmaps;
7935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
7945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public BitmapCache() {
7955d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmaps = new ArrayList<Bitmap>();
7965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
7975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
7985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public BitmapCache(Parcel source) {
7995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = source.readInt();
8005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmaps = new ArrayList<Bitmap>();
8015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
8025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Bitmap b = Bitmap.CREATOR.createFromParcel(source);
8035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmaps.add(b);
8045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public int getBitmapId(Bitmap b) {
8085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (b == null) {
8095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return -1;
8105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
8115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                if (mBitmaps.contains(b)) {
8125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    return mBitmaps.indexOf(b);
8135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                } else {
8145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mBitmaps.add(b);
8155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    return (mBitmaps.size() - 1);
8165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
8175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public Bitmap getBitmapForId(int id) {
8215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (id == -1 || id >= mBitmaps.size()) {
8225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return null;
8235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
8245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mBitmaps.get(id);
8255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void writeBitmapsToParcel(Parcel dest, int flags) {
8295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = mBitmaps.size();
8305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(count);
8315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
8325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmaps.get(i).writeToParcel(dest, flags);
8335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void assimilate(BitmapCache bitmapCache) {
8375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            ArrayList<Bitmap> bitmapsToBeAdded = bitmapCache.mBitmaps;
8385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = bitmapsToBeAdded.size();
8395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < count; i++) {
8405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Bitmap b = bitmapsToBeAdded.get(i);
8415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                if (!mBitmaps.contains(b)) {
8425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mBitmaps.add(b);
8435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
8445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void addBitmapMemory(MemoryUsageCounter memoryCounter) {
8485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i = 0; i < mBitmaps.size(); i++) {
8495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                memoryCounter.addBitmapMemory(mBitmaps.get(i));
8505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
8515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
8535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private class BitmapReflectionAction extends Action {
8555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int bitmapId;
8565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        Bitmap bitmap;
8575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        String methodName;
8585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        BitmapReflectionAction(int viewId, String methodName, Bitmap bitmap) {
8605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.bitmap = bitmap;
8615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.viewId = viewId;
8625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            this.methodName = methodName;
8635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = mBitmapCache.getBitmapId(bitmap);
8645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        BitmapReflectionAction(Parcel in) {
8675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            viewId = in.readInt();
8685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            methodName = in.readString();
8695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = in.readInt();
8705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmap = mBitmapCache.getBitmapForId(bitmapId);
8715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
8745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void writeToParcel(Parcel dest, int flags) {
8755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(TAG);
8765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(viewId);
8775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeString(methodName);
8785d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(bitmapId);
8795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
882a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent,
883a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                OnClickHandler handler) throws ActionException {
8845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            ReflectionAction ra = new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP,
8855d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bitmap);
886a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn            ra.apply(root, rootParent, handler);
8875d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
8895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
8905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void setBitmapCache(BitmapCache bitmapCache) {
8915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            bitmapId = bitmapCache.getBitmapId(bitmap);
8925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
8935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
894fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
895fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "BitmapReflectionAction";
896fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
897fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
8985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public final static int TAG = 12;
8995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
9005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Base class for the reflection actions.
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class ReflectionAction extends Action {
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int TAG = 2;
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BOOLEAN = 1;
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BYTE = 2;
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int SHORT = 3;
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int INT = 4;
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int LONG = 5;
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int FLOAT = 6;
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int DOUBLE = 7;
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int CHAR = 8;
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int STRING = 9;
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int CHAR_SEQUENCE = 10;
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int URI = 11;
918fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // BITMAP actions are never stored in the list of actions. They are only used locally
919fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        // to implement BitmapReflectionAction, which eliminates duplicates using BitmapCache.
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        static final int BITMAP = 12;
921d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert        static final int BUNDLE = 13;
922499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        static final int INTENT = 14;
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String methodName;
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int type;
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Object value;
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ReflectionAction(int viewId, String methodName, int type, Object value) {
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = viewId;
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.methodName = methodName;
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.type = type;
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.value = value;
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ReflectionAction(Parcel in) {
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.viewId = in.readInt();
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.methodName = in.readString();
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.type = in.readInt();
939a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            //noinspection ConstantIfStatement
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (false) {
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.d("RemoteViews", "read viewId=0x" + Integer.toHexString(this.viewId)
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " methodName=" + this.methodName + " type=" + this.type);
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
944c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
945c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // For some values that may have been null, we first check a flag to see if they were
946c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // written to the parcel.
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readInt() != 0;
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readByte();
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = (short)in.readInt();
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readInt();
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readLong();
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readFloat();
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readDouble();
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = (char)in.readInt();
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = in.readString();
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.value = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
979c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
980c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Uri.CREATOR.createFromParcel(in);
981c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
984c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
985c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Bitmap.CREATOR.createFromParcel(in);
986c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
988d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
989d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    this.value = in.readBundle();
990d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    break;
991499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
992c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (in.readInt() != 0) {
993c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        this.value = Intent.CREATOR.createFromParcel(in);
994c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
995499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    break;
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel out, int flags) {
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(TAG);
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(this.viewId);
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeString(this.methodName);
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            out.writeInt(this.type);
1006a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            //noinspection ConstantIfStatement
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (false) {
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.d("RemoteViews", "write viewId=0x" + Integer.toHexString(this.viewId)
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " methodName=" + this.methodName + " type=" + this.type);
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1011c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen
1012c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // For some values which are null, we record an integer flag to indicate whether
1013c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen            // we have written a valid value to the parcel.
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
1016a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Boolean) this.value ? 1 : 0);
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
1019a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeByte((Byte) this.value);
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
1022a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Short) this.value);
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
1025a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeInt((Integer) this.value);
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
1028a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeLong((Long) this.value);
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
1031a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeFloat((Float) this.value);
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
1034a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                    out.writeDouble((Double) this.value);
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    out.writeInt((int)((Character)this.value).charValue());
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    out.writeString((String)this.value);
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
1043e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller                    TextUtils.writeToParcel((CharSequence)this.value, out, flags);
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
1046c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1047c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1048c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Uri)this.value).writeToParcel(out, flags);
1049c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
1052c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1053c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1054c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Bitmap)this.value).writeToParcel(out, flags);
1055c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1057d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
1058d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    out.writeBundle((Bundle) this.value);
1059d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    break;
1060499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
1061c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    out.writeInt(this.value != null ? 1 : 0);
1062c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    if (this.value != null) {
1063c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                        ((Intent)this.value).writeToParcel(out, flags);
1064c6151f2369d92e7725d30d13c62b64cff49285a6Adam Cohen                    }
1065499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    break;
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private Class getParameterType() {
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (this.type) {
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BOOLEAN:
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return boolean.class;
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BYTE:
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return byte.class;
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case SHORT:
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return short.class;
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case INT:
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return int.class;
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case LONG:
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return long.class;
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case FLOAT:
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return float.class;
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case DOUBLE:
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return double.class;
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR:
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return char.class;
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STRING:
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return String.class;
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case CHAR_SEQUENCE:
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return CharSequence.class;
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case URI:
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return Uri.class;
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case BITMAP:
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return Bitmap.class;
1097d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                case BUNDLE:
1098d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert                    return Bundle.class;
1099499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                case INTENT:
1100499cb9f516062b654952d282f211bee44c31a3c2Winson Chung                    return Intent.class;
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                default:
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return null;
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1107a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final View view = root.findViewById(viewId);
11092b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (view == null) return;
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Class param = getParameterType();
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (param == null) {
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("bad type: " + this.type);
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Class klass = view.getClass();
1117a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy            Method method;
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                method = klass.getMethod(this.methodName, getParameterType());
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            catch (NoSuchMethodException ex) {
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ")");
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException("view: " + klass.getName()
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " can't use method with RemoteViews: "
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ")");
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
1133a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                //noinspection ConstantIfStatement
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (false) {
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.d("RemoteViews", "view: " + klass.getName() + " calling method: "
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + this.methodName + "(" + param.getName() + ") with "
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + (this.value == null ? "null" : this.value.getClass().getName()));
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                method.invoke(view, this.value);
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            catch (Exception ex) {
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new ActionException(ex);
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11453ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
1146fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
1147fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // smoothScrollBy is cumulative, everything else overwites.
1148fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            if (methodName.equals("smoothScrollBy")) {
1149fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_APPEND;
1150fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            } else {
1151fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen                return MERGE_REPLACE;
11523ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
11533ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
1154fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1155fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1156fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // Each type of reflection action corresponds to a setter, so each should be seen as
1157fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            // unique from the standpoint of merging.
1158fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ReflectionAction" + this.methodName + this.type;
1159fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private void configureRemoteViewsAsChild(RemoteViews rv) {
11635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache.assimilate(rv.mBitmapCache);
11645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        rv.setBitmapCache(mBitmapCache);
11655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        rv.setNotRoot();
11665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
11675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
11685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    void setNotRoot() {
11695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mIsRoot = false;
11705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
11715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
11721162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
11731162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
11741162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * given {@link RemoteViews}, or calling {@link ViewGroup#removeAllViews()}
11751162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * when null. This allows users to build "nested" {@link RemoteViews}.
11761162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
11771162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    private class ViewGroupAction extends Action {
11781162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public ViewGroupAction(int viewId, RemoteViews nestedViews) {
11791162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            this.viewId = viewId;
11801162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            this.nestedViews = nestedViews;
1181c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen            if (nestedViews != null) {
1182c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen                configureRemoteViewsAsChild(nestedViews);
1183c431c156bbb5c59f921c031e56744e5d6f12a77aAdam Cohen            }
11841162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
11851162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
11865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public ViewGroupAction(Parcel parcel, BitmapCache bitmapCache) {
11871162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            viewId = parcel.readInt();
11885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            boolean nestedViewsNull = parcel.readInt() == 0;
11895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (!nestedViewsNull) {
11905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews = new RemoteViews(parcel, bitmapCache);
11915d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
11925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews = null;
11935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
11941162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
11951162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
11961162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public void writeToParcel(Parcel dest, int flags) {
11971162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            dest.writeInt(TAG);
11981162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            dest.writeInt(viewId);
11995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (nestedViews != null) {
12005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                dest.writeInt(1);
12015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews.writeToParcel(dest, flags);
12025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
12035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                // signifies null
12045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                dest.writeInt(0);
12055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
12061162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
12071162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12081162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        @Override
1209a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
12101162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            final Context context = root.getContext();
12111162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            final ViewGroup target = (ViewGroup) root.findViewById(viewId);
12122b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            if (target == null) return;
12131162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            if (nestedViews != null) {
12141162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                // Inflate nested views and add as children
1215a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                target.addView(nestedViews.apply(context, target, handler));
12162b69ce469d544f4b2cb6423feaf4da8df7cf7a64Joe Onorato            } else {
12171162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                // Clear all children when nested views omitted
12181162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey                target.removeAllViews();
12191162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey            }
12201162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        }
12211162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12223ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        @Override
12233ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
12243ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            if (nestedViews != null) {
12255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                counter.increment(nestedViews.estimateMemoryUsage());
12265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
12275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
12285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
12295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        @Override
12305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void setBitmapCache(BitmapCache bitmapCache) {
12315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (nestedViews != null) {
12325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                nestedViews.setBitmapCache(bitmapCache);
12333ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
12343ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
12353ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
1236fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1237fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ViewGroupAction" + this.nestedViews == null ? "Remove" : "Add";
1238fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1239fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1240fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public int mergeBehavior() {
1241fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return MERGE_APPEND;
1242fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1243fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
12441162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        RemoteViews nestedViews;
12451162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
12461162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        public final static int TAG = 4;
12471162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1250820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * Helper action to set compound drawables on a TextView. Supports relative
1251820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * (s/t/e/b) or cardinal (l/t/r/b) arrangement.
1252820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1253820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    private class TextViewDrawableAction extends Action {
1254820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public TextViewDrawableAction(int viewId, boolean isRelative, int d1, int d2, int d3, int d4) {
1255820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.viewId = viewId;
1256820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.isRelative = isRelative;
1257820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d1 = d1;
1258820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d2 = d2;
1259820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d3 = d3;
1260820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            this.d4 = d4;
1261820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1262820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1263820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public TextViewDrawableAction(Parcel parcel) {
1264820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            viewId = parcel.readInt();
1265820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            isRelative = (parcel.readInt() != 0);
1266820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d1 = parcel.readInt();
1267820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d2 = parcel.readInt();
1268820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d3 = parcel.readInt();
1269820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            d4 = parcel.readInt();
1270820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1271820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1272820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public void writeToParcel(Parcel dest, int flags) {
1273820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(TAG);
1274820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(viewId);
1275820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(isRelative ? 1 : 0);
1276820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d1);
1277820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d2);
1278820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d3);
1279820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            dest.writeInt(d4);
1280820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1281820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1282820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        @Override
1283a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
1284820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            final Context context = root.getContext();
1285820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            final TextView target = (TextView) root.findViewById(viewId);
1286820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            if (target == null) return;
1287820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            if (isRelative) {
1288820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler                target.setCompoundDrawablesRelativeWithIntrinsicBounds(d1, d2, d3, d4);
1289820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            } else {
1290820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler                target.setCompoundDrawablesWithIntrinsicBounds(d1, d2, d3, d4);
1291820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler            }
1292820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        }
1293820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1294fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1295fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "TextViewDrawableAction";
1296fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1297fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
1298820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        boolean isRelative = false;
1299820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        int d1, d2, d3, d4;
1300820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1301820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        public final static int TAG = 11;
1302820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1303820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1304820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
130599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * Helper action to set text size on a TextView in any supported units.
13067264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     */
13077264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    private class TextViewSizeAction extends Action {
13087264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public TextViewSizeAction(int viewId, int units, float size) {
13097264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.viewId = viewId;
13107264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.units = units;
13117264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            this.size = size;
13127264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
13137264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13147264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public TextViewSizeAction(Parcel parcel) {
13157264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            viewId = parcel.readInt();
13167264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            units = parcel.readInt();
13177264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            size  = parcel.readFloat();
13187264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
13197264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13207264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public void writeToParcel(Parcel dest, int flags) {
13217264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(TAG);
13227264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(viewId);
13237264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeInt(units);
13247264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            dest.writeFloat(size);
13257264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
13267264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13277264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        @Override
1328a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
13297264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            final Context context = root.getContext();
13307264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            final TextView target = (TextView) root.findViewById(viewId);
13317264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            if (target == null) return;
13327264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler            target.setTextSize(units, size);
13337264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        }
13347264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
1335fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1336fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "TextViewSizeAction";
1337fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1338fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
13397264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        int units;
13407264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        float size;
13417264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13427264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        public final static int TAG = 13;
13437264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    }
13447264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
13457264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    /**
134699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * Helper action to set padding on a View.
134799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     */
134899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    private class ViewPaddingAction extends Action {
134999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public ViewPaddingAction(int viewId, int left, int top, int right, int bottom) {
135099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.viewId = viewId;
135199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.left = left;
135299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.top = top;
135399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.right = right;
135499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            this.bottom = bottom;
135599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
135699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
135799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public ViewPaddingAction(Parcel parcel) {
135899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            viewId = parcel.readInt();
135999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            left = parcel.readInt();
136099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            top = parcel.readInt();
136199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            right = parcel.readInt();
136299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            bottom = parcel.readInt();
136399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
136499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
136599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public void writeToParcel(Parcel dest, int flags) {
136699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(TAG);
136799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(viewId);
136899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(left);
136999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(top);
137099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(right);
137199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            dest.writeInt(bottom);
137299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
137399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
137499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        @Override
1375a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
137699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            final Context context = root.getContext();
137799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            final View target = root.findViewById(viewId);
137899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            if (target == null) return;
137999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler            target.setPadding(left, top, right, bottom);
138099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        }
138199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
1382fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        public String getActionName() {
1383fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen            return "ViewPaddingAction";
1384fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen        }
1385fbe44b7d5e2d9d06a238a54f8ed460fb8bc49585Adam Cohen
138699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        int left, top, right, bottom;
138799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
138899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        public final static int TAG = 14;
138999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    }
139099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
139199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    /**
13923ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Simple class used to keep track of memory usage in a RemoteViews.
13933ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     *
13943ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
13953ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    private class MemoryUsageCounter {
13963ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        public void clear() {
13975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsage = 0;
13983ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
13993ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void increment(int numBytes) {
14015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsage += numBytes;
14023ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
14033ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public int getMemoryUsage() {
14055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            return mMemoryUsage;
14063ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
14073ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        public void addBitmapMemory(Bitmap b) {
14095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            final Bitmap.Config c = b.getConfig();
14105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // If we don't know, be pessimistic and assume 4
14115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int bpp = 4;
14125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (c != null) {
14135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                switch (c) {
14145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ALPHA_8:
14155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 1;
14165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
14175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case RGB_565:
14185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ARGB_4444:
14195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 2;
14205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
14215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                case ARGB_8888:
14225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    bpp = 4;
14235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    break;
14245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
14255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
14265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            increment(b.getWidth() * b.getHeight() * bpp);
14275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
14285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int mMemoryUsage;
14303ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
14313ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14323ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new RemoteViews object that will display the views contained
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the specified layout file.
1435e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param packageName Name of the package that contains the layout resource
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param layoutId The id of the layout resource
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RemoteViews(String packageName, int layoutId) {
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPackage = packageName;
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayoutId = layoutId;
14425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = new BitmapCache();
14433ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
14443ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // setup the memory usage statistics
14453ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter = new MemoryUsageCounter();
14463ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        recalculateMemoryUsage();
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private boolean hasLandscapeAndPortraitLayouts() {
14505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return (mLandscape != null) && (mPortrait != null);
14515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
14525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     /**
14545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Create a new RemoteViews object that will inflate as the specified
14555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * landspace or portrait RemoteViews, depending on the current configuration.
14565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     *
14575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @param landscape The RemoteViews to inflate in landscape configuration
14585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @param portrait The RemoteViews to inflate in portrait configuration
14595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
14605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    public RemoteViews(RemoteViews landscape, RemoteViews portrait) {
14615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (landscape == null || portrait == null) {
14625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("Both RemoteViews must be non-null");
14635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
14645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (landscape.getPackage().compareTo(portrait.getPackage()) != 0) {
14655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("Both RemoteViews must share the same package");
14665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
14675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mPackage = portrait.getPackage();
14685d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mLayoutId = portrait.getLayoutId();
14695d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14705d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mLandscape = landscape;
14715d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mPortrait = portrait;
14725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // setup the memory usage statistics
14745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mMemoryUsageCounter = new MemoryUsageCounter();
14755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = new BitmapCache();
14775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        configureRemoteViewsAsChild(landscape);
14785d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        configureRemoteViewsAsChild(portrait);
14795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        recalculateMemoryUsage();
14815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
14825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Reads a RemoteViews object from a parcel.
1485e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parcel
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RemoteViews(Parcel parcel) {
14895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        this(parcel, null);
14905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
1491ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
14925d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews(Parcel parcel, BitmapCache bitmapCache) {
14935d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        int mode = parcel.readInt();
14945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
14955d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // We only store a bitmap cache in the root of the RemoteViews.
14965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (bitmapCache == null) {
14975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmapCache = new BitmapCache(parcel);
14985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
14995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            setBitmapCache(bitmapCache);
15005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            setNotRoot();
15015d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
15025d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15035d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (mode == MODE_NORMAL) {
15045d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPackage = parcel.readString();
15055d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLayoutId = parcel.readInt();
15065d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mIsWidgetCollectionChild = parcel.readInt() == 1 ? true : false;
15075d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
15085d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count = parcel.readInt();
15095d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (count > 0) {
15105d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mActions = new ArrayList<Action>(count);
15115d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i=0; i<count; i++) {
15125d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    int tag = parcel.readInt();
15135d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    switch (tag) {
15145d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetOnClickPendingIntent.TAG:
15155d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetOnClickPendingIntent(parcel));
15165d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetDrawableParameters.TAG:
15185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetDrawableParameters(parcel));
15195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ReflectionAction.TAG:
15215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ReflectionAction(parcel));
15225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ViewGroupAction.TAG:
15245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ViewGroupAction(parcel, mBitmapCache));
15255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case ReflectionActionWithoutParams.TAG:
15275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new ReflectionActionWithoutParams(parcel));
15285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetEmptyView.TAG:
15305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetEmptyView(parcel));
15315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetPendingIntentTemplate.TAG:
15335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetPendingIntentTemplate(parcel));
15345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetOnClickFillInIntent.TAG:
15365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetOnClickFillInIntent(parcel));
15375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case SetRemoteViewsAdapterIntent.TAG:
15395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new SetRemoteViewsAdapterIntent(parcel));
15405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case TextViewDrawableAction.TAG:
15425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new TextViewDrawableAction(parcel));
15435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15447264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                    case TextViewSizeAction.TAG:
15457264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                        mActions.add(new TextViewSizeAction(parcel));
15467264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler                        break;
154799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                    case ViewPaddingAction.TAG:
154899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                        mActions.add(new ViewPaddingAction(parcel));
154999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler                        break;
15505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    case BitmapReflectionAction.TAG:
15515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        mActions.add(new BitmapReflectionAction(parcel));
15525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        break;
15535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    default:
15545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        throw new ActionException("Tag " + tag + " not found");
15555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    }
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
15595d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // MODE_HAS_LANDSCAPE_AND_PORTRAIT
15605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape = new RemoteViews(parcel, mBitmapCache);
15615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait = new RemoteViews(parcel, mBitmapCache);
15625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPackage = mPortrait.getPackage();
15635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLayoutId = mPortrait.getLayoutId();
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15653ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
15663ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // setup the memory usage statistics
15673ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter = new MemoryUsageCounter();
15683ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        recalculateMemoryUsage();
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15713030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne    @Override
157218e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato    public RemoteViews clone() {
15735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        RemoteViews that;
15745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
15755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            that = new RemoteViews(mPackage, mLayoutId);
15763ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
15775d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
15785d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                that.mActions = (ArrayList<Action>)mActions.clone();
15795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
15805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
15815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            RemoteViews land = mLandscape.clone();
15825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            RemoteViews port = mPortrait.clone();
15835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            that = new RemoteViews(land, port);
15845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
15853ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // update the memory usage stats of the cloned RemoteViews
15863ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        that.recalculateMemoryUsage();
158718e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato        return that;
158818e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato    }
158918e69dfc7235f8a4bfe257f9d1c43539049a22ceJoe Onorato
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getPackage() {
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mPackage;
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15945d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
15955d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Reutrns the layout id of the root layout associated with this RemoteViews. In the case
15965d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * that the RemoteViews has both a landscape and portrait root, this will return the layout
15975d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * id associated with the portrait layout.
15985d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     *
15995d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * @return the layout id.
16005d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getLayoutId() {
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayoutId;
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16053ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /*
1606ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * This flag indicates whether this RemoteViews object is being created from a
1607ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * RemoteViewsService for use as a child of a widget collection. This flag is used
1608ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * to determine whether or not certain features are available, in particular,
1609ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * setting on click extras and setting on click pending intents. The former is enabled,
1610ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * and the latter disabled when this flag is true.
1611ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     */
1612ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    void setIsWidgetCollectionChild(boolean isWidgetCollectionChild) {
1613ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        mIsWidgetCollectionChild = isWidgetCollectionChild;
1614ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    }
1615ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
1616ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    /**
16173ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Updates the memory usage statistics.
16183ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
16193ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    private void recalculateMemoryUsage() {
16203ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        mMemoryUsageCounter.clear();
16213ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
16235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // Accumulate the memory usage for each action
16245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
16255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                final int count = mActions.size();
16265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i= 0; i < count; ++i) {
16275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mActions.get(i).updateMemoryUsageEstimate(mMemoryUsageCounter);
16285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
16295d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
16305d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
16315d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.addBitmapMemory(mMemoryUsageCounter);
16323ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung            }
16335d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
16345d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsageCounter.increment(mLandscape.estimateMemoryUsage());
16355d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mMemoryUsageCounter.increment(mPortrait.estimateMemoryUsage());
16365d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mBitmapCache.addBitmapMemory(mMemoryUsageCounter);
16375d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
16385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
16395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
16405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    /**
16415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     * Recursively sets BitmapCache in the hierarchy and update the bitmap ids.
16425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen     */
16435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private void setBitmapCache(BitmapCache bitmapCache) {
16445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        mBitmapCache = bitmapCache;
16455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
16465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
16475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                final int count = mActions.size();
16485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                for (int i= 0; i < count; ++i) {
16495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    mActions.get(i).setBitmapCache(bitmapCache);
16505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                }
16515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
16525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        } else {
16535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape.setBitmapCache(bitmapCache);
16545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait.setBitmapCache(bitmapCache);
16553ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        }
16563ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
16573ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16583ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
16593ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     * Returns an estimate of the bitmap heap memory usage for this RemoteViews.
16603ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung     */
1661311c79c3e93589c6fc720fe6c58ed522af591376Adam Cohen    /** @hide */
1662311c79c3e93589c6fc720fe6c58ed522af591376Adam Cohen    public int estimateMemoryUsage() {
16635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return mMemoryUsageCounter.getMemoryUsage();
16643ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    }
16653ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16663ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung    /**
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Add an action to be executed on the remote side when apply is called.
1668e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param a The action to add
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void addAction(Action a) {
16725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
16735d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            throw new RuntimeException("RemoteViews specifying separate landscape and portrait" +
16745d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    " layouts cannot be modified. Instead, fully configure the landscape and" +
16755d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                    " portrait layouts individually before constructing the combined layout.");
16765d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mActions == null) {
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mActions = new ArrayList<Action>();
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mActions.add(a);
16813ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung
16823ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        // update the memory usage stats
16833ec9a45c36d3ca5ffbc6e85bbeb497b065e14155Winson Chung        a.updateMemoryUsageEstimate(mMemoryUsageCounter);
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16851162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
16861162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
16871162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
16881162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * given {@link RemoteViews}. This allows users to build "nested"
16891162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * {@link RemoteViews}. In cases where consumers of {@link RemoteViews} may
16901162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * recycle layouts, use {@link #removeAllViews(int)} to clear any existing
16911162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * children.
16921162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *
16931162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param viewId The id of the parent {@link ViewGroup} to add child into.
16941162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param nestedView {@link RemoteViews} that describes the child.
16951162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
16961162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    public void addView(int viewId, RemoteViews nestedView) {
16971162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        addAction(new ViewGroupAction(viewId, nestedView));
16981162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
16991162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
17001162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    /**
17011162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * Equivalent to calling {@link ViewGroup#removeAllViews()}.
17021162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *
17031162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     * @param viewId The id of the parent {@link ViewGroup} to remove all
17041162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     *            children from.
17051162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey     */
17061162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    public void removeAllViews(int viewId) {
17071162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey        addAction(new ViewGroupAction(viewId, null));
17081162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey    }
17091162fd77a8ff8467c96204c00bcaf941aef6aa85Jeff Sharkey
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17110b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#showNext()}
17122dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     *
17130b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call {@link AdapterViewAnimator#showNext()}
17142dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     */
17152dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    public void showNext(int viewId) {
17162dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        addAction(new ReflectionActionWithoutParams(viewId, "showNext"));
17172dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
17182dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
17192dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    /**
17200b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#showPrevious()}
17212dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     *
17220b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call {@link AdapterViewAnimator#showPrevious()}
17232dd2197805edb4d9547b143deef2226413218f4cAdam Cohen     */
17242dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    public void showPrevious(int viewId) {
17252dd2197805edb4d9547b143deef2226413218f4cAdam Cohen        addAction(new ReflectionActionWithoutParams(viewId, "showPrevious"));
17262dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    }
17272dd2197805edb4d9547b143deef2226413218f4cAdam Cohen
17282dd2197805edb4d9547b143deef2226413218f4cAdam Cohen    /**
17290b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * Equivalent to calling {@link AdapterViewAnimator#setDisplayedChild(int)}
17300b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     *
17310b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     * @param viewId The id of the view on which to call
17320b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     *               {@link AdapterViewAnimator#setDisplayedChild(int)}
17330b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen     */
17340b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    public void setDisplayedChild(int viewId, int childIndex) {
17350b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen        setInt(viewId, "setDisplayedChild", childIndex);
17360b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    }
17370b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen
17380b96a57c851af2f66e3bc738035478efb3c1957eAdam Cohen    /**
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling View.setVisibility
1740e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose visibility should change
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param visibility The new visibility for the view
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setViewVisibility(int viewId, int visibility) {
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setVisibility", visibility);
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1747ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling TextView.setText
1750e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose text should change
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text The new text for the view
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTextViewText(int viewId, CharSequence text) {
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setCharSequence(viewId, "setText", text);
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17577264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
17587264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    /**
17597264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * Equivalent to calling {@link TextView#setTextSize(int, float)}
1760e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
17617264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param viewId The id of the view whose text size should change
17627264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param units The units of size (e.g. COMPLEX_UNIT_SP)
17637264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     * @param size The size of the text
17647264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler     */
17657264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    public void setTextViewTextSize(int viewId, int units, float size) {
17667264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler        addAction(new TextViewSizeAction(viewId, units, size));
17677264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler    }
17687264f71399018e2dd79d974ee5162cf652ac786fDaniel Sandler
17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1770e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * Equivalent to calling
1771820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * {@link TextView#setCompoundDrawablesWithIntrinsicBounds(int, int, int, int)}.
1772820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     *
1773820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param viewId The id of the view whose text should change
1774820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param left The id of a drawable to place to the left of the text, or 0
1775820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param top The id of a drawable to place above the text, or 0
1776820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param right The id of a drawable to place to the right of the text, or 0
1777e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param bottom The id of a drawable to place below the text, or 0
1778820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1779820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    public void setTextViewCompoundDrawables(int viewId, int left, int top, int right, int bottom) {
1780820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        addAction(new TextViewDrawableAction(viewId, false, left, top, right, bottom));
1781820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1782820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1783820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
1784e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * Equivalent to calling {@link
1785820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)}.
1786820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     *
1787820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param viewId The id of the view whose text should change
1788e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param start The id of a drawable to place before the text (relative to the
1789820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * layout direction), or 0
1790820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param top The id of a drawable to place above the text, or 0
1791820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     * @param end The id of a drawable to place after the text, or 0
179266388dcb09018933ccd1d38eae563f0890ba4f06Fabrice Di Meglio     * @param bottom The id of a drawable to place below the text, or 0
1793820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler     */
1794820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    public void setTextViewCompoundDrawablesRelative(int viewId, int start, int top, int end, int bottom) {
1795820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler        addAction(new TextViewDrawableAction(viewId, true, start, top, end, bottom));
1796820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    }
1797820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler
1798820ba323f9919d33aac5e999bd8daa7842d3969cDaniel Sandler    /**
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageResource
1800e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose drawable should change
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param srcId The new resource id for the drawable
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1804e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller    public void setImageViewResource(int viewId, int srcId) {
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setImageResource", srcId);
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageURI
1810e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view whose drawable should change
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The Uri for the image
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setImageViewUri(int viewId, Uri uri) {
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setUri(viewId, "setImageURI", uri);
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling ImageView.setImageBitmap
1820e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
182193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view whose bitmap should change
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bitmap The new Bitmap for the drawable
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setImageViewBitmap(int viewId, Bitmap bitmap) {
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBitmap(viewId, "setImageBitmap", bitmap);
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18291480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * Equivalent to calling AdapterView.setEmptyView
18301480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     *
18311480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * @param viewId The id of the view on which to set the empty view
18321480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     * @param emptyViewId The view id of the empty view
18331480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen     */
18341480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    public void setEmptyView(int viewId, int emptyViewId) {
18351480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen        addAction(new SetEmptyView(viewId, emptyViewId));
18361480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    }
18371480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen
18381480fddea874a42adb43b4bcdac6704e4c3e110bAdam Cohen    /**
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link Chronometer#setBase Chronometer.setBase},
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Chronometer#setFormat Chronometer.setFormat},
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link Chronometer#start Chronometer.start()} or
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Chronometer#stop Chronometer.stop()}.
1843e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
184493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link Chronometer} to change
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param base The time at which the timer would have read 0:00.  This
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             time should be based off of
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}.
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param format The Chronometer format string, or null to
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               simply display the timer value.
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param started True if you want the clock to be started, false if not.
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setChronometer(int viewId, long base, String format, boolean started) {
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setLong(viewId, "setBase", base);
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setString(viewId, "setFormat", format);
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBoolean(viewId, "setStarted", started);
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1857e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link ProgressBar#setMax ProgressBar.setMax},
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ProgressBar#setProgress ProgressBar.setProgress}, and
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ProgressBar#setIndeterminate ProgressBar.setIndeterminate}
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If indeterminate is true, then the values for max and progress are ignored.
1864e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
186593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link ProgressBar} to change
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param max The 100% value for the progress bar
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param progress The current value of the progress bar.
1868e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     * @param indeterminate True if the progress bar is indeterminate,
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                false if not.
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1871e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller    public void setProgressBar(int viewId, int max, int progress,
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean indeterminate) {
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setBoolean(viewId, "setIndeterminate", indeterminate);
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!indeterminate) {
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setInt(viewId, "setMax", max);
18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setInt(viewId, "setProgress", progress);
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1879e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller
18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to launch the provided {@link PendingIntent}.
1884e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
188535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When setting the on-click action of items within collections (eg. {@link ListView},
188635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * {@link StackView} etc.), this method will not work. Instead, use {@link
188735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setPendingIntentTemplate(int, PendingIntent) in conjunction with
188835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setOnClickFillInIntent(int, Intent).
188935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view that will trigger the {@link PendingIntent} when clicked
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pendingIntent The {@link PendingIntent} to send when user clicks
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) {
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new SetOnClickPendingIntent(viewId, pendingIntent));
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
189835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very
189935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * costly to set PendingIntents on the individual items, and is hence not permitted. Instead
190035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * this method should be used to set a single PendingIntent template on the collection, and
190135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * individual items can differentiate their on-click behavior using
190235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * {@link RemoteViews#setOnClickFillInIntent(int, Intent)}.
1903ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *
1904ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * @param viewId The id of the collection who's children will use this PendingIntent template
1905ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *          when clicked
1906ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     * @param pendingIntentTemplate The {@link PendingIntent} to be combined with extras specified
1907ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     *          by a child of viewId and executed when that child is clicked
1908ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen     */
1909ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    public void setPendingIntentTemplate(int viewId, PendingIntent pendingIntentTemplate) {
1910ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen        addAction(new SetPendingIntentTemplate(viewId, pendingIntentTemplate));
1911ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    }
1912ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen
1913ca6fd847945464c2ddddcd165021082c048f05fbAdam Cohen    /**
191435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very
191535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * costly to set PendingIntents on the individual items, and is hence not permitted. Instead
191635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * a single PendingIntent template can be set on the collection, see {@link
191735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * RemoteViews#setPendingIntentTemplate(int, PendingIntent)}, and the individual on-click
191835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * action of a given item can be distinguished by setting a fillInIntent on that item. The
191935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * fillInIntent is then combined with the PendingIntent template in order to determine the final
192035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * intent which will be executed when the item is clicked. This works as follows: any fields
192135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * which are left blank in the PendingIntent template, but are provided by the fillInIntent
192235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * will be overwritten, and the resulting PendingIntent will be used.
192335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
192435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
192535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * of the PendingIntent template will then be filled in with the associated fields that are
192635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * set in fillInIntent. See {@link Intent#fillIn(Intent, int)} for more details.
192735ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *
192835ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * @param viewId The id of the view on which to set the fillInIntent
192935ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     * @param fillInIntent The intent which will be combined with the parent's PendingIntent
193035ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     *        in order to determine the on-click behavior of the view specified by viewId
193135ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen     */
193235ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    public void setOnClickFillInIntent(int viewId, Intent fillInIntent) {
193335ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen        addAction(new SetOnClickFillInIntent(viewId, fillInIntent));
193435ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    }
193535ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen
193635ae9ca5bf4b99bc341afe43d501a2d166f5df43Adam Cohen    /**
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * view.
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * You can omit specific calls by marking their values with null or -1.
1944e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param viewId The id of the view that contains the target
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link Drawable}
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param targetBackground If true, apply these parameters to the
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link Drawable} returned by
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link android.view.View#getBackground()}. Otherwise, assume
19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the target view is an {@link ImageView} and apply them to
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link ImageView#getDrawable()}.
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param alpha Specify an alpha value for the drawable, or -1 to leave
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colorFilter Specify a color for a
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            {@link android.graphics.ColorFilter} for this drawable, or -1
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            to leave unchanged.
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode Specify a PorterDuff mode for this drawable, or null to leave
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param level Specify the level for the drawable, or -1 to leave
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            unchanged.
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDrawableParameters(int viewId, boolean targetBackground, int alpha,
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int colorFilter, PorterDuff.Mode mode, int level) {
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new SetDrawableParameters(viewId, targetBackground, alpha,
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                colorFilter, mode, level));
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Equivalent to calling {@link android.widget.TextView#setTextColor(int)}.
1970e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
197193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view whose text color should change
19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param color Sets the text color for all the states (normal, selected,
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            focused) to be this color.
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTextColor(int viewId, int color) {
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setInt(viewId, "setTextColor", color);
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1979592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
1980499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
1981499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
1982037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @param appWidgetId The id of the app widget which contains the specified view. (This
1983037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *      parameter is ignored in this deprecated method)
198493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link AbsListView}
198581f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     * @param intent The intent of the service which will be
198681f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     *            providing data to the RemoteViewsAdapter
1987037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @deprecated This method has been deprecated. See
1988037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *      {@link android.widget.RemoteViews#setRemoteAdapter(int, Intent)}
198981f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung     */
1990037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    @Deprecated
199181f39eb6e76d0be1dd341af835e8002a0f80524eWinson Chung    public void setRemoteAdapter(int appWidgetId, int viewId, Intent intent) {
1992037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        setRemoteAdapter(viewId, intent);
1993037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    }
1994037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung
1995037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    /**
1996037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
1997037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * Can only be used for App Widgets.
1998037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *
199993dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the {@link AbsListView}
2000037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     * @param intent The intent of the service which will be
2001037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     *            providing data to the RemoteViewsAdapter
2002037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung     */
2003037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung    public void setRemoteAdapter(int viewId, Intent intent) {
2004037300bba5c87c9a9efe1f693b48f6ff1ffd7479Winson Chung        addAction(new SetRemoteViewsAdapterIntent(viewId, intent));
2005499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2006499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2007499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
2008499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
2009499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
201093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view to change
2011499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * @param position Scroll to this adapter position
2012499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2013499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setScrollPosition(int viewId, int position) {
2014499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        setInt(viewId, "smoothScrollToPosition", position);
2015499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2016499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2017499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
2018499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     * Equivalent to calling {@link android.widget.AbsListView#smoothScrollToPosition(int, int)}.
2019499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
202093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view to change
202195362595ed4a42aec87b4d166092b30c8139d220Winson Chung     * @param offset Scroll by this adapter position offset
2022499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2023499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setRelativeScrollPosition(int viewId, int offset) {
2024499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        setInt(viewId, "smoothScrollByOffset", offset);
2025499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2026499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2027499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
2028d5353b475001f19e3cbc9c1a4165c9e6038a812fDaniel Sandler     * Equivalent to calling {@link android.view.View#setPadding(int, int, int, int)}.
202999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     *
203099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param viewId The id of the view to change
203199d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param left the left padding in pixels
203299d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param top the top padding in pixels
203399d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param right the right padding in pixels
203499d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     * @param bottom the bottom padding in pixels
203599d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler     */
203699d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    public void setViewPadding(int viewId, int left, int top, int right, int bottom) {
203799d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler        addAction(new ViewPaddingAction(viewId, left, top, right, bottom));
203899d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    }
203999d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler
204099d1f74864c3449585690f85a5fe6fb36ef796d5Daniel Sandler    /**
2041592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one boolean on a view in the layout for this RemoteViews.
2042592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
204393dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2044592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2045592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2046592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBoolean(int viewId, String methodName, boolean value) {
20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BOOLEAN, value));
20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2051592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2052592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one byte on a view in the layout for this RemoteViews.
2053592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
205493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2055592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2056592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2057592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setByte(int viewId, String methodName, byte value) {
20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BYTE, value));
20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2062592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2063592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one short on a view in the layout for this RemoteViews.
2064592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
206593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2066592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2067592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2068592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setShort(int viewId, String methodName, short value) {
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.SHORT, value));
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2073592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2074592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one int on a view in the layout for this RemoteViews.
2075592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
207693dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2077592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2078592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2079592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInt(int viewId, String methodName, int value) {
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INT, value));
20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2084592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2085592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one long on a view in the layout for this RemoteViews.
2086592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
208793dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2088592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2089592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2090592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setLong(int viewId, String methodName, long value) {
20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.LONG, value));
20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2095592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2096592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one float on a view in the layout for this RemoteViews.
2097592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
209893dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2099592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2100592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2101592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFloat(int viewId, String methodName, float value) {
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.FLOAT, value));
21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2106592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2107592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one double on a view in the layout for this RemoteViews.
2108592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
210993dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2110592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2111592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2112592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDouble(int viewId, String methodName, double value) {
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.DOUBLE, value));
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2117592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2118592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one char on a view in the layout for this RemoteViews.
2119592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
212093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2121592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2122592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2123592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setChar(int viewId, String methodName, char value) {
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR, value));
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2128592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2129592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one String on a view in the layout for this RemoteViews.
2130592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
213193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2132592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2133592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2134592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setString(int viewId, String methodName, String value) {
21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.STRING, value));
21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2140592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one CharSequence on a view in the layout for this RemoteViews.
2141592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
214293dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2143592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2144592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2145592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCharSequence(int viewId, String methodName, CharSequence value) {
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE, value));
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2150592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2151592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one Uri on a view in the layout for this RemoteViews.
2152592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
215393dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2154592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2155592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2156592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setUri(int viewId, String methodName, Uri value) {
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.URI, value));
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2161592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato    /**
2162592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * Call a method taking one Bitmap on a view in the layout for this RemoteViews.
2163592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @more
2164592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * <p class="note">The bitmap will be flattened into the parcel if this object is
2165592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * sent across processes, so it may end up using a lot of memory, and may be fairly slow.</p>
2166592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     *
216793dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2168592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param methodName The name of the method to call.
2169592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     * @param value The value to pass to the method.
2170592d0650d5bfc673082c4e58ac8ba2dc3103c842Joe Onorato     */
21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBitmap(int viewId, String methodName, Bitmap value) {
21725d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        addAction(new BitmapReflectionAction(viewId, methodName, value));
21739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2176d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * Call a method taking one Bundle on a view in the layout for this RemoteViews.
2177d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     *
217893dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
2179d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * @param methodName The name of the method to call.
2180d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     * @param value The value to pass to the method.
2181d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert     */
2182d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    public void setBundle(int viewId, String methodName, Bundle value) {
2183d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BUNDLE, value));
2184d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    }
2185d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert
2186d755b06805dd3ed4dc6c08ff1750e28543901854Bjorn Bringert    /**
218793dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * Call a method taking one Intent on a view in the layout for this RemoteViews.
2188499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     *
218993dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param viewId The id of the view on which to call the method.
219093dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param methodName The name of the method to call.
219193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main     * @param value The {@link android.content.Intent} to pass the method.
2192499cb9f516062b654952d282f211bee44c31a3c2Winson Chung     */
2193499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    public void setIntent(int viewId, String methodName, Intent value) {
2194499cb9f516062b654952d282f211bee44c31a3c2Winson Chung        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INTENT, value));
2195499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    }
2196499cb9f516062b654952d282f211bee44c31a3c2Winson Chung
2197499cb9f516062b654952d282f211bee44c31a3c2Winson Chung    /**
219833aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * Equivalent to calling View.setContentDescription(CharSequence).
2199e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov     *
220033aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param viewId The id of the view whose content description should change.
220133aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param contentDescription The new content description for the view.
2202e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov     */
2203e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    public void setContentDescription(int viewId, CharSequence contentDescription) {
2204e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov        setCharSequence(viewId, "setContentDescription", contentDescription);
2205e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    }
2206e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov
220733aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    /**
220833aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * Equivalent to calling View.setLabelFor(int).
220933aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     *
221033aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param viewId The id of the view whose property to set.
221133aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     * @param labeledId The id of a view for which this view serves as a label.
221233aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov     */
221333aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    public void setLabelFor(int viewId, int labeledId) {
221433aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov        setInt(viewId, "setLabelFor", labeledId);
221533aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov    }
221633aef98fd28dcac0a2ad37e7329afd3e666f5e0aSvetoslav Ganov
22175d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    private RemoteViews getRemoteViewsToApply(Context context) {
22185d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
22195d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int orientation = context.getResources().getConfiguration().orientation;
22205d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
22215d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mLandscape;
22225d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
22235d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                return mPortrait;
22245d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
22255d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
22265d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        return this;
22275d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen    }
22285d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
2229e261e283eaedd38235fc93b2a5c35758c613b10cSvetoslav Ganov    /**
22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Inflates the view hierarchy represented by this object and applies
22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * all of the actions.
2232e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><strong>Caller beware: this may throw</strong>
2234e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Default context to use
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent Parent that the resulting view hierarchy will be attached to. This method
22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * does <strong>not</strong> attach the hierarchy. The caller should do so when appropriate.
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The inflated view hierarchy
22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View apply(Context context, ViewGroup parent) {
2241e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller        return apply(context, parent, null);
22421927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn    }
22431927ae8a56a010919a7535231fa0f7db70f7e152Dianne Hackborn
2244a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    /** @hide */
2245a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    public View apply(Context context, ViewGroup parent, OnClickHandler handler) {
22465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        RemoteViews rvToApply = getRemoteViewsToApply(context);
22475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
2248a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        View result;
22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Context c = prepareContext(context);
22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2252a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        LayoutInflater inflater = (LayoutInflater)
2253a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy                c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inflater = inflater.cloneInContext(c);
22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        inflater.setFilter(this);
22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        result = inflater.inflate(rvToApply.getLayoutId(), parent, false);
22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2260a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        rvToApply.performApply(result, parent, handler);
22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Applies all of the actions to the provided view.
22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><strong>Caller beware: this may throw</strong>
2269e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param v The view to apply the actions to.  This should be the result of
22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #apply(Context,ViewGroup)} call.
22729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void reapply(Context context, View v) {
2274e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller        reapply(context, v, null);
2275a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    }
2276a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn
2277a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    /** @hide */
2278a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    public void reapply(Context context, View v, OnClickHandler handler) {
22795d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        RemoteViews rvToApply = getRemoteViewsToApply(context);
22805d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
22815d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // In the case that a view has this RemoteViews applied in one orientation, is persisted
22825d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // across orientation change, and has the RemoteViews re-applied in the new orientation,
22835d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        // we throw an exception, since the layouts may be completely unrelated.
22845d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (hasLandscapeAndPortraitLayouts()) {
22855d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (v.getId() != rvToApply.getLayoutId()) {
22865d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" +
22875d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                        " that does not share the same root layout id.");
22885d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
22895d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        }
22905d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        prepareContext(context);
2292a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn        rvToApply.performApply(v, (ViewGroup) v.getParent(), handler);
22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2295a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn    private void performApply(View v, ViewGroup parent, OnClickHandler handler) {
22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mActions != null) {
2297e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller            handler = handler == null ? DEFAULT_ON_CLICK_HANDLER : handler;
22989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int count = mActions.size();
22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Action a = mActions.get(i);
2301a19402165000e9513f3097e10df2b7ebc8dbe1d4Dianne Hackborn                a.apply(v, parent, handler);
23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context prepareContext(Context context) {
2307a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy        Context c;
23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String packageName = mPackage;
23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (packageName != null) {
23119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
2312870e09fcd2dfdc12ac318962efd28b0420c562bbRomain Guy                c = context.createPackageContext(packageName, Context.CONTEXT_RESTRICTED);
23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (NameNotFoundException e) {
23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.e(LOG_TAG, "Package name " + packageName + " not found");
23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c = context;
23169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c = context;
23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;
23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* (non-Javadoc)
23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used to restrict the views which can be inflated
2326e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller     *
23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.view.LayoutInflater.Filter#onLoadClass(java.lang.Class)
23289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2329e6ac8b9aade9443ab8456c8f7a47cdfba3b70266Gilles Debunne    public boolean onLoadClass(Class clazz) {
23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return clazz.isAnnotationPresent(RemoteView.class);
23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23325d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen
23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int describeContents() {
23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToParcel(Parcel dest, int flags) {
23385d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen        if (!hasLandscapeAndPortraitLayouts()) {
23395d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(MODE_NORMAL);
23405d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // We only write the bitmap cache if we are the root RemoteViews, as this cache
23415d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // is shared by all children.
23425d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
23435d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.writeBitmapsToParcel(dest, flags);
23445d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23455d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeString(mPackage);
23465d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(mLayoutId);
23475d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
23485d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            int count;
23495d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mActions != null) {
23505d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                count = mActions.size();
23515d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            } else {
23525d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                count = 0;
23535d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23545d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(count);
23555d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            for (int i=0; i<count; i++) {
23565d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                Action a = mActions.get(i);
23575d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                a.writeToParcel(dest, 0);
23585d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
23605d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            dest.writeInt(MODE_HAS_LANDSCAPE_AND_PORTRAIT);
23615d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // We only write the bitmap cache if we are the root RemoteViews, as this cache
23625d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            // is shared by all children.
23635d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            if (mIsRoot) {
23645d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen                mBitmapCache.writeBitmapsToParcel(dest, flags);
23655d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            }
23665d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mLandscape.writeToParcel(dest, flags);
23675d20064651b9947a4573c9a0eefec90f66eb1b59Adam Cohen            mPortrait.writeToParcel(dest, flags);
23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
23729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Parcelable.Creator that instantiates RemoteViews objects
23739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final Parcelable.Creator<RemoteViews> CREATOR = new Parcelable.Creator<RemoteViews>() {
23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public RemoteViews createFromParcel(Parcel parcel) {
23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new RemoteViews(parcel);
23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public RemoteViews[] newArray(int size) {
23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new RemoteViews[size];
23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2384