Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright 2017 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 
     17 package com.android.internal.telephony;
     18 
     19 import android.annotation.CallSuper;
     20 import android.hardware.radio.V1_0.CellInfoType;
     21 import android.hardware.radio.V1_0.RegState;
     22 import android.os.AsyncResult;
     23 import android.os.Handler;
     24 import android.os.HandlerThread;
     25 import android.os.Looper;
     26 import android.os.Message;
     27 import android.telephony.AccessNetworkConstants.TransportType;
     28 import android.telephony.CellIdentity;
     29 import android.telephony.CellIdentityCdma;
     30 import android.telephony.CellIdentityGsm;
     31 import android.telephony.CellIdentityLte;
     32 import android.telephony.CellIdentityTdscdma;
     33 import android.telephony.CellIdentityWcdma;
     34 import android.telephony.NetworkRegistrationState;
     35 import android.telephony.NetworkService;
     36 import android.telephony.NetworkServiceCallback;
     37 import android.telephony.Rlog;
     38 import android.telephony.ServiceState;
     39 import android.telephony.SubscriptionManager;
     40 
     41 import java.util.concurrent.ConcurrentHashMap;
     42 
     43 /**
     44  * Implementation of network services for Cellular. It's a service that handles network requests
     45  * for Cellular. It passes the requests to inner CellularNetworkServiceProvider which has a
     46  * handler thread for each slot.
     47  */
     48 public class CellularNetworkService extends NetworkService {
     49     private static final boolean DBG = false;
     50 
     51     private static final String TAG = CellularNetworkService.class.getSimpleName();
     52 
     53     private static final int GET_CS_REGISTRATION_STATE_DONE = 1;
     54     private static final int GET_PS_REGISTRATION_STATE_DONE = 2;
     55     private static final int NETWORK_REGISTRATION_STATE_CHANGED = 3;
     56 
     57     private class CellularNetworkServiceProvider extends NetworkServiceProvider {
     58 
     59         private final ConcurrentHashMap<Message, NetworkServiceCallback> mCallbackMap =
     60                 new ConcurrentHashMap<>();
     61 
     62         private final Looper mLooper;
     63 
     64         private final HandlerThread mHandlerThread;
     65 
     66         private final Handler mHandler;
     67 
     68         private final Phone mPhone;
     69 
     70         CellularNetworkServiceProvider(int slotId) {
     71             super(slotId);
     72 
     73             mPhone = PhoneFactory.getPhone(getSlotId());
     74 
     75             mHandlerThread = new HandlerThread(CellularNetworkService.class.getSimpleName());
     76             mHandlerThread.start();
     77             mLooper = mHandlerThread.getLooper();
     78             mHandler = new Handler(mLooper) {
     79                 @Override
     80                 public void handleMessage(Message message) {
     81                     NetworkServiceCallback callback = mCallbackMap.remove(message);
     82 
     83                     AsyncResult ar;
     84                     switch (message.what) {
     85                         case GET_CS_REGISTRATION_STATE_DONE:
     86                         case GET_PS_REGISTRATION_STATE_DONE:
     87                             if (callback == null) return;
     88                             ar = (AsyncResult) message.obj;
     89                             int domain = (message.what == GET_CS_REGISTRATION_STATE_DONE)
     90                                     ? NetworkRegistrationState.DOMAIN_CS
     91                                     : NetworkRegistrationState.DOMAIN_PS;
     92                             NetworkRegistrationState netState =
     93                                     getRegistrationStateFromResult(ar.result, domain);
     94 
     95                             int resultCode;
     96                             if (ar.exception != null || netState == null) {
     97                                 resultCode = NetworkServiceCallback.RESULT_ERROR_FAILED;
     98                             } else {
     99                                 resultCode = NetworkServiceCallback.RESULT_SUCCESS;
    100                             }
    101 
    102                             try {
    103                                 if (DBG) {
    104                                     log("Calling callback.onGetNetworkRegistrationStateComplete."
    105                                             + "resultCode = " + resultCode
    106                                             + ", netState = " + netState);
    107                                 }
    108                                 callback.onGetNetworkRegistrationStateComplete(
    109                                          resultCode, netState);
    110                             } catch (Exception e) {
    111                                 loge("Exception: " + e);
    112                             }
    113                             break;
    114                         case NETWORK_REGISTRATION_STATE_CHANGED:
    115                             notifyNetworkRegistrationStateChanged();
    116                             break;
    117                         default:
    118                             return;
    119                     }
    120                 }
    121             };
    122 
    123             mPhone.mCi.registerForNetworkStateChanged(
    124                     mHandler, NETWORK_REGISTRATION_STATE_CHANGED, null);
    125         }
    126 
    127         private int getRegStateFromHalRegState(int halRegState) {
    128             switch (halRegState) {
    129                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
    130                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM:
    131                     return NetworkRegistrationState.REG_STATE_NOT_REG_NOT_SEARCHING;
    132                 case RegState.REG_HOME:
    133                     return NetworkRegistrationState.REG_STATE_HOME;
    134                 case RegState.NOT_REG_MT_SEARCHING_OP:
    135                 case RegState.NOT_REG_MT_SEARCHING_OP_EM:
    136                     return NetworkRegistrationState.REG_STATE_NOT_REG_SEARCHING;
    137                 case RegState.REG_DENIED:
    138                 case RegState.REG_DENIED_EM:
    139                     return NetworkRegistrationState.REG_STATE_DENIED;
    140                 case RegState.UNKNOWN:
    141                 case RegState.UNKNOWN_EM:
    142                     return NetworkRegistrationState.REG_STATE_UNKNOWN;
    143                 case RegState.REG_ROAMING:
    144                     return NetworkRegistrationState.REG_STATE_ROAMING;
    145                 default:
    146                     return NetworkRegistrationState.REG_STATE_NOT_REG_NOT_SEARCHING;
    147             }
    148         }
    149 
    150         private boolean isEmergencyOnly(int halRegState) {
    151             switch (halRegState) {
    152                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM:
    153                 case RegState.NOT_REG_MT_SEARCHING_OP_EM:
    154                 case RegState.REG_DENIED_EM:
    155                 case RegState.UNKNOWN_EM:
    156                     return true;
    157                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
    158                 case RegState.REG_HOME:
    159                 case RegState.NOT_REG_MT_SEARCHING_OP:
    160                 case RegState.REG_DENIED:
    161                 case RegState.UNKNOWN:
    162                 case RegState.REG_ROAMING:
    163                 default:
    164                     return false;
    165             }
    166         }
    167 
    168         private int[] getAvailableServices(int regState, int domain, boolean emergencyOnly) {
    169             int[] availableServices = null;
    170 
    171             // In emergency only states, only SERVICE_TYPE_EMERGENCY is available.
    172             // Otherwise, certain services are available only if it's registered on home or roaming
    173             // network.
    174             if (emergencyOnly) {
    175                 availableServices = new int[] {NetworkRegistrationState.SERVICE_TYPE_EMERGENCY};
    176             } else if (regState == NetworkRegistrationState.REG_STATE_ROAMING
    177                     || regState == NetworkRegistrationState.REG_STATE_HOME) {
    178                 if (domain == NetworkRegistrationState.DOMAIN_PS) {
    179                     availableServices = new int[] {NetworkRegistrationState.SERVICE_TYPE_DATA};
    180                 } else if (domain == NetworkRegistrationState.DOMAIN_CS) {
    181                     availableServices = new int[] {
    182                             NetworkRegistrationState.SERVICE_TYPE_VOICE,
    183                             NetworkRegistrationState.SERVICE_TYPE_SMS,
    184                             NetworkRegistrationState.SERVICE_TYPE_VIDEO
    185                     };
    186                 }
    187             }
    188 
    189             return availableServices;
    190         }
    191 
    192         private int getAccessNetworkTechnologyFromRat(int rilRat) {
    193             return ServiceState.rilRadioTechnologyToNetworkType(rilRat);
    194         }
    195 
    196         private NetworkRegistrationState getRegistrationStateFromResult(Object result, int domain) {
    197             if (result == null) {
    198                 return null;
    199             }
    200 
    201             // TODO: unify when voiceRegStateResult and DataRegStateResult are unified.
    202             if (domain == NetworkRegistrationState.DOMAIN_CS) {
    203                 return createRegistrationStateFromVoiceRegState(result);
    204             } else if (domain == NetworkRegistrationState.DOMAIN_PS) {
    205                 return createRegistrationStateFromDataRegState(result);
    206             } else {
    207                 return null;
    208             }
    209         }
    210 
    211         private NetworkRegistrationState createRegistrationStateFromVoiceRegState(Object result) {
    212             int transportType = TransportType.WWAN;
    213             int domain = NetworkRegistrationState.DOMAIN_CS;
    214 
    215             if (result instanceof android.hardware.radio.V1_0.VoiceRegStateResult) {
    216                 android.hardware.radio.V1_0.VoiceRegStateResult voiceRegState =
    217                         (android.hardware.radio.V1_0.VoiceRegStateResult) result;
    218                 int regState = getRegStateFromHalRegState(voiceRegState.regState);
    219                 int accessNetworkTechnology = getAccessNetworkTechnologyFromRat(voiceRegState.rat);
    220                 int reasonForDenial = voiceRegState.reasonForDenial;
    221                 boolean emergencyOnly = isEmergencyOnly(voiceRegState.regState);
    222                 boolean cssSupported = voiceRegState.cssSupported;
    223                 int roamingIndicator = voiceRegState.roamingIndicator;
    224                 int systemIsInPrl = voiceRegState.systemIsInPrl;
    225                 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator;
    226                 int[] availableServices = getAvailableServices(
    227                         regState, domain, emergencyOnly);
    228                 CellIdentity cellIdentity =
    229                         convertHalCellIdentityToCellIdentity(voiceRegState.cellIdentity);
    230 
    231                 return new NetworkRegistrationState(transportType, domain, regState,
    232                         accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices,
    233                         cellIdentity, cssSupported, roamingIndicator, systemIsInPrl,
    234                         defaultRoamingIndicator);
    235             } else if (result instanceof android.hardware.radio.V1_2.VoiceRegStateResult) {
    236                 android.hardware.radio.V1_2.VoiceRegStateResult voiceRegState =
    237                         (android.hardware.radio.V1_2.VoiceRegStateResult) result;
    238                 int regState = getRegStateFromHalRegState(voiceRegState.regState);
    239                 int accessNetworkTechnology = getAccessNetworkTechnologyFromRat(voiceRegState.rat);
    240                 int reasonForDenial = voiceRegState.reasonForDenial;
    241                 boolean emergencyOnly = isEmergencyOnly(voiceRegState.regState);
    242                 boolean cssSupported = voiceRegState.cssSupported;
    243                 int roamingIndicator = voiceRegState.roamingIndicator;
    244                 int systemIsInPrl = voiceRegState.systemIsInPrl;
    245                 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator;
    246                 int[] availableServices = getAvailableServices(
    247                         regState, domain, emergencyOnly);
    248                 CellIdentity cellIdentity =
    249                         convertHalCellIdentityToCellIdentity(voiceRegState.cellIdentity);
    250 
    251                 return new NetworkRegistrationState(transportType, domain, regState,
    252                         accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices,
    253                         cellIdentity, cssSupported, roamingIndicator, systemIsInPrl,
    254                         defaultRoamingIndicator);
    255             }
    256 
    257             return null;
    258         }
    259 
    260         private NetworkRegistrationState createRegistrationStateFromDataRegState(Object result) {
    261             int transportType = TransportType.WWAN;
    262             int domain = NetworkRegistrationState.DOMAIN_PS;
    263 
    264             if (result instanceof android.hardware.radio.V1_0.DataRegStateResult) {
    265                 android.hardware.radio.V1_0.DataRegStateResult dataRegState =
    266                         (android.hardware.radio.V1_0.DataRegStateResult) result;
    267                 int regState = getRegStateFromHalRegState(dataRegState.regState);
    268                 int accessNetworkTechnology = getAccessNetworkTechnologyFromRat(dataRegState.rat);
    269                 int reasonForDenial = dataRegState.reasonDataDenied;
    270                 boolean emergencyOnly = isEmergencyOnly(dataRegState.regState);
    271                 int maxDataCalls = dataRegState.maxDataCalls;
    272                 int[] availableServices = getAvailableServices(regState, domain, emergencyOnly);
    273                 CellIdentity cellIdentity =
    274                         convertHalCellIdentityToCellIdentity(dataRegState.cellIdentity);
    275 
    276                 return new NetworkRegistrationState(transportType, domain, regState,
    277                         accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices,
    278                         cellIdentity, maxDataCalls);
    279             } else if (result instanceof android.hardware.radio.V1_2.DataRegStateResult) {
    280                 android.hardware.radio.V1_2.DataRegStateResult dataRegState =
    281                         (android.hardware.radio.V1_2.DataRegStateResult) result;
    282                 int regState = getRegStateFromHalRegState(dataRegState.regState);
    283                 int accessNetworkTechnology = getAccessNetworkTechnologyFromRat(dataRegState.rat);
    284                 int reasonForDenial = dataRegState.reasonDataDenied;
    285                 boolean emergencyOnly = isEmergencyOnly(dataRegState.regState);
    286                 int maxDataCalls = dataRegState.maxDataCalls;
    287                 int[] availableServices = getAvailableServices(regState, domain, emergencyOnly);
    288                 CellIdentity cellIdentity =
    289                         convertHalCellIdentityToCellIdentity(dataRegState.cellIdentity);
    290 
    291                 return new NetworkRegistrationState(transportType, domain, regState,
    292                         accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices,
    293                         cellIdentity, maxDataCalls);
    294             }
    295 
    296             return null;
    297         }
    298 
    299         private CellIdentity convertHalCellIdentityToCellIdentity(
    300                 android.hardware.radio.V1_0.CellIdentity cellIdentity) {
    301             if (cellIdentity == null) {
    302                 return null;
    303             }
    304 
    305             CellIdentity result = null;
    306             switch(cellIdentity.cellInfoType) {
    307                 case CellInfoType.GSM: {
    308                     if (cellIdentity.cellIdentityGsm.size() == 1) {
    309                         android.hardware.radio.V1_0.CellIdentityGsm cellIdentityGsm =
    310                                 cellIdentity.cellIdentityGsm.get(0);
    311                         result = new CellIdentityGsm(cellIdentityGsm.lac, cellIdentityGsm.cid,
    312                                 cellIdentityGsm.arfcn, cellIdentityGsm.bsic, cellIdentityGsm.mcc,
    313                                 cellIdentityGsm.mnc, null, null);
    314                     }
    315                     break;
    316                 }
    317                 case CellInfoType.WCDMA: {
    318                     if (cellIdentity.cellIdentityWcdma.size() == 1) {
    319                         android.hardware.radio.V1_0.CellIdentityWcdma cellIdentityWcdma =
    320                                 cellIdentity.cellIdentityWcdma.get(0);
    321                         result = new CellIdentityWcdma(cellIdentityWcdma.lac, cellIdentityWcdma.cid,
    322                                 cellIdentityWcdma.psc, cellIdentityWcdma.uarfcn,
    323                                 cellIdentityWcdma.mcc, cellIdentityWcdma.mnc, null, null);
    324                     }
    325                     break;
    326                 }
    327                 case CellInfoType.TD_SCDMA: {
    328                     if (cellIdentity.cellIdentityTdscdma.size() == 1) {
    329                         android.hardware.radio.V1_0.CellIdentityTdscdma cellIdentityTdscdma =
    330                                 cellIdentity.cellIdentityTdscdma.get(0);
    331                         result = new  CellIdentityTdscdma(cellIdentityTdscdma.mcc,
    332                                 cellIdentityTdscdma.mnc, cellIdentityTdscdma.lac,
    333                                 cellIdentityTdscdma.cid, cellIdentityTdscdma.cpid);
    334                     }
    335                     break;
    336                 }
    337                 case CellInfoType.LTE: {
    338                     if (cellIdentity.cellIdentityLte.size() == 1) {
    339                         android.hardware.radio.V1_0.CellIdentityLte cellIdentityLte =
    340                                 cellIdentity.cellIdentityLte.get(0);
    341 
    342                         result = new CellIdentityLte(cellIdentityLte.ci, cellIdentityLte.pci,
    343                                 cellIdentityLte.tac, cellIdentityLte.earfcn, Integer.MAX_VALUE,
    344                                 cellIdentityLte.mcc, cellIdentityLte.mnc, null, null);
    345                     }
    346                     break;
    347                 }
    348                 case CellInfoType.CDMA: {
    349                     if (cellIdentity.cellIdentityCdma.size() == 1) {
    350                         android.hardware.radio.V1_0.CellIdentityCdma cellIdentityCdma =
    351                                 cellIdentity.cellIdentityCdma.get(0);
    352 
    353                         result = new CellIdentityCdma(cellIdentityCdma.networkId,
    354                                 cellIdentityCdma.systemId, cellIdentityCdma.baseStationId,
    355                                 cellIdentityCdma.longitude, cellIdentityCdma.latitude);
    356                     }
    357                     break;
    358                 }
    359                 case CellInfoType.NONE:
    360                 default:
    361                     break;
    362             }
    363 
    364             return result;
    365         }
    366 
    367         private CellIdentity convertHalCellIdentityToCellIdentity(
    368                 android.hardware.radio.V1_2.CellIdentity cellIdentity) {
    369             if (cellIdentity == null) {
    370                 return null;
    371             }
    372 
    373             CellIdentity result = null;
    374             switch(cellIdentity.cellInfoType) {
    375                 case CellInfoType.GSM: {
    376                     if (cellIdentity.cellIdentityGsm.size() == 1) {
    377                         android.hardware.radio.V1_2.CellIdentityGsm cellIdentityGsm =
    378                                 cellIdentity.cellIdentityGsm.get(0);
    379 
    380                         result = new CellIdentityGsm(
    381                                 cellIdentityGsm.base.lac,
    382                                 cellIdentityGsm.base.cid,
    383                                 cellIdentityGsm.base.arfcn,
    384                                 cellIdentityGsm.base.bsic,
    385                                 cellIdentityGsm.base.mcc,
    386                                 cellIdentityGsm.base.mnc,
    387                                 cellIdentityGsm.operatorNames.alphaLong,
    388                                 cellIdentityGsm.operatorNames.alphaShort);
    389                     }
    390                     break;
    391                 }
    392                 case CellInfoType.WCDMA: {
    393                     if (cellIdentity.cellIdentityWcdma.size() == 1) {
    394                         android.hardware.radio.V1_2.CellIdentityWcdma cellIdentityWcdma =
    395                                 cellIdentity.cellIdentityWcdma.get(0);
    396 
    397                         result = new CellIdentityWcdma(
    398                                 cellIdentityWcdma.base.lac,
    399                                 cellIdentityWcdma.base.cid,
    400                                 cellIdentityWcdma.base.psc,
    401                                 cellIdentityWcdma.base.uarfcn,
    402                                 cellIdentityWcdma.base.mcc,
    403                                 cellIdentityWcdma.base.mnc,
    404                                 cellIdentityWcdma.operatorNames.alphaLong,
    405                                 cellIdentityWcdma.operatorNames.alphaShort);
    406                     }
    407                     break;
    408                 }
    409                 case CellInfoType.TD_SCDMA: {
    410                     if (cellIdentity.cellIdentityTdscdma.size() == 1) {
    411                         android.hardware.radio.V1_2.CellIdentityTdscdma cellIdentityTdscdma =
    412                                 cellIdentity.cellIdentityTdscdma.get(0);
    413 
    414                         result = new  CellIdentityTdscdma(
    415                                 cellIdentityTdscdma.base.mcc,
    416                                 cellIdentityTdscdma.base.mnc,
    417                                 cellIdentityTdscdma.base.lac,
    418                                 cellIdentityTdscdma.base.cid,
    419                                 cellIdentityTdscdma.base.cpid,
    420                                 cellIdentityTdscdma.operatorNames.alphaLong,
    421                                 cellIdentityTdscdma.operatorNames.alphaShort);
    422                     }
    423                     break;
    424                 }
    425                 case CellInfoType.LTE: {
    426                     if (cellIdentity.cellIdentityLte.size() == 1) {
    427                         android.hardware.radio.V1_2.CellIdentityLte cellIdentityLte =
    428                                 cellIdentity.cellIdentityLte.get(0);
    429 
    430                         result = new CellIdentityLte(
    431                                 cellIdentityLte.base.ci,
    432                                 cellIdentityLte.base.pci,
    433                                 cellIdentityLte.base.tac,
    434                                 cellIdentityLte.base.earfcn,
    435                                 cellIdentityLte.bandwidth,
    436                                 cellIdentityLte.base.mcc,
    437                                 cellIdentityLte.base.mnc,
    438                                 cellIdentityLte.operatorNames.alphaLong,
    439                                 cellIdentityLte.operatorNames.alphaShort);
    440                     }
    441                     break;
    442                 }
    443                 case CellInfoType.CDMA: {
    444                     if (cellIdentity.cellIdentityCdma.size() == 1) {
    445                         android.hardware.radio.V1_2.CellIdentityCdma cellIdentityCdma =
    446                                 cellIdentity.cellIdentityCdma.get(0);
    447 
    448                         result = new CellIdentityCdma(
    449                                 cellIdentityCdma.base.networkId,
    450                                 cellIdentityCdma.base.systemId,
    451                                 cellIdentityCdma.base.baseStationId,
    452                                 cellIdentityCdma.base.longitude,
    453                                 cellIdentityCdma.base.latitude,
    454                                 cellIdentityCdma.operatorNames.alphaLong,
    455                                 cellIdentityCdma.operatorNames.alphaShort);
    456                     }
    457                     break;
    458                 }
    459                 case CellInfoType.NONE:
    460                 default:
    461                     break;
    462             }
    463 
    464             return result;
    465         }
    466 
    467         @Override
    468         public void getNetworkRegistrationState(int domain, NetworkServiceCallback callback) {
    469             if (DBG) log("getNetworkRegistrationState for domain " + domain);
    470             Message message = null;
    471 
    472             if (domain == NetworkRegistrationState.DOMAIN_CS) {
    473                 message = Message.obtain(mHandler, GET_CS_REGISTRATION_STATE_DONE);
    474                 mCallbackMap.put(message, callback);
    475                 mPhone.mCi.getVoiceRegistrationState(message);
    476             } else if (domain == NetworkRegistrationState.DOMAIN_PS) {
    477                 message = Message.obtain(mHandler, GET_PS_REGISTRATION_STATE_DONE);
    478                 mCallbackMap.put(message, callback);
    479                 mPhone.mCi.getDataRegistrationState(message);
    480             } else {
    481                 loge("getNetworkRegistrationState invalid domain " + domain);
    482                 callback.onGetNetworkRegistrationStateComplete(
    483                         NetworkServiceCallback.RESULT_ERROR_INVALID_ARG, null);
    484             }
    485         }
    486 
    487         @CallSuper
    488         protected void onDestroy() {
    489             super.onDestroy();
    490 
    491             mCallbackMap.clear();
    492             mHandlerThread.quit();
    493             mPhone.mCi.unregisterForNetworkStateChanged(mHandler);
    494         }
    495     }
    496 
    497     @Override
    498     protected NetworkServiceProvider createNetworkServiceProvider(int slotId) {
    499         if (DBG) log("Cellular network service created for slot " + slotId);
    500         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
    501             loge("Tried to Cellular network service with invalid slotId " + slotId);
    502             return null;
    503         }
    504         return new CellularNetworkServiceProvider(slotId);
    505     }
    506 
    507     private void log(String s) {
    508         Rlog.d(TAG, s);
    509     }
    510 
    511     private void loge(String s) {
    512         Rlog.e(TAG, s);
    513     }
    514 }
    515