diff --git a/android/BOINC/res/values/strings.xml b/android/BOINC/res/values/strings.xml index 4ea25fe012..94163ccf1d 100644 --- a/android/BOINC/res/values/strings.xml +++ b/android/BOINC/res/values/strings.xml @@ -159,7 +159,7 @@ Limits the daily data traffic caused by BOINC. Transfer tasks on WiFi only Autostart - Show notifications + Show notification when suspended Used CPU cores Limits the number of CPU cores BOINC uses for computation. Pause at CPU usage above diff --git a/android/BOINC/src/edu/berkeley/boinc/PrefsActivity.java b/android/BOINC/src/edu/berkeley/boinc/PrefsActivity.java index 275565480f..f0de9885b2 100644 --- a/android/BOINC/src/edu/berkeley/boinc/PrefsActivity.java +++ b/android/BOINC/src/edu/berkeley/boinc/PrefsActivity.java @@ -237,7 +237,7 @@ public class PrefsActivity extends FragmentActivity { break; case R.string.prefs_show_notification_header: //app pref appPrefs.setShowNotification(isSet); - ClientNotification.getInstance(getApplicationContext()).update(); // update notification + ClientNotification.getInstance(getApplicationContext()).enable(isSet); updateBoolPref(ID, isSet); updateLayout(); break; diff --git a/android/BOINC/src/edu/berkeley/boinc/client/ClientNotification.java b/android/BOINC/src/edu/berkeley/boinc/client/ClientNotification.java index 5c96f29174..5c6497d4a4 100644 --- a/android/BOINC/src/edu/berkeley/boinc/client/ClientNotification.java +++ b/android/BOINC/src/edu/berkeley/boinc/client/ClientNotification.java @@ -21,9 +21,12 @@ public class ClientNotification { private NotificationManager nm; private Integer notificationId; private PendingIntent contentIntent; - + private int mOldComputingStatus = -1; private int mOldSuspendReason = -1; + // debug foreground state by running + // adb shell: dumpsys activity services edu.berkeley.boinc + private boolean foreground = false; /** * Returns a reference to a singleton ClientNotification object. @@ -49,30 +52,35 @@ public class ClientNotification { /** * Updates notification with client's current status */ - public synchronized void update() { - // check whether notification is allowed in preferences - if (!Monitor.getAppPrefs().getShowNotification()) { - nm.cancel(notificationId); - clientNotification.mOldComputingStatus = -1; - return; - } - - // try to get current client status from monitor - ClientStatus updatedStatus; - try{ - updatedStatus = Monitor.getClientStatus(); - } catch (Exception e){ - if(Logging.WARNING) Log.w(Logging.TAG,"ClientNotification: Could not load data, clientStatus not initialized."); - return; - } + public synchronized void update(ClientStatus updatedStatus, Monitor monitorService) { - // update notification + // update notification, only after change in status if (clientNotification.mOldComputingStatus == -1 || updatedStatus.computingStatus.intValue() != clientNotification.mOldComputingStatus || (updatedStatus.computingStatus == ClientStatus.COMPUTING_STATUS_SUSPENDED && updatedStatus.computingSuspendReason != clientNotification.mOldSuspendReason)) { - nm.notify(notificationId, buildNotification(updatedStatus)); + if(updatedStatus.computingStatus == ClientStatus.COMPUTING_STATUS_COMPUTING) { + // computing! set service as foreground + monitorService.startForeground(notificationId, buildNotification(updatedStatus)); + if(Logging.DEBUG) Log.d(Logging.TAG,"ClientNotification.update() start service as foreground."); + foreground = true; + } else { + // not computing, set service as background + if(foreground) { + foreground = false; + monitorService.stopForeground(true); + if(Logging.DEBUG) Log.d(Logging.TAG,"ClientNotification.update() stop service as foreground."); + } + // check whether notification is allowed in preferences + if (!Monitor.getAppPrefs().getShowNotification()) { + enable(false); + return; + } + + nm.notify(notificationId, buildNotification(updatedStatus)); + } + // save status for comparison next time clientNotification.mOldComputingStatus = updatedStatus.computingStatus; @@ -80,6 +88,30 @@ public class ClientNotification { } } + // called after change in notification preference + public synchronized void enable(Boolean enable) { + if(Logging.DEBUG) Log.d(Logging.TAG,"ClientNotification.enable() " + enable); + if(foreground) { + // foreground notification mandatory, do not change + if(Logging.DEBUG) Log.d(Logging.TAG,"ClientNotification.enable() service in foreground, do not change."); + } else { + // service in background, notification behavior configurable + if(enable){ + try{ + ClientStatus status = Monitor.getClientStatus(); + nm.notify(notificationId, buildNotification(status)); + // save status for comparison next time + clientNotification.mOldComputingStatus = status.computingStatus; + clientNotification.mOldSuspendReason = status.computingSuspendReason; + } catch (Exception e) {if(Logging.WARNING) Log.w(Logging.TAG,"ClientNotification.enable() failed!");} + + } else { + nm.cancel(notificationId); + clientNotification.mOldComputingStatus = -1; + } + } + } + // cancels notification, called during client shutdown public synchronized void cancel() { nm.cancel(notificationId); diff --git a/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java b/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java index cebc8ea0bf..703856716a 100644 --- a/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java +++ b/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java @@ -370,7 +370,7 @@ public class Monitor extends Service { if( (status != null) && (state != null) && (state.results != null) && (state.projects != null) && (transfers != null) && (state.host_info != null)) { Monitor.getClientStatus().setClientStatus(status, state.results, state.projects, transfers, state.host_info); // Update status bar notification - ClientNotification.getInstance(getApplicationContext()).update(); + ClientNotification.getInstance(getApplicationContext()).update(Monitor.getClientStatus(), this); } else { if(Logging.ERROR) Log.e(Logging.TAG, "readClientStatus(): connection problem"); }