Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Is there any intents to listen for CPU "sleep" and "wake Up" apart from screen on and off?

My understanding is,existing Screen OFF and ON intents are not exactly mean that the device is in sleep and waked up respectively. Any applications on the device holds partial wake lock, device will not be in deep sleep but screen may be off/on.

Is there any intents to listen CPU "WAKE UP" and "SLEEP" ?

Is there any way, we know CPU is waked UP from deep sleep ?

like image 740
Pampapathi Avatar asked Oct 31 '22 09:10

Pampapathi


1 Answers

I needed a tool to do exactly this when troubleshooting some timing behavior on my app in the background. So I made my own class to do it. See code below. Here's how you use it:

CpuSleepDetector.getInstance().setSleepEndNotifier(new CpuSleepDetector.SleepEndNotifier() {
        @Override
        public void cpuSleepEnded(long sleepDurationMillis) {
            Log.d(TAG, "The CPU just exited sleep.  It was sleeping for "+sleepDurationMillis+" ms.");
        }
});
CpuSleepDetector.getInstance().logDump();

The logDump method will dump the last 100 sleep events to LogCat. This is useful in troubleshooting, becaue to get the CPU to sleep, I had to not only disconnect my USB cable from my phone, I actually had to turn off my adb connection over WiFi. This way, you can reconnect adb at a later time and use the logDump method to get recent detections.

I know this is an old question, but hopefully this will be useful to somebody else.

Here's the code for the detector class:

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;

public class CpuSleepDetector {
    private static final String TAG = CpuSleepDetector.class.getSimpleName();
    private static CpuSleepDetector instance = null;
    private HandlerThread thread;
    private Handler handler;
    private SleepEndNotifier notifier;

    public static CpuSleepDetector getInstance() {
        if (instance == null) {
            instance = new CpuSleepDetector();
        }
        return instance;
    }
    private CpuSleepDetector() {
        thread = new HandlerThread("cpuSleepDetectorThread");
        thread.start();
        handler = new Handler(thread.getLooper());
        watchForSleep();
    }
    private void watchForSleep(){
        // uptime stalls when cpu stalls
        final long uptimeAtStart = SystemClock.uptimeMillis();
        final long realtimeAtStart = SystemClock.elapsedRealtime();
        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                long uptimeAtEnd = SystemClock.uptimeMillis();
                long realtimeAtEnd = SystemClock.elapsedRealtime();
                long realtimeDelta = realtimeAtEnd - realtimeAtStart;
                long uptimeDelta = uptimeAtEnd - uptimeAtStart;
                final long sleepTime = realtimeDelta - uptimeDelta;
                if (sleepTime > 1) {
                    detectedStalls.put(new Date(), sleepTime);
                    prune();
                    if (notifier != null) {
                        new Handler(Looper.getMainLooper()).post(new Runnable() {
                            @Override
                            public void run() {
                                notifier.cpuSleepEnded(sleepTime);
                            }
                        });
                    }
                }
                watchForSleep();
            }
        }, 1000);
    }
    private HashMap<Date,Long> detectedStalls = new HashMap<Date,Long>();
    private HashMap<Date,Long> getDetectedStalls() {
        return detectedStalls;
    }
    private void prune() {
        int numberToPrune = detectedStalls.size() - 100;
        if (numberToPrune > 0) {
            HashMap<Date,Long> newDetectedStalls = new HashMap<Date,Long>();
            ArrayList<Date>  dates = new ArrayList<>(getDetectedStalls().keySet());
            Collections.sort(dates);
            for (int i = numberToPrune; i < detectedStalls.size(); i++) {
                newDetectedStalls.put(dates.get(i), detectedStalls.get(dates.get(i)));
            }
            detectedStalls = newDetectedStalls;
        }
    }
    public void logDump() {
        Log.d(TAG, "Last 100 known CPU sleep incidents:");
        ArrayList<Date>  dates = new ArrayList<>(getDetectedStalls().keySet());
        Collections.sort(dates);
        for (Date date: dates) {
            Log.d(TAG, ""+date+": "+getDetectedStalls().get(date));
        }
    }
    public void setSleepEndNotifier(SleepEndNotifier notifier) {
        this.notifier = notifier;
    }
    public interface SleepEndNotifier {
        public void cpuSleepEnded(long sleepDurationMillis);
    }
}
like image 101
davidgyoung Avatar answered Nov 11 '22 12:11

davidgyoung