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