10d4bcdf379842af4b6304809156971e926f374f0Jake Hamby/* 20d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Copyright (C) 2013 The Android Open Source Project 30d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * 40d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Licensed under the Apache License, Version 2.0 (the "License"); 50d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * you may not use this file except in compliance with the License. 60d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * You may obtain a copy of the License at 70d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * 80d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * http://www.apache.org/licenses/LICENSE-2.0 90d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * 100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Unless required by applicable law or agreed to in writing, software 110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * distributed under the License is distributed on an "AS IS" BASIS, 120d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * See the License for the specific language governing permissions and 140d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * limitations under the License. 150d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 160d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 170d4bcdf379842af4b6304809156971e926f374f0Jake Hambypackage com.android.internal.telephony; 180d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 190d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.content.BroadcastReceiver; 200d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.content.Context; 210d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.content.Intent; 220d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.os.Build; 230d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.os.Message; 240d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.os.PowerManager; 250d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport android.telephony.Rlog; 260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 270d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.util.State; 280d4bcdf379842af4b6304809156971e926f374f0Jake Hambyimport com.android.internal.util.StateMachine; 290d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 300d4bcdf379842af4b6304809156971e926f374f0Jake Hamby/** 310d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Generic state machine for handling messages and waiting for ordered broadcasts to complete. 320d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Subclasses implement {@link #handleSmsMessage}, which returns true to transition into waiting 330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * state, or false to remain in idle state. The wakelock is acquired on exit from idle state, 340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * and is released a few seconds after returning to idle state, or immediately upon calling 350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * {@link #quit}. 360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 370d4bcdf379842af4b6304809156971e926f374f0Jake Hambypublic abstract class WakeLockStateMachine extends StateMachine { 380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected static final boolean DBG = true; // TODO: change to false 390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private final PowerManager.WakeLock mWakeLock; 410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** New message to process. */ 430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public static final int EVENT_NEW_SMS_MESSAGE = 1; 440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** Result receiver called for current cell broadcast. */ 460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected static final int EVENT_BROADCAST_COMPLETE = 2; 470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** Release wakelock after a short timeout when returning to idle state. */ 490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby static final int EVENT_RELEASE_WAKE_LOCK = 3; 500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 51d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville static final int EVENT_UPDATE_PHONE_OBJECT = 4; 52d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville 536c806ef816f8ae0a1849ba05f3128a04577b32d0Amit Mahajan protected Phone mPhone; 54d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville 55d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville protected Context mContext; 56d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville 570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** Wakelock release delay when returning to idle state. */ 580d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private static final int WAKE_LOCK_TIMEOUT = 3000; 590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 600d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private final DefaultState mDefaultState = new DefaultState(); 610d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private final IdleState mIdleState = new IdleState(); 620d4bcdf379842af4b6304809156971e926f374f0Jake Hamby private final WaitingState mWaitingState = new WaitingState(); 630d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 646c806ef816f8ae0a1849ba05f3128a04577b32d0Amit Mahajan protected WakeLockStateMachine(String debugTag, Context context, Phone phone) { 650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby super(debugTag); 660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 67d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville mContext = context; 68d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville mPhone = phone; 69d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville 700d4bcdf379842af4b6304809156971e926f374f0Jake Hamby PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 710d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, debugTag); 720d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mWakeLock.acquire(); // wake lock released after we enter idle state 730d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 740d4bcdf379842af4b6304809156971e926f374f0Jake Hamby addState(mDefaultState); 750d4bcdf379842af4b6304809156971e926f374f0Jake Hamby addState(mIdleState, mDefaultState); 760d4bcdf379842af4b6304809156971e926f374f0Jake Hamby addState(mWaitingState, mDefaultState); 770d4bcdf379842af4b6304809156971e926f374f0Jake Hamby setInitialState(mIdleState); 780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 790d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 806c806ef816f8ae0a1849ba05f3128a04577b32d0Amit Mahajan public void updatePhoneObject(Phone phone) { 81d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville sendMessage(EVENT_UPDATE_PHONE_OBJECT, phone); 82d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville } 83d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville 840d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 850d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Tell the state machine to quit after processing all messages. 860d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 870d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public final void dispose() { 880d4bcdf379842af4b6304809156971e926f374f0Jake Hamby quit(); 890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 900d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 920d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected void onQuitting() { 930d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // fully release the wakelock 940d4bcdf379842af4b6304809156971e926f374f0Jake Hamby while (mWakeLock.isHeld()) { 950d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mWakeLock.release(); 960d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 990d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 1000d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Send a message with the specified object for {@link #handleSmsMessage}. 1010d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param obj the object to pass in the msg.obj field 1020d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 1030d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public final void dispatchSmsMessage(Object obj) { 1040d4bcdf379842af4b6304809156971e926f374f0Jake Hamby sendMessage(EVENT_NEW_SMS_MESSAGE, obj); 1050d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1060d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1070d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 1080d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * This parent state throws an exception (for debug builds) or prints an error for unhandled 1090d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * message types. 1100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 1110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby class DefaultState extends State { 1120d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 1130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public boolean processMessage(Message msg) { 114d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville switch (msg.what) { 115d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville case EVENT_UPDATE_PHONE_OBJECT: { 1166c806ef816f8ae0a1849ba05f3128a04577b32d0Amit Mahajan mPhone = (Phone) msg.obj; 117d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville log("updatePhoneObject: phone=" + mPhone.getClass().getSimpleName()); 118d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville break; 119d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville } 120d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville default: { 121d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville String errorText = "processMessage: unhandled message type " + msg.what; 122d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville if (Build.IS_DEBUGGABLE) { 123d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville throw new RuntimeException(errorText); 124d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville } else { 125d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville loge(errorText); 126d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville } 127d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville break; 128d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville } 129d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville } 130d2feaf918ab0c1173d4ada182532e48d0c0d3f77Wink Saville return HANDLED; 1310d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1320d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 1350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Idle state delivers Cell Broadcasts to receivers. It acquires the wakelock, which is 1360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * released when the broadcast completes. 1370d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 1380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby class IdleState extends State { 1390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 1400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public void enter() { 1410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby sendMessageDelayed(EVENT_RELEASE_WAKE_LOCK, WAKE_LOCK_TIMEOUT); 1420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 1450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public void exit() { 1460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mWakeLock.acquire(); 1470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (DBG) log("acquired wakelock, leaving Idle state"); 1480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 1510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public boolean processMessage(Message msg) { 1520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby switch (msg.what) { 1530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case EVENT_NEW_SMS_MESSAGE: 1540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // transition to waiting state if we sent a broadcast 1550d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (handleSmsMessage(msg)) { 1560d4bcdf379842af4b6304809156971e926f374f0Jake Hamby transitionTo(mWaitingState); 1570d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1580d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return HANDLED; 1590d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1600d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case EVENT_RELEASE_WAKE_LOCK: 1610d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mWakeLock.release(); 1620d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (DBG) { 1630d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (mWakeLock.isHeld()) { 1640d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // this is okay as long as we call release() for every acquire() 1650d4bcdf379842af4b6304809156971e926f374f0Jake Hamby log("mWakeLock is still held after release"); 1660d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } else { 1670d4bcdf379842af4b6304809156971e926f374f0Jake Hamby log("mWakeLock released"); 1680d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1690d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1700d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return HANDLED; 1710d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1720d4bcdf379842af4b6304809156971e926f374f0Jake Hamby default: 1730d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return NOT_HANDLED; 1740d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1750d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1760d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 1770d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1780d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 1790d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Waiting state waits for the result receiver to be called for the current cell broadcast. 1800d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * In this state, any new cell broadcasts are deferred until we return to Idle state. 1810d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 1820d4bcdf379842af4b6304809156971e926f374f0Jake Hamby class WaitingState extends State { 1830d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 1840d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public boolean processMessage(Message msg) { 1850d4bcdf379842af4b6304809156971e926f374f0Jake Hamby switch (msg.what) { 1860d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case EVENT_NEW_SMS_MESSAGE: 1870d4bcdf379842af4b6304809156971e926f374f0Jake Hamby log("deferring message until return to idle"); 1880d4bcdf379842af4b6304809156971e926f374f0Jake Hamby deferMessage(msg); 1890d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return HANDLED; 1900d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1910d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case EVENT_BROADCAST_COMPLETE: 1920d4bcdf379842af4b6304809156971e926f374f0Jake Hamby log("broadcast complete, returning to idle"); 1930d4bcdf379842af4b6304809156971e926f374f0Jake Hamby transitionTo(mIdleState); 1940d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return HANDLED; 1950d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 1960d4bcdf379842af4b6304809156971e926f374f0Jake Hamby case EVENT_RELEASE_WAKE_LOCK: 1970d4bcdf379842af4b6304809156971e926f374f0Jake Hamby mWakeLock.release(); // decrement wakelock from previous entry to Idle 1980d4bcdf379842af4b6304809156971e926f374f0Jake Hamby if (!mWakeLock.isHeld()) { 1990d4bcdf379842af4b6304809156971e926f374f0Jake Hamby // wakelock should still be held until 3 seconds after we enter Idle 2000d4bcdf379842af4b6304809156971e926f374f0Jake Hamby loge("mWakeLock released while still in WaitingState!"); 2010d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2020d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return HANDLED; 2030d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2040d4bcdf379842af4b6304809156971e926f374f0Jake Hamby default: 2050d4bcdf379842af4b6304809156971e926f374f0Jake Hamby return NOT_HANDLED; 2060d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2070d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2080d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2090d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2100d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 2110d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Implemented by subclass to handle messages in {@link IdleState}. 2120d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param message the message to process 2130d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @return true to transition to {@link WaitingState}; false to stay in {@link IdleState} 2140d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 2150d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected abstract boolean handleSmsMessage(Message message); 2160d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2170d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 2180d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * BroadcastReceiver to send message to return to idle state. 2190d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 2200d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected final BroadcastReceiver mReceiver = new BroadcastReceiver() { 2210d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 2220d4bcdf379842af4b6304809156971e926f374f0Jake Hamby public void onReceive(Context context, Intent intent) { 2230d4bcdf379842af4b6304809156971e926f374f0Jake Hamby sendMessage(EVENT_BROADCAST_COMPLETE); 2240d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2250d4bcdf379842af4b6304809156971e926f374f0Jake Hamby }; 2260d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2270d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 2280d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Log with debug level. 2290d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param s the string to log 2300d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 2310d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 2320d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected void log(String s) { 2330d4bcdf379842af4b6304809156971e926f374f0Jake Hamby Rlog.d(getName(), s); 2340d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2350d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2360d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 2370d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Log with error level. 2380d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param s the string to log 2390d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 2400d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 2410d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected void loge(String s) { 2420d4bcdf379842af4b6304809156971e926f374f0Jake Hamby Rlog.e(getName(), s); 2430d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2440d4bcdf379842af4b6304809156971e926f374f0Jake Hamby 2450d4bcdf379842af4b6304809156971e926f374f0Jake Hamby /** 2460d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * Log with error level. 2470d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param s the string to log 2480d4bcdf379842af4b6304809156971e926f374f0Jake Hamby * @param e is a Throwable which logs additional information. 2490d4bcdf379842af4b6304809156971e926f374f0Jake Hamby */ 2500d4bcdf379842af4b6304809156971e926f374f0Jake Hamby @Override 2510d4bcdf379842af4b6304809156971e926f374f0Jake Hamby protected void loge(String s, Throwable e) { 2520d4bcdf379842af4b6304809156971e926f374f0Jake Hamby Rlog.e(getName(), s, e); 2530d4bcdf379842af4b6304809156971e926f374f0Jake Hamby } 2540d4bcdf379842af4b6304809156971e926f374f0Jake Hamby} 255