1/* 2 * Copyright (C) 2016 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.googlecode.android_scripting.facade; 18 19import android.app.Service; 20import android.content.BroadcastReceiver; 21import android.content.Context; 22import android.content.Intent; 23import android.content.IntentFilter; 24import android.os.BatteryManager; 25import android.os.Bundle; 26 27import com.googlecode.android_scripting.Log; 28import com.googlecode.android_scripting.jsonrpc.RpcReceiver; 29import com.googlecode.android_scripting.rpc.Rpc; 30import com.googlecode.android_scripting.rpc.RpcStartEvent; 31import com.googlecode.android_scripting.rpc.RpcStopEvent; 32 33import java.lang.reflect.Field; 34 35/** 36 * Exposes Batterymanager API. Note that in order to use any of the batteryGet* functions, you need 37 * to batteryStartMonitoring, and then wait for a "battery" event. Sleeping for a second will 38 * usually work just as well. 39 * 40 */ 41public class BatteryManagerFacade extends RpcReceiver { 42 43 private final Service mService; 44 private final EventFacade mEventFacade; 45 private final int mSdkVersion; 46 47 private BatteryStateListener mReceiver; 48 49 private volatile Bundle mBatteryData = null; 50 private volatile Integer mBatteryStatus = null; 51 private volatile Integer mBatteryHealth = null; 52 private volatile Integer mPlugType = null; 53 54 private volatile Boolean mBatteryPresent = null; 55 private volatile Integer mBatteryLevel = null; 56 private volatile Integer mBatteryMaxLevel = null; 57 private volatile Integer mBatteryVoltage = null; 58 private volatile Integer mBatteryTemperature = null; 59 private volatile String mBatteryTechnology = null; 60 61 public BatteryManagerFacade(FacadeManager manager) { 62 super(manager); 63 mService = manager.getService(); 64 mSdkVersion = manager.getSdkLevel(); 65 mEventFacade = manager.getReceiver(EventFacade.class); 66 mReceiver = null; 67 mBatteryData = null; 68 } 69 70 private class BatteryStateListener extends BroadcastReceiver { 71 72 private final EventFacade mmEventFacade; 73 74 private BatteryStateListener(EventFacade facade) { 75 mmEventFacade = facade; 76 } 77 78 @Override 79 public void onReceive(Context context, Intent intent) { 80 mBatteryStatus = intent.getIntExtra("status", 1); 81 mBatteryHealth = intent.getIntExtra("health", 1); 82 mPlugType = intent.getIntExtra("plugged", -1); 83 if (mSdkVersion >= 5) { 84 mBatteryPresent = 85 intent.getBooleanExtra(getBatteryManagerFieldValue("EXTRA_PRESENT"), false); 86 mBatteryLevel = intent.getIntExtra(getBatteryManagerFieldValue("EXTRA_LEVEL"), -1); 87 mBatteryMaxLevel = intent.getIntExtra(getBatteryManagerFieldValue("EXTRA_SCALE"), 0); 88 mBatteryVoltage = intent.getIntExtra(getBatteryManagerFieldValue("EXTRA_VOLTAGE"), -1); 89 mBatteryTemperature = 90 intent.getIntExtra(getBatteryManagerFieldValue("EXTRA_TEMPERATURE"), -1); 91 mBatteryTechnology = intent.getStringExtra(getBatteryManagerFieldValue("EXTRA_TECHNOLOGY")); 92 } 93 Bundle data = new Bundle(); 94 data.putInt("status", mBatteryStatus); 95 data.putInt("health", mBatteryHealth); 96 data.putInt("plugged", mPlugType); 97 if (mSdkVersion >= 5) { 98 data.putBoolean("battery_present", mBatteryPresent); 99 if (mBatteryMaxLevel == null || mBatteryMaxLevel == 100 || mBatteryMaxLevel == 0) { 100 data.putInt("level", mBatteryLevel); 101 } else { 102 data.putInt("level", (int) (mBatteryLevel * 100.0 / mBatteryMaxLevel)); 103 } 104 data.putInt("voltage", mBatteryVoltage); 105 data.putInt("temperature", mBatteryTemperature); 106 data.putString("technology", mBatteryTechnology); 107 } 108 mBatteryData = data; 109 mmEventFacade.postEvent("battery", mBatteryData.clone()); 110 } 111 } 112 113 private String getBatteryManagerFieldValue(String name) { 114 try { 115 Field f = BatteryManager.class.getField(name); 116 return f.get(null).toString(); 117 } catch (Exception e) { 118 Log.e(e); 119 } 120 return null; 121 } 122 123 @Rpc(description = "Returns the most recently recorded battery data.") 124 public Bundle readBatteryData() { 125 return mBatteryData; 126 } 127 128 /** 129 * throws "battery" events 130 */ 131 @Rpc(description = "Starts tracking battery state.") 132 @RpcStartEvent("battery") 133 public void batteryStartMonitoring() { 134 if (mReceiver == null) { 135 IntentFilter filter = new IntentFilter(); 136 filter.addAction(Intent.ACTION_BATTERY_CHANGED); 137 mReceiver = new BatteryStateListener(mEventFacade); 138 mService.registerReceiver(mReceiver, filter); 139 } 140 } 141 142 @Rpc(description = "Stops tracking battery state.") 143 @RpcStopEvent("battery") 144 public void batteryStopMonitoring() { 145 if (mReceiver != null) { 146 mService.unregisterReceiver(mReceiver); 147 mReceiver = null; 148 } 149 mBatteryData = null; 150 } 151 152 @Override 153 public void shutdown() { 154 batteryStopMonitoring(); 155 } 156 157 @Rpc(description = "Returns the most recently received battery status data:" + "\n1 - unknown;" 158 + "\n2 - charging;" + "\n3 - discharging;" + "\n4 - not charging;" + "\n5 - full;") 159 public Integer batteryGetStatus() { 160 return mBatteryStatus; 161 } 162 163 @Rpc(description = "Returns the most recently received battery health data:" + "\n1 - unknown;" 164 + "\n2 - good;" + "\n3 - overheat;" + "\n4 - dead;" + "\n5 - over voltage;" 165 + "\n6 - unspecified failure;") 166 public Integer batteryGetHealth() { 167 return mBatteryHealth; 168 } 169 170 /** Power source is an AC charger. */ 171 public static final int BATTERY_PLUGGED_AC = 1; 172 /** Power source is a USB port. */ 173 public static final int BATTERY_PLUGGED_USB = 2; 174 175 @Rpc(description = "Returns the most recently received plug type data:" + "\n-1 - unknown" 176 + "\n0 - unplugged;" + "\n1 - power source is an AC charger" 177 + "\n2 - power source is a USB port") 178 public Integer batteryGetPlugType() { 179 return mPlugType; 180 } 181 182 @Rpc(description = "Returns the most recently received battery presence data.") 183 public Boolean batteryCheckPresent() { 184 return mBatteryPresent; 185 } 186 187 @Rpc(description = "Returns the most recently received battery level (percentage).") 188 public Integer batteryGetLevel() { 189 if (mBatteryMaxLevel == null || mBatteryMaxLevel == 100 || mBatteryMaxLevel == 0) { 190 return mBatteryLevel; 191 } else { 192 return (int) (mBatteryLevel * 100.0 / mBatteryMaxLevel); 193 } 194 } 195 196 @Rpc(description = "Returns the most recently received battery voltage.") 197 public Integer batteryGetVoltage() { 198 return mBatteryVoltage; 199 } 200 201 @Rpc(description = "Returns the most recently received battery temperature.") 202 public Integer batteryGetTemperature() { 203 return mBatteryTemperature; 204 } 205 206 @Rpc(description = "Returns the most recently received battery technology data.") 207 public String batteryGetTechnology() { 208 return mBatteryTechnology; 209 } 210 211} 212