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 */ 16 package android.os; 17 18 import java.net.InetAddress; 19 import java.net.Inet4Address; 20 import java.net.Inet6Address; 21 import java.net.InetSocketAddress; 22 import java.util.Locale; 23 import static libcore.io.OsConstants.*; 24 25 class 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