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 java.util.Locale;
     23 import static android.system.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