1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
19import android.content.Context;
20import android.os.Handler;
21import android.os.Looper;
22import android.os.Message;
23
24public class HandlerCaller {
25    private static final String TAG = "HandlerCaller";
26    private static final boolean DEBUG = false;
27
28    public final Context mContext;
29
30    final Looper mMainLooper;
31    final Handler mH;
32
33    final Callback mCallback;
34
35    public static class SomeArgs {
36        SomeArgs next;
37
38        public Object arg1;
39        public Object arg2;
40        public Object arg3;
41        public Object arg4;
42        public int argi1;
43        public int argi2;
44        public int argi3;
45        public int argi4;
46        public int argi5;
47        public int argi6;
48    }
49
50    static final int ARGS_POOL_MAX_SIZE = 10;
51    int mArgsPoolSize;
52    SomeArgs mArgsPool;
53
54    class MyHandler extends Handler {
55        MyHandler(Looper looper) {
56            super(looper);
57        }
58
59        @Override
60        public void handleMessage(Message msg) {
61            mCallback.executeMessage(msg);
62        }
63    }
64
65    public interface Callback {
66        public void executeMessage(Message msg);
67    }
68
69    public HandlerCaller(Context context, Callback callback) {
70        mContext = context;
71        mMainLooper = context.getMainLooper();
72        mH = new MyHandler(mMainLooper);
73        mCallback = callback;
74    }
75
76    public HandlerCaller(Context context, Looper looper, Callback callback) {
77        mContext = context;
78        mMainLooper = looper;
79        mH = new MyHandler(mMainLooper);
80        mCallback = callback;
81    }
82
83    public SomeArgs obtainArgs() {
84        synchronized (mH) {
85            SomeArgs args = mArgsPool;
86            if (args != null) {
87                mArgsPool = args.next;
88                args.next = null;
89                mArgsPoolSize--;
90                return args;
91            }
92        }
93        return new SomeArgs();
94    }
95
96    public void recycleArgs(SomeArgs args) {
97        synchronized (mH) {
98            if (mArgsPoolSize < ARGS_POOL_MAX_SIZE) {
99                args.next = mArgsPool;
100                mArgsPool = args;
101                mArgsPoolSize++;
102            }
103        }
104    }
105
106    public void executeOrSendMessage(Message msg) {
107        // If we are calling this from the main thread, then we can call
108        // right through.  Otherwise, we need to send the message to the
109        // main thread.
110        if (Looper.myLooper() == mMainLooper) {
111            mCallback.executeMessage(msg);
112            msg.recycle();
113            return;
114        }
115
116        mH.sendMessage(msg);
117    }
118
119    public boolean hasMessages(int what) {
120        return mH.hasMessages(what);
121    }
122
123    public void removeMessages(int what) {
124        mH.removeMessages(what);
125    }
126
127    public void removeMessages(int what, Object obj) {
128        mH.removeMessages(what, obj);
129    }
130
131    public void sendMessage(Message msg) {
132        mH.sendMessage(msg);
133    }
134
135    public Message obtainMessage(int what) {
136        return mH.obtainMessage(what);
137    }
138
139    public Message obtainMessageBO(int what, boolean arg1, Object arg2) {
140        return mH.obtainMessage(what, arg1 ? 1 : 0, 0, arg2);
141    }
142
143    public Message obtainMessageBOO(int what, boolean arg1, Object arg2, Object arg3) {
144        SomeArgs args = obtainArgs();
145        args.arg1 = arg2;
146        args.arg2 = arg3;
147        return mH.obtainMessage(what, arg1 ? 1 : 0, 0, args);
148    }
149
150    public Message obtainMessageO(int what, Object arg1) {
151        return mH.obtainMessage(what, 0, 0, arg1);
152    }
153
154    public Message obtainMessageI(int what, int arg1) {
155        return mH.obtainMessage(what, arg1, 0);
156    }
157
158    public Message obtainMessageII(int what, int arg1, int arg2) {
159        return mH.obtainMessage(what, arg1, arg2);
160    }
161
162    public Message obtainMessageIO(int what, int arg1, Object arg2) {
163        return mH.obtainMessage(what, arg1, 0, arg2);
164    }
165
166    public Message obtainMessageIIO(int what, int arg1, int arg2, Object arg3) {
167        return mH.obtainMessage(what, arg1, arg2, arg3);
168    }
169
170    public Message obtainMessageIIOO(int what, int arg1, int arg2,
171            Object arg3, Object arg4) {
172        SomeArgs args = obtainArgs();
173        args.arg1 = arg3;
174        args.arg2 = arg4;
175        return mH.obtainMessage(what, arg1, arg2, args);
176    }
177
178    public Message obtainMessageIOO(int what, int arg1, Object arg2, Object arg3) {
179        SomeArgs args = obtainArgs();
180        args.arg1 = arg2;
181        args.arg2 = arg3;
182        return mH.obtainMessage(what, arg1, 0, args);
183    }
184
185    public Message obtainMessageOO(int what, Object arg1, Object arg2) {
186        SomeArgs args = obtainArgs();
187        args.arg1 = arg1;
188        args.arg2 = arg2;
189        return mH.obtainMessage(what, 0, 0, args);
190    }
191
192    public Message obtainMessageOOO(int what, Object arg1, Object arg2, Object arg3) {
193        SomeArgs args = obtainArgs();
194        args.arg1 = arg1;
195        args.arg2 = arg2;
196        args.arg3 = arg3;
197        return mH.obtainMessage(what, 0, 0, args);
198    }
199
200    public Message obtainMessageOOOO(int what, Object arg1, Object arg2,
201            Object arg3, Object arg4) {
202        SomeArgs args = obtainArgs();
203        args.arg1 = arg1;
204        args.arg2 = arg2;
205        args.arg3 = arg3;
206        args.arg4 = arg4;
207        return mH.obtainMessage(what, 0, 0, args);
208    }
209
210    public Message obtainMessageIIII(int what, int arg1, int arg2,
211            int arg3, int arg4) {
212        SomeArgs args = obtainArgs();
213        args.argi1 = arg1;
214        args.argi2 = arg2;
215        args.argi3 = arg3;
216        args.argi4 = arg4;
217        return mH.obtainMessage(what, 0, 0, args);
218    }
219
220    public Message obtainMessageIIIIII(int what, int arg1, int arg2,
221            int arg3, int arg4, int arg5, int arg6) {
222        SomeArgs args = obtainArgs();
223        args.argi1 = arg1;
224        args.argi2 = arg2;
225        args.argi3 = arg3;
226        args.argi4 = arg4;
227        args.argi5 = arg5;
228        args.argi6 = arg6;
229        return mH.obtainMessage(what, 0, 0, args);
230    }
231
232    public Message obtainMessageIIIIO(int what, int arg1, int arg2,
233            int arg3, int arg4, Object arg5) {
234        SomeArgs args = obtainArgs();
235        args.arg1 = arg5;
236        args.argi1 = arg1;
237        args.argi2 = arg2;
238        args.argi3 = arg3;
239        args.argi4 = arg4;
240        return mH.obtainMessage(what, 0, 0, args);
241    }
242}
243