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