CommonTimeUtils.java revision 34385d352da19805ae948215e2edbeedd16b7941
1/*
2 * Copyright (C) 2012 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 */
16package android.os;
17
18import java.net.InetAddress;
19import java.net.Inet4Address;
20import java.net.Inet6Address;
21import java.net.InetSocketAddress;
22import java.util.Locale;
23import static android.system.OsConstants.*;
24
25class CommonTimeUtils {
26    /**
27     * Successful operation.
28     */
29    public static final int SUCCESS = 0;
30    /**
31     * Unspecified error.
32     */
33    public static final int ERROR = -1;
34    /**
35     * Operation failed due to bad parameter value.
36     */
37    public static final int ERROR_BAD_VALUE = -4;
38    /**
39     * Operation failed due to dead remote object.
40     */
41    public static final int ERROR_DEAD_OBJECT = -7;
42
43    public CommonTimeUtils(IBinder remote, String interfaceDesc) {
44        mRemote = remote;
45        mInterfaceDesc = interfaceDesc;
46    }
47
48    public int transactGetInt(int method_code, int error_ret_val)
49    throws RemoteException {
50        android.os.Parcel data  = android.os.Parcel.obtain();
51        android.os.Parcel reply = android.os.Parcel.obtain();
52        int ret_val;
53
54        try {
55            int res;
56            data.writeInterfaceToken(mInterfaceDesc);
57            mRemote.transact(method_code, data, reply, 0);
58
59            res = reply.readInt();
60            ret_val = (0 == res) ? reply.readInt() : error_ret_val;
61        }
62        finally {
63            reply.recycle();
64            data.recycle();
65        }
66
67        return ret_val;
68    }
69
70    public int transactSetInt(int method_code, int val) {
71        android.os.Parcel data  = android.os.Parcel.obtain();
72        android.os.Parcel reply = android.os.Parcel.obtain();
73
74        try {
75            data.writeInterfaceToken(mInterfaceDesc);
76            data.writeInt(val);
77            mRemote.transact(method_code, data, reply, 0);
78
79            return reply.readInt();
80        }
81        catch (RemoteException e) {
82            return ERROR_DEAD_OBJECT;
83        }
84        finally {
85            reply.recycle();
86            data.recycle();
87        }
88    }
89
90    public long transactGetLong(int method_code, long error_ret_val)
91    throws RemoteException {
92        android.os.Parcel data  = android.os.Parcel.obtain();
93        android.os.Parcel reply = android.os.Parcel.obtain();
94        long ret_val;
95
96        try {
97            int res;
98            data.writeInterfaceToken(mInterfaceDesc);
99            mRemote.transact(method_code, data, reply, 0);
100
101            res = reply.readInt();
102            ret_val = (0 == res) ? reply.readLong() : error_ret_val;
103        }
104        finally {
105            reply.recycle();
106            data.recycle();
107        }
108
109        return ret_val;
110    }
111
112    public int transactSetLong(int method_code, long val) {
113        android.os.Parcel data  = android.os.Parcel.obtain();
114        android.os.Parcel reply = android.os.Parcel.obtain();
115
116        try {
117            data.writeInterfaceToken(mInterfaceDesc);
118            data.writeLong(val);
119            mRemote.transact(method_code, data, reply, 0);
120
121            return reply.readInt();
122        }
123        catch (RemoteException e) {
124            return ERROR_DEAD_OBJECT;
125        }
126        finally {
127            reply.recycle();
128            data.recycle();
129        }
130    }
131
132    public String transactGetString(int method_code, String error_ret_val)
133    throws RemoteException {
134        android.os.Parcel data  = android.os.Parcel.obtain();
135        android.os.Parcel reply = android.os.Parcel.obtain();
136        String ret_val;
137
138        try {
139            int res;
140            data.writeInterfaceToken(mInterfaceDesc);
141            mRemote.transact(method_code, data, reply, 0);
142
143            res = reply.readInt();
144            ret_val = (0 == res) ? reply.readString() : error_ret_val;
145        }
146        finally {
147            reply.recycle();
148            data.recycle();
149        }
150
151        return ret_val;
152    }
153
154    public int transactSetString(int method_code, String val) {
155        android.os.Parcel data  = android.os.Parcel.obtain();
156        android.os.Parcel reply = android.os.Parcel.obtain();
157
158        try {
159            data.writeInterfaceToken(mInterfaceDesc);
160            data.writeString(val);
161            mRemote.transact(method_code, data, reply, 0);
162
163            return reply.readInt();
164        }
165        catch (RemoteException e) {
166            return ERROR_DEAD_OBJECT;
167        }
168        finally {
169            reply.recycle();
170            data.recycle();
171        }
172    }
173
174    public InetSocketAddress transactGetSockaddr(int method_code)
175    throws RemoteException {
176        android.os.Parcel data  = android.os.Parcel.obtain();
177        android.os.Parcel reply = android.os.Parcel.obtain();
178        InetSocketAddress ret_val = null;
179
180        try {
181            int res;
182            data.writeInterfaceToken(mInterfaceDesc);
183            mRemote.transact(method_code, data, reply, 0);
184
185            res = reply.readInt();
186            if (0 == res) {
187                int type;
188                int port = 0;
189                String addrStr = null;
190
191                type = reply.readInt();
192
193                if (AF_INET == type) {
194                    int addr = reply.readInt();
195                    port = reply.readInt();
196                    addrStr = String.format(Locale.US, "%d.%d.%d.%d",
197                                                       (addr >> 24) & 0xFF,
198                                                       (addr >> 16) & 0xFF,
199                                                       (addr >>  8) & 0xFF,
200                                                        addr        & 0xFF);
201                } else if (AF_INET6 == type) {
202                    int addr1 = reply.readInt();
203                    int addr2 = reply.readInt();
204                    int addr3 = reply.readInt();
205                    int addr4 = reply.readInt();
206
207                    port = reply.readInt();
208
209                    int flowinfo = reply.readInt();
210                    int scope_id = reply.readInt();
211
212                    addrStr = String.format(Locale.US, "[%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X]",
213                                                       (addr1 >> 16) & 0xFFFF, addr1 & 0xFFFF,
214                                                       (addr2 >> 16) & 0xFFFF, addr2 & 0xFFFF,
215                                                       (addr3 >> 16) & 0xFFFF, addr3 & 0xFFFF,
216                                                       (addr4 >> 16) & 0xFFFF, addr4 & 0xFFFF);
217                }
218
219                if (null != addrStr) {
220                    ret_val = new InetSocketAddress(addrStr, port);
221                }
222            }
223        }
224        finally {
225            reply.recycle();
226            data.recycle();
227        }
228
229        return ret_val;
230    }
231
232    public int transactSetSockaddr(int method_code, InetSocketAddress addr) {
233        android.os.Parcel data  = android.os.Parcel.obtain();
234        android.os.Parcel reply = android.os.Parcel.obtain();
235        int ret_val = ERROR;
236
237        try {
238            data.writeInterfaceToken(mInterfaceDesc);
239
240            if (null == addr) {
241                data.writeInt(0);
242            } else {
243                data.writeInt(1);
244                final InetAddress a = addr.getAddress();
245                final byte[]      b = a.getAddress();
246                final int         p = addr.getPort();
247
248                if (a instanceof Inet4Address) {
249                    int v4addr = (((int)b[0] & 0xFF) << 24) |
250                                 (((int)b[1] & 0xFF) << 16) |
251                                 (((int)b[2] & 0xFF) << 8) |
252                                  ((int)b[3] & 0xFF);
253
254                    data.writeInt(AF_INET);
255                    data.writeInt(v4addr);
256                    data.writeInt(p);
257                } else
258                if (a instanceof Inet6Address) {
259                    int i;
260                    Inet6Address v6 = (Inet6Address)a;
261                    data.writeInt(AF_INET6);
262                    for (i = 0; i < 4; ++i) {
263                        int aword = (((int)b[(i*4) + 0] & 0xFF) << 24) |
264                                    (((int)b[(i*4) + 1] & 0xFF) << 16) |
265                                    (((int)b[(i*4) + 2] & 0xFF) << 8) |
266                                     ((int)b[(i*4) + 3] & 0xFF);
267                        data.writeInt(aword);
268                    }
269                    data.writeInt(p);
270                    data.writeInt(0);   // flow info
271                    data.writeInt(v6.getScopeId());
272                } else {
273                    return ERROR_BAD_VALUE;
274                }
275            }
276
277            mRemote.transact(method_code, data, reply, 0);
278            ret_val = reply.readInt();
279        }
280        catch (RemoteException e) {
281            ret_val = ERROR_DEAD_OBJECT;
282        }
283        finally {
284            reply.recycle();
285            data.recycle();
286        }
287
288        return ret_val;
289    }
290
291    private IBinder mRemote;
292    private String mInterfaceDesc;
293};
294