mirror of https://github.com/BOINC/boinc.git
android: implementation of <report_device_status>
This commit is contained in:
parent
3bef989991
commit
8df34c4fbf
|
@ -25,6 +25,8 @@
|
|||
<integer name="monitor_setup_connection_retry_rate_ms">1000</integer>
|
||||
<integer name="monitor_setup_connection_retry_attempts">10</integer>
|
||||
<integer name="autostart_notification_id">460</integer>
|
||||
<!-- Device status -->
|
||||
<integer name="minimum_device_status_refresh_rate_in_monitor_loops">10</integer>
|
||||
<!-- configuration on tab layout -->
|
||||
<bool name="tab_status">true</bool>
|
||||
<bool name="tab_projects">true</bool>
|
||||
|
|
|
@ -46,6 +46,7 @@ import edu.berkeley.boinc.rpc.AccountIn;
|
|||
import edu.berkeley.boinc.rpc.AccountOut;
|
||||
import edu.berkeley.boinc.rpc.CcState;
|
||||
import edu.berkeley.boinc.rpc.CcStatus;
|
||||
import edu.berkeley.boinc.rpc.DeviceStatus;
|
||||
import edu.berkeley.boinc.rpc.GlobalPreferences;
|
||||
import edu.berkeley.boinc.rpc.Message;
|
||||
import edu.berkeley.boinc.rpc.Project;
|
||||
|
@ -919,6 +920,11 @@ public class Monitor extends Service {
|
|||
|
||||
// Frequency of which the monitor updates client status via RPC, to often can cause reduced performance!
|
||||
private Integer refreshFrequency = getResources().getInteger(R.integer.monitor_refresh_rate_ms);
|
||||
private Integer minimumDeviceStatusFrequency = getResources().getInteger(R.integer.minimum_device_status_refresh_rate_in_monitor_loops);
|
||||
private Integer deviceStatusOmitCounter = 0;
|
||||
|
||||
// DeviceStatus wrapper class
|
||||
private DeviceStatus deviceStatus = new DeviceStatus(getApplicationContext());
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Integer... params) {
|
||||
|
@ -933,6 +939,19 @@ public class Monitor extends Service {
|
|||
clientSetup();
|
||||
sleep = false;
|
||||
} else {
|
||||
// connection alive
|
||||
|
||||
// set devices status
|
||||
try {
|
||||
if(deviceStatus.update() || deviceStatusOmitCounter >= minimumDeviceStatusFrequency) {
|
||||
if(showRpcCommands) Log.d(TAG, "reportDeviceStatus");
|
||||
Boolean reportStatusSuccess = rpc.reportDeviceStatus(deviceStatus);
|
||||
Log.d(TAG,"reportDeviceStatus returned: " + reportStatusSuccess);
|
||||
if(reportStatusSuccess) deviceStatusOmitCounter = 0;
|
||||
} else deviceStatusOmitCounter++;
|
||||
} catch (Exception e) { Log.w(TAG, "device status update failed: " + e.getLocalizedMessage()); }
|
||||
|
||||
// retrieve client status
|
||||
if(showRpcCommands) Log.d(TAG, "getCcStatus");
|
||||
CcStatus status = rpc.getCcStatus();
|
||||
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/*******************************************************************************
|
||||
* This file is part of BOINC.
|
||||
* http://boinc.berkeley.edu
|
||||
* Copyright (C) 2012 University of California
|
||||
*
|
||||
* BOINC is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* BOINC is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
package edu.berkeley.boinc.rpc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.BatteryManager;
|
||||
import android.util.Log;
|
||||
|
||||
public class DeviceStatus{
|
||||
|
||||
private final String TAG = "Rpc.DeviceState";
|
||||
|
||||
// variables describing device status
|
||||
private boolean on_ac_power;
|
||||
private boolean on_usb_power; //not used
|
||||
private int battery_charge_pct;
|
||||
private int battery_state; //not used
|
||||
private int battery_temperature_celcius;
|
||||
private boolean wifi_online;
|
||||
|
||||
// android specifics
|
||||
private Context ctx;// context required for reading device status
|
||||
private ConnectivityManager connManager; // connManager contains current wifi status
|
||||
private Intent batteryStatus; // sticky intent, extras of Intent contain status, see BatteryManager.
|
||||
|
||||
// constructor
|
||||
public DeviceStatus(Context ctx) {
|
||||
this.ctx = ctx;
|
||||
this.connManager = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
batteryStatus = ctx.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
}
|
||||
|
||||
// polls current device status
|
||||
// returns true if data model has actually changed
|
||||
// returns false if device status is unchanged -> avoid RPC call
|
||||
public Boolean update() throws Exception {
|
||||
if(ctx == null) {
|
||||
Log.w(TAG,"context not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
Boolean change = false;
|
||||
|
||||
// check battery
|
||||
batteryStatus = ctx.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
if(batteryStatus != null){
|
||||
|
||||
// calculate charging level
|
||||
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
|
||||
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
|
||||
int batteryPct = (int) ((level / (float) scale) * 100); // always rounds down
|
||||
if(batteryPct <= 1 || batteryPct > 100) throw new Exception("battery level parsing error");
|
||||
if(batteryPct != battery_charge_pct) {
|
||||
battery_charge_pct = batteryPct;
|
||||
change = true;
|
||||
}
|
||||
|
||||
// temperature
|
||||
int temperature = batteryStatus.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1) / 10; // always rounds down
|
||||
if(temperature < 0) throw new Exception("temperature parsing error");
|
||||
if(temperature != battery_temperature_celcius) {
|
||||
battery_temperature_celcius = temperature;
|
||||
change = true;
|
||||
}
|
||||
|
||||
// plugged in
|
||||
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
|
||||
if(status != BatteryManager.BATTERY_STATUS_DISCHARGING){
|
||||
// power supply online. not equivalent to BATTERY_STATUS_CHARGING which is not the case when full and plugged in
|
||||
if(!on_ac_power) change = true; // if different from before, set flag
|
||||
on_ac_power = true;
|
||||
} else {
|
||||
//power supply offline
|
||||
if(on_ac_power) change = true; // if different from before, set flag
|
||||
on_ac_power = false;
|
||||
}
|
||||
}
|
||||
|
||||
// check wifi status
|
||||
if(connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()){
|
||||
//wifi is online
|
||||
if(!wifi_online) change = true; // if different from before, set flag
|
||||
wifi_online = true;
|
||||
} else {
|
||||
//wifi offline
|
||||
if(wifi_online) change = true; // if different from before, set flag
|
||||
wifi_online = false;
|
||||
}
|
||||
|
||||
Log.d(TAG, "change: " + change + " - power supply: " + on_ac_power + " ; level: " + battery_charge_pct + " ; temperature: " + battery_temperature_celcius + " ; wifi: " + wifi_online);
|
||||
return change;
|
||||
}
|
||||
|
||||
// getter
|
||||
public boolean isOn_ac_power() {
|
||||
return on_ac_power;
|
||||
}
|
||||
|
||||
public boolean isOn_usb_power() {
|
||||
return on_usb_power;
|
||||
}
|
||||
|
||||
public int getBattery_charge_pct() {
|
||||
return battery_charge_pct;
|
||||
}
|
||||
|
||||
public int getBattery_state() {
|
||||
return battery_state;
|
||||
}
|
||||
|
||||
public int getBattery_temperature_celcius() {
|
||||
return battery_temperature_celcius;
|
||||
}
|
||||
|
||||
public boolean isWifi_online() {
|
||||
return wifi_online;
|
||||
}
|
||||
}
|
|
@ -580,6 +580,41 @@ public class RpcClient {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the current device state to the BOINC core client,
|
||||
* if not called frequently, BOINC core client will suspend
|
||||
* @return true for success, false for failure
|
||||
*/
|
||||
public synchronized boolean reportDeviceStatus(DeviceStatus deviceStatus) {
|
||||
mLastErrorMessage = null;
|
||||
mRequest.setLength(0);
|
||||
mRequest.append("<report_device_status>\n <device_status>\n <on_ac_power>");
|
||||
mRequest.append(deviceStatus.isOn_ac_power() ? 1 : 0);
|
||||
mRequest.append("</on_ac_power>\n <on_usb_power>");
|
||||
mRequest.append(deviceStatus.isOn_usb_power() ? 1 : 0);
|
||||
mRequest.append("</on_usb_power>\n <battery_charge_pct>");
|
||||
mRequest.append(deviceStatus.getBattery_charge_pct());
|
||||
mRequest.append("</battery_charge_pct>\n <battery_state>");
|
||||
mRequest.append(deviceStatus.getBattery_state());
|
||||
mRequest.append("</battery_state>\n <battery_temperature_celsius>");
|
||||
mRequest.append(deviceStatus.getBattery_temperature_celcius());
|
||||
mRequest.append("</battery_temperature_celsius>\n <wifi_online>");
|
||||
mRequest.append(deviceStatus.isWifi_online() ? 1 : 0);
|
||||
mRequest.append("</wifi_online>\n </device_status>\n</report_device_status>\n");
|
||||
try {
|
||||
sendRequest(mRequest.toString());
|
||||
SimpleReplyParser parser = SimpleReplyParser.parse(receiveReply());
|
||||
if (parser == null)
|
||||
return false;
|
||||
mLastErrorMessage = parser.getErrorMessage();
|
||||
return parser.result();
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (Logging.WARNING) Log.w(TAG, "error in networkAvailable()", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the BOINC core client that a network connection is available,
|
||||
* and that it should do as much network activity as it can.
|
||||
|
|
|
@ -105,6 +105,7 @@ public class BOINCDefs {
|
|||
public static final int SUSPEND_REASON_WIFI_STATE = 4097;
|
||||
public static final int SUSPEND_REASON_BATTERY_CHARGING = 4098;
|
||||
public static final int SUSPEND_REASON_BATTERY_OVERHEATED = 4099;
|
||||
public static final int SUSPEND_REASON_NO_GUI_KEEPALIVE = 4100;
|
||||
|
||||
// Values of RESULT::state
|
||||
// THESE MUST BE IN NUMERICAL ORDER
|
||||
|
|
Loading…
Reference in New Issue