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