AsyncChannel.java revision 583eaaa57c51b28bf14da2a5cc94a2e6091cccf5
1d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville/**
2d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * Copyright (C) 2010 The Android Open Source Project
3d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville *
4d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * you may not use this file except in compliance with the License.
6d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * You may obtain a copy of the License at
7d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville *
8d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville *
10d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * Unless required by applicable law or agreed to in writing, software
11d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * See the License for the specific language governing permissions and
14d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * limitations under the License.
15d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville */
16d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
17d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savillepackage com.android.internal.util;
18d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
19d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.content.ComponentName;
20d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.content.Context;
21d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.content.Intent;
22d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.content.ServiceConnection;
23d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.os.Handler;
24d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.os.HandlerThread;
25d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.os.IBinder;
26d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.os.Looper;
27d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.os.Message;
28d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.os.Messenger;
29d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.os.RemoteException;
30d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport android.util.Slog;
31d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
32d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savilleimport java.util.Stack;
33d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
34d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville/**
3533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>An asynchronous channel between two handlers.</p>
36d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville *
3733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>The handlers maybe in the same process or in another process. There
38d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * are two protocol styles that can be used with an AysncChannel. The
39d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * first is a simple request/reply protocol where the server does
4033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * not need to know which client is issuing the request.</p>
41d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville *
4233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>In a simple request/reply protocol the client/source sends requests to the
43d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * server/destination. And the server uses the replyToMessage methods.
44d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * In this usage model there is no need for the destination to
4533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * use the connect methods. The typical sequence of operations is:</p>
4633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *<ol>
470246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *   <li>Client calls AsyncChannel#connectSync or Asynchronously:</li>
480246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *      <ol>For an asynchronous half connection client calls AsyncChannel#connect.</ol>
490246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *          <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
500246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *      </ol>
5133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li><code>comm-loop:</code></li>
520246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *   <li>Client calls AsyncChannel#sendMessage</li>
530246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *   <li>Server processes messages and optionally replies using AsyncChannel#replyToMessage
5433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li>Loop to <code>comm-loop</code> until done</li>
550246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *   <li>When done Client calls {@link AsyncChannel#disconnect}</li>
560246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *   <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
5733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *</ol>
5833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *<br/>
5933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>A second usage model is where the server/destination needs to know
60d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * which client it's connected too. For example the server needs to
61d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * send unsolicited messages back to the client. Or the server keeps
62d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville * different state for each client. In this model the server will also
6333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * use the connect methods. The typical sequence of operation is:</p>
6433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *<ol>
650246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *   <li>Client calls AsyncChannel#fullyConnectSync or Asynchronously:<li>
660246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *      <ol>For an asynchronous full connection it calls AsyncChannel#connect</li>
670246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *          <li>Client receives CMD_CHANNEL_HALF_CONNECTED from AsyncChannel</li>
680246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *          <li>Client calls AsyncChannel#sendMessage(CMD_CHANNEL_FULL_CONNECTION)</li>
690246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *      </ol>
7033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li>Server receives CMD_CHANNEL_FULL_CONNECTION</li>
710246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *   <li>Server calls AsyncChannel#connected</li>
7233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li>Server sends AsyncChannel#sendMessage(CMD_CHANNEL_FULLY_CONNECTED)</li>
7333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li>Client receives CMD_CHANNEL_FULLY_CONNECTED</li>
7433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li><code>comm-loop:</code></li>
7533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li>Client/Server uses AsyncChannel#sendMessage/replyToMessage
7633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *       to communicate and perform work</li>
7733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li>Loop to <code>comm-loop</code> until done</li>
780246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *   <li>When done Client/Server calls {@link AsyncChannel#disconnect}</li>
7933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *   <li>Client/Server receives CMD_CHANNEL_DISCONNECTED from AsyncChannel</li>
8033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville *</ol>
810246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville *
820246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville * TODO: Consider simplifying where we have connect and fullyConnect with only one response
830246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville * message RSP_CHANNEL_CONNECT instead of two, CMD_CHANNEL_HALF_CONNECTED and
840246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville * CMD_CHANNEL_FULLY_CONNECTED. We'd also change CMD_CHANNEL_FULL_CONNECTION to REQ_CHANNEL_CONNECT.
85d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville */
86d20a5d6b5a821e28d73eba6502a2135134014a84Wink Savillepublic class AsyncChannel {
87d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Log tag */
88d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private static final String TAG = "AsyncChannel";
89d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
90d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Enable to turn on debugging */
91d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private static final boolean DBG = false;
92d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
930246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    private static final int BASE = Protocol.BASE_SYSTEM_ASYNC_CHANNEL;
940246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
95d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
96d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Command sent when the channel is half connected. Half connected
97d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * means that the channel can be used to send commends to the destination
98d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * but the destination is unaware that the channel exists. The first
99d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * command sent to the destination is typically CMD_CHANNEL_FULL_CONNECTION if
100d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * it is desired to establish a long term connection, but any command maybe
101d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * sent.
102d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
103d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * msg.arg1 == 0 : STATUS_SUCCESSFUL
104d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *             1 : STATUS_BINDING_UNSUCCESSFUL
105cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville     * msg.obj  == the AsyncChannel
106d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * msg.replyTo == dstMessenger if successful
107d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
1080246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public static final int CMD_CHANNEL_HALF_CONNECTED = BASE + 0;
109d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
110d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
111d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Command typically sent when after receiving the CMD_CHANNEL_HALF_CONNECTED.
112d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * This is used to initiate a long term connection with the destination and
113d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * typically the destination will reply with CMD_CHANNEL_FULLY_CONNECTED.
114d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
115d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * msg.replyTo = srcMessenger.
116d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
1170246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public static final int CMD_CHANNEL_FULL_CONNECTION = BASE + 1;
118d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
119d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
120d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Command typically sent after the destination receives a CMD_CHANNEL_FULL_CONNECTION.
121d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * This signifies the acceptance or rejection of the channel by the sender.
122d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
123d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * msg.arg1 == 0 : Accept connection
124d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *               : All other values signify the destination rejected the connection
1250246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *                 and {@link AsyncChannel#disconnect} would typically be called.
126d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
1270246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public static final int CMD_CHANNEL_FULLY_CONNECTED = BASE + 2;
128d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
129d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
130d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Command sent when one side or the other wishes to disconnect. The sender
131d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * may or may not be able to receive a reply depending upon the protocol and
1320246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * the state of the connection. The receiver should call {@link AsyncChannel#disconnect}
133d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * to close its side of the channel and it will receive a CMD_CHANNEL_DISCONNECTED
134d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * when the channel is closed.
135d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
136d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * msg.replyTo = messenger that is disconnecting
137d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
1380246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public static final int CMD_CHANNEL_DISCONNECT = BASE + 3;
139d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
140d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
141d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Command sent when the channel becomes disconnected. This is sent when the
142d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * channel is forcibly disconnected by the system or as a reply to CMD_CHANNEL_DISCONNECT.
143d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
144d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * msg.arg1 == 0 : STATUS_SUCCESSFUL
1450246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *             1 : STATUS_BINDING_UNSUCCESSFUL
1460246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *             2 : STATUS_SEND_UNSUCCESSFUL
147d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *               : All other values signify failure and the channel state is indeterminate
148cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville     * msg.obj  == the AsyncChannel
149d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * msg.replyTo = messenger disconnecting or null if it was never connected.
150d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
1510246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public static final int CMD_CHANNEL_DISCONNECTED = BASE + 4;
152d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
153583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    private static final int CMD_TO_STRING_COUNT = CMD_CHANNEL_DISCONNECTED + 1;
154583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
155583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    static {
156583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        sCmdToString[CMD_CHANNEL_HALF_CONNECTED - BASE] = "CMD_CHANNEL_HALF_CONNECTED";
157583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        sCmdToString[CMD_CHANNEL_FULL_CONNECTION - BASE] = "CMD_CHANNEL_FULL_CONNECTION";
158583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        sCmdToString[CMD_CHANNEL_FULLY_CONNECTED - BASE] = "CMD_CHANNEL_FULLY_CONNECTED";
159583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        sCmdToString[CMD_CHANNEL_DISCONNECT - BASE] = "CMD_CHANNEL_DISCONNECT";
160583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        sCmdToString[CMD_CHANNEL_DISCONNECTED - BASE] = "CMD_CHANNEL_DISCONNECTED";
161583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    }
162583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    protected static String cmdToString(int cmd) {
163583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        cmd -= BASE;
164583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        if ((cmd >= 0) && (cmd < sCmdToString.length)) {
165583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            return sCmdToString[cmd];
166583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        } else {
167583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            return null;
168583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        }
169583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    }
170583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville
171d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Successful status always 0, !0 is an unsuccessful status */
172d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public static final int STATUS_SUCCESSFUL = 0;
173d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
174d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Error attempting to bind on a connect */
175d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public static final int STATUS_BINDING_UNSUCCESSFUL = 1;
176d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
1770246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    /** Error attempting to send a message */
1780246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public static final int STATUS_SEND_UNSUCCESSFUL = 2;
1790246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
1800246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    /** CMD_FULLY_CONNECTED refused because a connection already exists*/
1810246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public static final int STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED = 3;
1820246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
183d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Service connection */
184d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private AsyncChannelConnection mConnection;
185d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
186d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Context for source */
187d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private Context mSrcContext;
188d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
189d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Handler for source */
190d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private Handler mSrcHandler;
191d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
192d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Messenger for source */
193d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private Messenger mSrcMessenger;
194d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
195d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /** Messenger for destination */
196d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private Messenger mDstMessenger;
197d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
198d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
199d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * AsyncChannel constructor
200d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
201d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public AsyncChannel() {
202d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
203d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
204d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
2050246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * Connect handler to named package/class synchronously.
206d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
207d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcContext is the context of the source
208d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
209d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *            messages
210d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param dstPackageName is the destination package name
211d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param dstClassName is the fully qualified class name (i.e. contains
212d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *            package name)
2130246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
2140246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @return STATUS_SUCCESSFUL on success any other value is an error.
215d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
2160246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public int connectSrcHandlerToPackageSync(
217cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville            Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) {
218d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        if (DBG) log("connect srcHandler to dst Package & class E");
219d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
220cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville        mConnection = new AsyncChannelConnection();
221d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
222d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /* Initialize the source information */
223d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcContext = srcContext;
224d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcHandler = srcHandler;
225d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcMessenger = new Messenger(srcHandler);
226d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
227d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /*
228d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         * Initialize destination information to null they will
229d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         * be initialized when the AsyncChannelConnection#onServiceConnected
230d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         * is called
231d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         */
232d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mDstMessenger = null;
233d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
234d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /* Send intent to create the connection */
235d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Intent intent = new Intent(Intent.ACTION_MAIN);
236d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        intent.setClassName(dstPackageName, dstClassName);
237d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        boolean result = srcContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
238d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        if (DBG) log("connect srcHandler to dst Package & class X result=" + result);
2390246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        return result ? STATUS_SUCCESSFUL : STATUS_BINDING_UNSUCCESSFUL;
2400246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    }
2410246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
2420246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    /**
2430246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * Connect a handler to Messenger synchronously.
2440246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
2450246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param srcContext is the context of the source
2460246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
2470246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *            messages
2480246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param dstMessenger is the hander to send messages to.
2490246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
2500246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @return STATUS_SUCCESSFUL on success any other value is an error.
2510246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     */
2520246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public int connectSync(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
2530246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        if (DBG) log("halfConnectSync srcHandler to the dstMessenger  E");
2540246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
2550246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        // We are connected
2560246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        connected(srcContext, srcHandler, dstMessenger);
2570246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
2580246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        if (DBG) log("halfConnectSync srcHandler to the dstMessenger X");
2590246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        return STATUS_SUCCESSFUL;
2600246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    }
2610246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
2620246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    /**
2630246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * connect two local Handlers synchronously.
2640246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
2650246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param srcContext is the context of the source
2660246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
2670246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *            messages
2680246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param dstHandler is the hander to send messages to.
2690246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
2700246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @return STATUS_SUCCESSFUL on success any other value is an error.
2710246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     */
2720246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public int connectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {
2730246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        return connectSync(srcContext, srcHandler, new Messenger(dstHandler));
2740246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    }
2750246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
2760246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    /**
2770246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * Fully connect two local Handlers synchronously.
2780246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
2790246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param srcContext is the context of the source
2800246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
2810246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *            messages
2820246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param dstHandler is the hander to send messages to.
2830246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
2840246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @return STATUS_SUCCESSFUL on success any other value is an error.
2850246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     */
2860246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public int fullyConnectSync(Context srcContext, Handler srcHandler, Handler dstHandler) {
2870246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        int status = connectSync(srcContext, srcHandler, dstHandler);
2880246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        if (status == STATUS_SUCCESSFUL) {
2890246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville            Message response = sendMessageSynchronously(CMD_CHANNEL_FULL_CONNECTION);
2900246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville            status = response.arg1;
2910246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        }
2920246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        return status;
293d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
294d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
295d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
296d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Connect handler to named package/class.
297d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
298d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
299d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *      msg.arg1 = status
300cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville     *      msg.obj = the AsyncChannel
301d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
302d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcContext is the context of the source
303d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
304d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *            messages
305d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param dstPackageName is the destination package name
306d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param dstClassName is the fully qualified class name (i.e. contains
307d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *            package name)
308d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
309d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void connect(Context srcContext, Handler srcHandler, String dstPackageName,
310cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville            String dstClassName) {
311d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        if (DBG) log("connect srcHandler to dst Package & class E");
312d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
313d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        final class ConnectAsync implements Runnable {
314d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            Context mSrcCtx;
315d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            Handler mSrcHdlr;
316d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            String mDstPackageName;
317d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            String mDstClassName;
318d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
319d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            ConnectAsync(Context srcContext, Handler srcHandler, String dstPackageName,
320cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville                    String dstClassName) {
321d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                mSrcCtx = srcContext;
322d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                mSrcHdlr = srcHandler;
323d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                mDstPackageName = dstPackageName;
324d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                mDstClassName = dstClassName;
325d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            }
326d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
3270246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville            @Override
328d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            public void run() {
3290246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                int result = connectSrcHandlerToPackageSync(mSrcCtx, mSrcHdlr, mDstPackageName,
3300246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                        mDstClassName);
3310246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                replyHalfConnected(result);
332d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            }
333d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
334d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
335cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville        ConnectAsync ca = new ConnectAsync(srcContext, srcHandler, dstPackageName, dstClassName);
336d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        new Thread(ca).start();
337d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
338d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        if (DBG) log("connect srcHandler to dst Package & class X");
339d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
340d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
341d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
342d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Connect handler to a class
343d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
344d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
345d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *      msg.arg1 = status
346cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville     *      msg.obj = the AsyncChannel
347d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
348d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcContext
349d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcHandler
350d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param klass is the class to send messages to.
351d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
352cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville    public void connect(Context srcContext, Handler srcHandler, Class<?> klass) {
353cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville        connect(srcContext, srcHandler, klass.getPackage().getName(), klass.getName());
354d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
355d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
356d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
357d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Connect handler and messenger.
358d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
359d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
360d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *      msg.arg1 = status
361cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville     *      msg.obj = the AsyncChannel
362d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
363d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcContext
364d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcHandler
365d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param dstMessenger
366d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
367cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville    public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
368d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        if (DBG) log("connect srcHandler to the dstMessenger  E");
369d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
3700246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        // We are connected
3710246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        connected(srcContext, srcHandler, dstMessenger);
3720246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
3730246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        // Tell source we are half connected
3740246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        replyHalfConnected(STATUS_SUCCESSFUL);
3750246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
3760246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        if (DBG) log("connect srcHandler to the dstMessenger X");
3770246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    }
3780246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
3790246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    /**
3800246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * Connect handler to messenger. This method is typically called
3810246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * when a server receives a CMD_CHANNEL_FULL_CONNECTION request
3820246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * and initializes the internal instance variables to allow communication
3830246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * with the dstMessenger.
3840246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
3850246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param srcContext
3860246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param srcHandler
3870246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param dstMessenger
3880246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     */
3890246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
3900246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        if (DBG) log("connected srcHandler to the dstMessenger  E");
3910246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
392d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        // Initialize source fields
393d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcContext = srcContext;
394d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcHandler = srcHandler;
395d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcMessenger = new Messenger(mSrcHandler);
396d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
397d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        // Initialize destination fields
398d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mDstMessenger = dstMessenger;
399d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
4000246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        if (DBG) log("connected srcHandler to the dstMessenger X");
401d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
402d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
403d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
404d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Connect two local Handlers.
405d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
406d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcContext is the context of the source
407d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
408d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *            messages
409d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param dstHandler is the hander to send messages to.
410d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
411cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville    public void connect(Context srcContext, Handler srcHandler, Handler dstHandler) {
412cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville        connect(srcContext, srcHandler, new Messenger(dstHandler));
413d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
414d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
415d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
416d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Connect service and messenger.
417d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
418d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Sends a CMD_CHANNEL_HALF_CONNECTED message to srcAsyncService when complete.
419d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *      msg.arg1 = status
420cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville     *      msg.obj = the AsyncChannel
421d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
422d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcAsyncService
423d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param dstMessenger
424d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
425cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville    public void connect(AsyncService srcAsyncService, Messenger dstMessenger) {
426cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville        connect(srcAsyncService, srcAsyncService.getHandler(), dstMessenger);
427d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
428d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
429d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
430d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * To close the connection call when handler receives CMD_CHANNEL_DISCONNECTED
431d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
432d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void disconnected() {
4330246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        mSrcContext = null;
434d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcHandler = null;
435d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcMessenger = null;
436d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mDstMessenger = null;
437d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mConnection = null;
438d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
439d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
440d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
441d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Disconnect
442d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
443cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville    public void disconnect() {
4440246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        if ((mConnection != null) && (mSrcContext != null)) {
445d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            mSrcContext.unbindService(mConnection);
446d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
447d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        if (mSrcHandler != null) {
4480246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville            replyDisconnected(STATUS_SUCCESSFUL);
449d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
450d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
451d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
452d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
453d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send a message to the destination handler.
454d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
455d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param msg
456d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
457d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void sendMessage(Message msg) {
458d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.replyTo = mSrcMessenger;
459d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        try {
460d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            mDstMessenger.send(msg);
461d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        } catch (RemoteException e) {
4620246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville            replyDisconnected(STATUS_SEND_UNSUCCESSFUL);
463d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
464d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
465d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
466d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
467d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send a message to the destination handler
468d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
469d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
470d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
471d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void sendMessage(int what) {
472d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
473d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
474d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        sendMessage(msg);
475d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
476d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
477d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
478d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send a message to the destination handler
479d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
480d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
481d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
482d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
483d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void sendMessage(int what, int arg1) {
484d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
485d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
486d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
487d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        sendMessage(msg);
488d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
489d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
490d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
491d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send a message to the destination handler
492d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
493d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
494d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
495d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg2
496d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
497d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void sendMessage(int what, int arg1, int arg2) {
498d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
499d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
500d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
501d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg2 = arg2;
502d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        sendMessage(msg);
503d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
504d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
505d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
506d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send a message to the destination handler
507d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
508d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
509d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
510d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg2
511d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param obj
512d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
513d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void sendMessage(int what, int arg1, int arg2, Object obj) {
514d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
515d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
516d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
517d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg2 = arg2;
518d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.obj = obj;
519d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        sendMessage(msg);
520d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
521d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
522d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
523d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send a message to the destination handler
524d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
525d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
526d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param obj
527d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
528d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void sendMessage(int what, Object obj) {
529d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
530d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
531d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.obj = obj;
532d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        sendMessage(msg);
533d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
534d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
535d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
536d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Reply to srcMsg sending dstMsg
537d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
538d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcMsg
539d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param dstMsg
540d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
541d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void replyToMessage(Message srcMsg, Message dstMsg) {
542d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        try {
5430246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville            dstMsg.replyTo = mSrcMessenger;
544d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            srcMsg.replyTo.send(dstMsg);
545d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        } catch (RemoteException e) {
546d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            log("TODO: handle replyToMessage RemoteException" + e);
547d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            e.printStackTrace();
548d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
549d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
550d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
551d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
552d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Reply to srcMsg
553d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
554d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcMsg
555d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
556d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
557d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void replyToMessage(Message srcMsg, int what) {
558d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
559d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
560d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        replyToMessage(srcMsg, msg);
561d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
562d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
563d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
564d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Reply to srcMsg
565d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
566d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcMsg
567d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
568d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
569d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
570d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void replyToMessage(Message srcMsg, int what, int arg1) {
571d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
572d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
573d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
574d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        replyToMessage(srcMsg, msg);
575d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
576d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
577d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
578d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Reply to srcMsg
579d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
580d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcMsg
581d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
582d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
583d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg2
584d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
585d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void replyToMessage(Message srcMsg, int what, int arg1, int arg2) {
586d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
587d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
588d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
589d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg2 = arg2;
590d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        replyToMessage(srcMsg, msg);
591d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
592d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
593d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
594d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Reply to srcMsg
595d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
596d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcMsg
597d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
598d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
599d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg2
600d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param obj
601d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
602d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void replyToMessage(Message srcMsg, int what, int arg1, int arg2, Object obj) {
603d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
604d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
605d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
606d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg2 = arg2;
607d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.obj = obj;
608d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        replyToMessage(srcMsg, msg);
609d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
610d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
611d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
612d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Reply to srcMsg
613d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
614d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param srcMsg
615d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
616d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param obj
617d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
618d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public void replyToMessage(Message srcMsg, int what, Object obj) {
619d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
620d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
621d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.obj = obj;
622d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        replyToMessage(srcMsg, msg);
623d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
624d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
625d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
626d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send the Message synchronously.
627d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
628d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param msg to send
629d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @return reply message or null if an error.
630d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
631d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public Message sendMessageSynchronously(Message msg) {
632d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message resultMsg = SyncMessenger.sendMessageSynchronously(mDstMessenger, msg);
633d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        return resultMsg;
634d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
635d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
636d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
637d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send the Message synchronously.
638d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
639d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
640d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @return reply message or null if an error.
641d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
642d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public Message sendMessageSynchronously(int what) {
643d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
644d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
645d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message resultMsg = sendMessageSynchronously(msg);
646d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        return resultMsg;
647d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
648d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
649d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
650d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send the Message synchronously.
651d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
652d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
653d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
654d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @return reply message or null if an error.
655d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
656d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public Message sendMessageSynchronously(int what, int arg1) {
657d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
658d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
659d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
660d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message resultMsg = sendMessageSynchronously(msg);
661d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        return resultMsg;
662d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
663d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
664d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
665d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send the Message synchronously.
666d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
667d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
668d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
669d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg2
670d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @return reply message or null if an error.
671d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
672d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public Message sendMessageSynchronously(int what, int arg1, int arg2) {
673d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
674d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
675d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
676d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg2 = arg2;
677d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message resultMsg = sendMessageSynchronously(msg);
678d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        return resultMsg;
679d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
680d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
681d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
682d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send the Message synchronously.
683d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
684d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
685d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg1
686d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param arg2
687d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param obj
688d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @return reply message or null if an error.
689d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
690d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public Message sendMessageSynchronously(int what, int arg1, int arg2, Object obj) {
691d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
692d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
693d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = arg1;
694d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg2 = arg2;
695d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.obj = obj;
696d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message resultMsg = sendMessageSynchronously(msg);
697d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        return resultMsg;
698d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
699d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
700d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
701d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Send the Message synchronously.
702d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
703d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param what
704d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param obj
705d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @return reply message or null if an error.
706d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
707d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    public Message sendMessageSynchronously(int what, Object obj) {
708d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = Message.obtain();
709d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.what = what;
710d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.obj = obj;
711d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message resultMsg = sendMessageSynchronously(msg);
712d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        return resultMsg;
713d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
714d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
715d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
716d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Helper class to send messages synchronously
717d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
718d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private static class SyncMessenger {
719d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /** A stack of SyncMessengers */
720d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private static Stack<SyncMessenger> sStack = new Stack<SyncMessenger>();
721d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /** A number of SyncMessengers created */
722d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private static int sCount = 0;
723d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /** The handler thread */
724d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private HandlerThread mHandlerThread;
725d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /** The handler that will receive the result */
726d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private SyncHandler mHandler;
727d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /** The messenger used to send the message */
728d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private Messenger mMessenger;
729d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
730d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /** private constructor */
731d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private SyncMessenger() {
732d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
733d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
734d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /** Synchronous Handler class */
735d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private class SyncHandler extends Handler {
736d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            /** The object used to wait/notify */
737d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            private Object mLockObject = new Object();
738d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            /** The resulting message */
739d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            private Message mResultMsg;
740d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
741d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            /** Constructor */
742d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            private SyncHandler(Looper looper) {
743d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                super(looper);
744d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            }
745d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
746d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            /** Handle of the reply message */
747d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            @Override
748d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            public void handleMessage(Message msg) {
749d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                mResultMsg = Message.obtain();
750d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                mResultMsg.copyFrom(msg);
751d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                synchronized(mLockObject) {
752d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                    mLockObject.notify();
753d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                }
754d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            }
755d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
756d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
757d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /**
758d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         * @return the SyncMessenger
759d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         */
760d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private static SyncMessenger obtain() {
761d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            SyncMessenger sm;
762d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            synchronized (sStack) {
763d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                if (sStack.isEmpty()) {
764d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                    sm = new SyncMessenger();
765d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                    sm.mHandlerThread = new HandlerThread("SyncHandler-" + sCount++);
766d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                    sm.mHandlerThread.start();
767d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                    sm.mHandler = sm.new SyncHandler(sm.mHandlerThread.getLooper());
768d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                    sm.mMessenger = new Messenger(sm.mHandler);
769d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                } else {
770d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                    sm = sStack.pop();
771d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                }
772d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            }
773d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            return sm;
774d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
775d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
776d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /**
777d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         * Recycle this object
778d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         */
779d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private void recycle() {
780d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            synchronized (sStack) {
781d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                sStack.push(this);
782d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            }
783d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
784d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
785d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        /**
786d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         * Send a message synchronously.
787d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         *
788d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         * @param msg to send
789d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         * @return result message or null if an error occurs
790d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville         */
791d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        private static Message sendMessageSynchronously(Messenger dstMessenger, Message msg) {
792d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            SyncMessenger sm = SyncMessenger.obtain();
793d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            try {
7940246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                if (dstMessenger != null && msg != null) {
7950246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                    msg.replyTo = sm.mMessenger;
7960246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                    synchronized (sm.mHandler.mLockObject) {
7970246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                        dstMessenger.send(msg);
7980246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                        sm.mHandler.mLockObject.wait();
7990246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                    }
8000246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                } else {
8010246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville                    sm.mHandler.mResultMsg = null;
802d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                }
803d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            } catch (InterruptedException e) {
804d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                sm.mHandler.mResultMsg = null;
805d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            } catch (RemoteException e) {
806d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville                sm.mHandler.mResultMsg = null;
807d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            }
808d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            Message resultMsg = sm.mHandler.mResultMsg;
809d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            sm.recycle();
810d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            return resultMsg;
811d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
812d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
813d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
814d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
815d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Reply to the src handler that we're half connected.
8160246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * see: CMD_CHANNEL_HALF_CONNECTED for message contents
817d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
818d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param status to be stored in msg.arg1
819d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
820cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville    private void replyHalfConnected(int status) {
821d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_HALF_CONNECTED);
822d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.arg1 = status;
823cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville        msg.obj = this;
824d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        msg.replyTo = mDstMessenger;
825d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        mSrcHandler.sendMessage(msg);
826d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
827d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
828d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
8290246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * Reply to the src handler that we are disconnected
8300246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * see: CMD_CHANNEL_DISCONNECTED for message contents
8310246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     *
8320246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     * @param status to be stored in msg.arg1
8330246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville     */
8340246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    private void replyDisconnected(int status) {
8350246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
8360246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        msg.arg1 = status;
8370246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        msg.obj = this;
8380246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        msg.replyTo = mDstMessenger;
8390246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        mSrcHandler.sendMessage(msg);
8400246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    }
8410246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
8420246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville
8430246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville    /**
844d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * ServiceConnection to receive call backs.
845d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
846d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    class AsyncChannelConnection implements ServiceConnection {
847cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville        AsyncChannelConnection() {
848d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
849d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
8500246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        @Override
851d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        public void onServiceConnected(ComponentName className, IBinder service) {
852d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville            mDstMessenger = new Messenger(service);
853cfce303cbdd59a3883957e4bc96a0476ceeb86acWink Saville            replyHalfConnected(STATUS_SUCCESSFUL);
854d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
855d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
8560246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville        @Override
857d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        public void onServiceDisconnected(ComponentName className) {
8580246bbc8d7b646a2344d04d5af41580fa9e17a98Wink Saville            replyDisconnected(STATUS_SUCCESSFUL);
859d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        }
860d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
861d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville
862d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    /**
863d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * Log the string.
864d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     *
865d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     * @param s
866d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville     */
867d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    private static void log(String s) {
868d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville        Slog.d(TAG, s);
869d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville    }
870d20a5d6b5a821e28d73eba6502a2135134014a84Wink Saville}
871