/*
* Tencent is pleased to support the open source community by making
* Tencent GT (Version 2.4 and subsequent versions) available.
*
* Notwithstanding anything to the contrary herein, any previous version
* of Tencent GT shall not be subject to the license hereunder.
* All right, title, and interest, including all intellectual property rights,
* in and to the previous version of Tencent GT (including any and all copies thereof)
* shall be owned and retained by Tencent and subject to the license under the
* Tencent GT End User License Agreement (http://gt.qq.com/wp-content/EULA_EN.html).
*
* Copyright (C) 2015 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the MIT License (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.tencent.wstt.gt.plugin.battery;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import com.tencent.wstt.gt.Functions;
import com.tencent.wstt.gt.GTApp;
import com.tencent.wstt.gt.OutPara;
import com.tencent.wstt.gt.R;
import com.tencent.wstt.gt.api.base.GTLog;
import com.tencent.wstt.gt.api.utils.DeviceUtils;
import com.tencent.wstt.gt.dao.GTPref;
import com.tencent.wstt.gt.manager.Client;
import com.tencent.wstt.gt.manager.ClientManager;
import com.tencent.wstt.gt.manager.OpPerfBridge;
import com.tencent.wstt.gt.plugin.PluginTaskExecutor;
import com.tencent.wstt.gt.utils.BrightnessUtils;
import com.tencent.wstt.gt.utils.FileUtil;
import android.os.Bundle;
public class GTBatteryEngine implements PluginTaskExecutor {
// 唯一实例
private static GTBatteryEngine INSTANCE;
// 插件参数的管理使用全局客户端
private Client globalClient;
private static Timer timer;
private static final String LOG_TAG = "Battery";
// 观察者们,包括UI和自动化模块
private List<BatteryPluginListener> listeners;
// 插件没有业务模块,各CheckBox状态保存在静态变量里
private boolean state_cb_I = true; // 默认电流开关是开的
private boolean state_cb_U = false;
private boolean state_cb_P = false;
private boolean state_cb_T = false;
// 保存当前的电池参数值
private String I = ""; // 电流
private String U = ""; // 电压
private String POW = ""; // 电量
private String TEMP = ""; // 温度
private int INT_TEMP = -273; // 上一次采集的温度的值
public static final String OPI = "Current"; // 电流出参key
public static final String OPU = "Volt"; // 电压出参key
public static final String OPPow = "Power"; // 电量出参key
public static final String OPTemp = "Temperature"; // 温度出参key
// 持久化key
private static final String KEY_I = "battery_I";
private static final String KEY_U = "battery_U";
private static final String KEY_Pow = "battery_Pow";
private static final String KEY_Temp = "battery_Temp";
private long startBattry = -1; // 记录上一次电池变化的时间
private String lastBatteryChangeTime = "";
// 刷新频率
private int refreshRate = 250; // 单位毫秒
// 亮度,0-255
private int brightness = -1;
// 是否已经开始监控flag
private boolean isStarted = false;
private GTBatteryEngine()
{
globalClient = ClientManager.getInstance().getGlobalClient();
listeners = new ArrayList<BatteryPluginListener>();
state_cb_I = GTPref.getGTPref().getBoolean(KEY_I, true); // 默认关注电流值
state_cb_U = GTPref.getGTPref().getBoolean(KEY_U, false);
state_cb_P = GTPref.getGTPref().getBoolean(KEY_Pow, false);
state_cb_T = GTPref.getGTPref().getBoolean(KEY_Temp, false);
}
public static GTBatteryEngine getInstance() {
if (null == INSTANCE) {
INSTANCE = new GTBatteryEngine();
}
return INSTANCE;
}
public boolean isStarted()
{
return isStarted;
}
@Override
public void execute(Bundle bundle) {
String cmd = bundle.getString("cmd");
if (cmd != null && cmd.equals("start")) {
doStart(250, 100);
} else if (cmd != null && cmd.equals("stop")) {
doStop();
}
}
public void doStart(int in_refreshRate, int in_brightness)
{
if (isStarted()) return;
try
{
if (state_cb_I)
{
globalClient.registerOutPara(OPI, "I");
globalClient.setOutparaMonitor(OPI, true);
OpPerfBridge.startProfier(
globalClient.getOutPara(OPI), Functions.PERF_DIGITAL_NORMAL, "", "mA");
}
if (state_cb_U)
{
globalClient.registerOutPara(OPU, "U");
globalClient.setOutparaMonitor(OPU, true);
OpPerfBridge.startProfier(
globalClient.getOutPara(OPU), Functions.PERF_DIGITAL_NORMAL, "", "mV");
}
if (state_cb_P)
{
globalClient.registerOutPara(OPPow, "POW");
globalClient.setOutparaMonitor(OPPow, true);
OpPerfBridge.startProfier(
globalClient.getOutPara(OPPow), Functions.PERF_DIGITAL_NORMAL, "", "%");
}
if (state_cb_T)
{
globalClient.registerOutPara(OPTemp, "TEMP");
globalClient.setOutparaMonitor(OPTemp, true);
OpPerfBridge.startProfier(
globalClient.getOutPara(OPTemp), Functions.PERF_DIGITAL_NORMAL, "", "℃");
}
if (in_refreshRate < 100)
{
for (BatteryPluginListener listener : listeners)
{
listener.onBatteryException(GTApp.getContext(
).getString(R.string.pi_battery_sample_tip2));
}
return;
}
else
{
this.refreshRate = in_refreshRate;
}
timer = new Timer(true);
timer.schedule(new ReadPowerTimerTask(), refreshRate, refreshRate);
// 处理亮度
if (in_brightness >= 0 && in_brightness <= 255)
{
setBrightness(in_brightness);
BrightnessUtils.setManualMode();
BrightnessUtils.setScreenBrightness(in_brightness);
BrightnessUtils.saveBrightness(in_brightness);
}
isStarted = true;
for (BatteryPluginListener listener : listeners)
{
listener.onBatteryStart();
}
}
catch (Exception e)
{
for (BatteryPluginListener listener : listeners)
{
listener.onBatteryException(
GTApp.getContext().getString(R.string.pi_battery_sample_tip));
}
}
}
public void doStop()
{
if (! isStarted()) return;
if (timer != null)
{
timer.cancel();
timer.purge();
timer = null;
}
isStarted = false;
for (BatteryPluginListener listener : listeners)
{
listener.onBatteryStop();
}
}
public boolean isState_cb_I() {
return state_cb_I;
}
public boolean isState_cb_U() {
return state_cb_U;
}
public boolean isState_cb_P() {
return state_cb_P;
}
public boolean isState_cb_T() {
return state_cb_T;
}
public void updateI(boolean isChecked)
{
if (isChecked)
{
globalClient.registerOutPara(GTBatteryEngine.OPI, "I");
globalClient.setOutparaMonitor(GTBatteryEngine.OPI, true);
}
else
{
globalClient.unregisterOutPara(GTBatteryEngine.OPI);
}
state_cb_I = isChecked;
GTPref.getGTPref().edit().putBoolean(GTBatteryEngine.KEY_I, isChecked).commit();
for (BatteryPluginListener listener : listeners)
{
listener.onUpdateI(isChecked);
}
}
public void updateU(boolean isChecked)
{
if (isChecked)
{
globalClient.registerOutPara(OPU, "U");
globalClient.setOutparaMonitor(GTBatteryEngine.OPU, true);
}
else
{
globalClient.unregisterOutPara(OPU);
}
state_cb_U = isChecked;
GTPref.getGTPref().edit().putBoolean(KEY_U, isChecked).commit();
for (BatteryPluginListener listener : listeners)
{
listener.onUpdateU(isChecked);
}
}
public void updateP(boolean isChecked)
{
if (isChecked)
{
globalClient.registerOutPara(OPPow, "POW");
globalClient.setOutparaMonitor(GTBatteryEngine.OPPow, true);
}
else
{
globalClient.unregisterOutPara(OPPow);
}
state_cb_P = isChecked;
GTPref.getGTPref().edit().putBoolean(KEY_Pow, isChecked).commit();
for (BatteryPluginListener listener : listeners)
{
listener.onUpdateP(isChecked);
}
}
public void updateT(boolean isChecked)
{
if (isChecked)
{
globalClient.registerOutPara(OPTemp, "TEMP");
globalClient.setOutparaMonitor(GTBatteryEngine.OPTemp, true);
}
else
{
globalClient.unregisterOutPara(OPTemp);
}
state_cb_T = isChecked;
GTPref.getGTPref().edit().putBoolean(KEY_Temp, isChecked).commit();
for (BatteryPluginListener listener : listeners)
{
listener.onUpdateT(isChecked);
}
}
public int getRefreshRate() {
return refreshRate;
}
public void setRefreshRate(int refreshRate) {
this.refreshRate = refreshRate;
}
public int getBrightness() {
return brightness;
}
public void setBrightness(int brightness) {
this.brightness = brightness;
}
public synchronized void addListener(BatteryPluginListener listener)
{
listeners.add(listener);
}
public synchronized void removeListener(BatteryPluginListener listener)
{
listeners.remove(listener);
}
class ReadPowerTimerTask extends TimerTask {
File f = new File("/sys/class/power_supply/battery/uevent");
// 如华为系统,Battery目录是大写的。。
File f2 = new File("/sys/class/power_supply/Battery/uevent");
boolean isHuawei = false;
boolean isLGg3 = false; // 但实际上LG g3的数据应该不够准确,静默都是1500mA左右
public ReadPowerTimerTask()
{
if (!f.exists() && f2.exists())
{
f = f2;
isHuawei = true;
}
if (DeviceUtils.getDevModel().startsWith("LG")
&& DeviceUtils.getHardware().equals("g3"))
{
isLGg3 = true;
}
}
@Override
public void run() {
BufferedReader br = null;
try {
FileReader fr = new FileReader(f);
br = new BufferedReader(fr);
String line = "";
while((line = br.readLine()) != null){
int found = 0;
if (line.startsWith("POWER_SUPPLY_VOLTAGE_NOW="))
{
U = line.substring(line.lastIndexOf("=") + 1);
// since 2.1.1 从μV转成mV
long volt = Long.parseLong(U) / 1000;
globalClient.setOutPara(OPU, volt + "mV");
OutPara op = globalClient.getOutPara(OPU);
if (null != op)
{
OpPerfBridge.addHistory(op, U, volt);
}
found++;
}
if (line.startsWith("POWER_SUPPLY_CURRENT_NOW="))
{
I = line.substring(line.lastIndexOf("=") + 1);
// since 2.1.1 从μA转成mA since 2.2.4 华为本身就是mA
long current = Long.parseLong(I);
if (isHuawei)
{
current = -current;
}
else if (isLGg3)
{
current = current >> 1; // 经验值估算LG g3的数据除以2后比较接近真实
}
else
{
current = current / 1000;
}
globalClient.setOutPara(OPI, current + "mA");
OutPara op = globalClient.getOutPara(OPI);
if (null != op)
{
OpPerfBridge.addHistory(op, I, current);
}
found++;
}
if (line.startsWith("POWER_SUPPLY_CAPACITY="))
{
String lastBattery = POW;
POW = line.substring(line.lastIndexOf("=") + 1);
if (! lastBattery.equals(POW)) // 电池百分比变化了
{
if (startBattry != -1)
{
lastBatteryChangeTime = (System.currentTimeMillis() - startBattry)/1000 + "s";
String tempValue = POW + "% | -1% time:" + lastBatteryChangeTime;
globalClient.setOutPara(OPPow, tempValue);
GTLog.logI(LOG_TAG, tempValue);
// 将电量加入历史记录
OutPara op = globalClient.getOutPara(OPPow);
if (null != op)
{
OpPerfBridge.addHistory(op, tempValue, Long.parseLong(POW));
}
}
startBattry = System.currentTimeMillis();
}
globalClient.setOutPara(OPPow, POW + "% | -1% time:" + lastBatteryChangeTime);
found++;
}
if (line.startsWith("POWER_SUPPLY_TEMP="))
{
TEMP = line.substring(line.lastIndexOf("=") + 1);
int iTemp = Integer.parseInt(TEMP);
iTemp = iTemp/10;
if (iTemp > -273)
{
TEMP = iTemp + "℃";
}
globalClient.setOutPara(OPTemp, TEMP);
OutPara op = globalClient.getOutPara(OPTemp);
if (null != op && iTemp != INT_TEMP)
{
OpPerfBridge.addHistory(op, TEMP, iTemp);
GTLog.logI(LOG_TAG, TEMP);
INT_TEMP = iTemp;
}
found++;
}
if (found >= 4)
{
return;
}
}
} catch (Exception e) {
doStop();
}
finally
{
FileUtil.closeReader(br);
}
}
};
}