From 96f3bdf16b5da814c617cdd7f08baa00b83f2293 Mon Sep 17 00:00:00 2001 From: Joachim Fritzsch Date: Sat, 6 Apr 2013 12:55:00 +0200 Subject: [PATCH] -android: acquisition of WakeLock to prevent CPU throttling when display is off. --- android/BOINC/AndroidManifest.xml | 1 + .../berkeley/boinc/client/ClientStatus.java | 40 ++++++++++++++++++- .../edu/berkeley/boinc/client/Monitor.java | 10 +++-- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/android/BOINC/AndroidManifest.xml b/android/BOINC/AndroidManifest.xml index 5a8d638f79..5c2552d14e 100644 --- a/android/BOINC/AndroidManifest.xml +++ b/android/BOINC/AndroidManifest.xml @@ -29,6 +29,7 @@ + results; @@ -75,6 +80,33 @@ public class ClientStatus { public Integer networkSuspendReason = 0; //reason why network activity got suspended, only if NETWORK_STATUS_SUSPENDED private Boolean networkParseError = false; //indicates that status could not be parsed and is therefore invalid + public ClientStatus(Context ctx) { + this.ctx = ctx; + + // set up Wake Lock + // see documentation at http://developer.android.com/reference/android/os/PowerManager.html + PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + wakeLock.setReferenceCounted(false); // "one call to release() is sufficient to undo the effect of all previous calls to acquire()" + } + + // call to acquire or release resources held by the WakeLock. + // acquisition: every time the Monitor loop calls setClientStatus and computingStatus == COMPUTING_STATUS_COMPUTING + // release: every time computingStatus != COMPUTING_STATUS_COMPUTING , and in Monitor.onDestroy() + public void setWakeLock(Boolean acquire) { + try { + if(wakeLock.isHeld() == acquire) return; // wakeLock already in desired state + + if(acquire) { // acquire wakeLock + wakeLock.acquire(); + Log.d(TAG, "wakeLock acquired"); + } else { // release wakeLock + wakeLock.release(); + Log.d(TAG, "wakeLock released"); + } + } catch (Exception e) {Log.w(TAG, "Exception durign setWakeLock " + acquire, e);} + } + /* * fires "clientstatuschange" broadcast, so registered Activities can update their model. */ @@ -90,10 +122,10 @@ public class ClientStatus { /* * Application context is required by the broadcast mechanism, reference is copied by Monitor service on start up. - */ + public synchronized void setCtx(Context tctx) { this.ctx = tctx; - } + }*/ /* * called frequently by Monitor to set the RPC data. These objects are used to determine the client status and parse it in the data model of this class. @@ -220,12 +252,14 @@ public class ClientStatus { computingStatus = COMPUTING_STATUS_NEVER; computingSuspendReason = status.task_suspend_reason; // = 4 - SUSPEND_REASON_USER_REQ???? computingParseError = false; + setWakeLock(false); return; } if((status.task_mode == BOINCDefs.RUN_MODE_AUTO) && (status.task_suspend_reason != BOINCDefs.SUSPEND_NOT_SUSPENDED)) { computingStatus = COMPUTING_STATUS_SUSPENDED; computingSuspendReason = status.task_suspend_reason; computingParseError = false; + setWakeLock(false); return; } if((status.task_mode == BOINCDefs.RUN_MODE_AUTO) && (status.task_suspend_reason == BOINCDefs.SUSPEND_NOT_SUSPENDED)) { @@ -244,11 +278,13 @@ public class ClientStatus { computingStatus = COMPUTING_STATUS_COMPUTING; computingSuspendReason = status.task_suspend_reason; // = 0 - SUSPEND_NOT_SUSPENDED computingParseError = false; + setWakeLock(true); return; } else { // client "is able but idle" computingStatus = COMPUTING_STATUS_IDLE; computingSuspendReason = status.task_suspend_reason; // = 0 - SUSPEND_NOT_SUSPENDED computingParseError = false; + setWakeLock(false); return; } } diff --git a/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java b/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java index 44a354727f..4775ad83bd 100644 --- a/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java +++ b/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java @@ -56,7 +56,7 @@ import edu.berkeley.boinc.rpc.Transfer; public class Monitor extends Service { - private final String TAG = "BOINC Monitor Service"; + private static final String TAG = "BOINC Monitor Service"; private static ClientStatus clientStatus; //holds the status of the client as determined by the Monitor private static AppPreferences appPrefs; //hold the status of the app, controlled by AppPreferences @@ -428,7 +428,7 @@ public class Monitor extends Service { public static ClientStatus getClientStatus() { //singleton pattern if (clientStatus == null) { - clientStatus = new ClientStatus(); + Log.d(TAG,"WARNING: clientStatus not yet initialized"); } return clientStatus; } @@ -480,7 +480,7 @@ public class Monitor extends Service { retryAttempts = getResources().getInteger(R.integer.monitor_setup_connection_retry_attempts); // initialize singleton helper classes and provide application context - getClientStatus().setCtx(this); + clientStatus = new ClientStatus(this); getAppPrefs().readPrefs(this); if(!started) { @@ -507,12 +507,14 @@ public class Monitor extends Service { // monitorRunning = false; monitorThread.interrupt(); + + clientStatus.setWakeLock(false); // release wakeLock, if held. // Quit client here is not appropriate?! // Keep Client running until explecitely killed, independently from UI //quitClient(); - //Toast.makeText(this, "BOINC Monitor Service Stopped", Toast.LENGTH_SHORT).show(); + //android.widget.Toast.makeText(this, "BOINC Monitor Service Stopped", android.widget.Toast.LENGTH_SHORT).show(); } @Override