/*
* 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.manager;
import android.content.Context;
import com.tencent.wstt.gt.Functions;
import com.tencent.wstt.gt.GTApp;
import com.tencent.wstt.gt.OutPara;
import com.tencent.wstt.gt.plugin.battery.GTBatteryEngine;
import com.tencent.wstt.gt.ui.model.ChangedListener;
import com.tencent.wstt.gt.ui.model.TagTimeEntry;
import com.tencent.wstt.gt.ui.model.ThresholdEntry;
import com.tencent.wstt.gt.utils.StringUtil;
import com.tencent.wstt.gt.utils.ToastUtil;
/**
* 输出参数与性能模块对接的桥,便于后续重构
* TODO 后续重构:性能模块需要能区分出出参所属的Client,而不是只由参数名作为key
*/
public class OpPerfBridge {
private static OpPerfManager opPerfManager = OpPerfManager.getInstance();
private static OpWarningManager opWarningManager = OpWarningManager.getInstance();
/**
* 要保证每个出参生成的时候key都是有区分的应该就行,在客户端就需要定下来的hash法
* @param key
* @return
*/
public static TagTimeEntry getProfilerData(String key)
{
return opPerfManager.get(key);
}
public static TagTimeEntry[] getAllProfilerData()
{
return opPerfManager.getAll();
}
/**
* 获取所有非disable态出参对应的性能对象数组
* @return
*/
public static TagTimeEntry[] getAllEnableProfilerData()
{
return opPerfManager.getAllEnable();
}
public static void removeProfilerData(String key)
{
opPerfManager.remove(key);
}
public static void startProfier(OutPara outPara, int funcId, String desc, String unit)
{
if (outPara == null)
{
return;
}
outPara.hasMonitorOnce = true;
TagTimeEntry profilerEntry = opPerfManager.get(outPara.getKey());
if (null == profilerEntry)
{
profilerEntry = new TagTimeEntry(null);
profilerEntry.setName(outPara.getKey());
profilerEntry.setAlias(outPara.getAlias());
profilerEntry.setFunctionId(funcId);
profilerEntry.setDesc(desc);
profilerEntry.setUnit(unit);
profilerEntry.setExkey(ClientManager.getInstance().getClientKey(outPara.getClient()));
opPerfManager.add(profilerEntry);
}
}
/**
* 多维的启动性能统计,在UI上也需要展示多条曲线
* @param key
* @param funcId
*/
public static void startProfier(
OutPara outPara, String[] subKeys, int[] funcIds, String desc, String unit)
{
if (outPara == null)
{
return;
}
outPara.hasMonitorOnce = true;
TagTimeEntry profilerEntry = opPerfManager.get(outPara.getKey());
if (null == profilerEntry)
{
profilerEntry = new TagTimeEntry(null);
profilerEntry.setName(outPara.getKey());
profilerEntry.setAlias(outPara.getAlias());
profilerEntry.setFunctionId(funcIds[0]);
profilerEntry.setDesc(desc);
profilerEntry.setUnit(unit);
profilerEntry.setExkey(ClientManager.getInstance().getClientKey(outPara.getClient()));
profilerEntry.initChildren(subKeys.length);
int i = 0;
for (TagTimeEntry subEntry : profilerEntry.getSubTagEntrys())
{
subEntry.setName(subKeys[i]);
subEntry.setFunctionId(funcIds[i]);
i++;
}
opPerfManager.add(profilerEntry);
}
}
/**
* 目前do nothing
* @param op
*/
public static void endProfier(OutPara op)
{
}
public static void setThreshold(String key, ThresholdEntry threshold)
{
TagTimeEntry profilerEntry = opPerfManager.get(key);
if (null == profilerEntry)
{
return;
}
profilerEntry.setThresholdEntry(threshold);
}
public static void addHistory(OutPara op, String nowValue, long data)
{
// 要在总控开关打开的前提下才要进行历史记录
if (! OpUIManager.gw_running)
{
return;
}
TagTimeEntry profilerEntry = opPerfManager.get(op.getKey());
if (null == profilerEntry)
{
return;
}
if (op.isMonitor()) // 有历史出参的告警
{
int seq = profilerEntry.add(data);
// 阈值对象对本次输入值进行是否预备告警的记录
profilerEntry.getThresholdEntry().add(data, seq);
profilerEntry.setLastValue(nowValue);
}
else
{
// 不记录历史数据的情况下统计告警,暂不使用
// profilerEntry.getThresholdEntry().add(data);
}
}
public static void addHistory(OutPara op, String nowValue, long time, long data)
{
// 要在总控开关打开的前提下才要进行历史记录
if (! OpUIManager.gw_running)
{
return;
}
TagTimeEntry profilerEntry = opPerfManager.get(op.getKey());
if (null == profilerEntry)
{
return;
}
if (op.isMonitor()) // 有历史出参的告警
{
int seq = profilerEntry.add(time, data);
// 阈值对象对本次输入值进行是否预备告警的记录
profilerEntry.getThresholdEntry().add(data, seq);
profilerEntry.setLastValue(nowValue);
}
else
{
// 不记录历史数据的情况下统计告警,暂不使用
// profilerEntry.getThresholdEntry().add(data);
}
}
/**
* 多维的历史数据,在UI上也需要展示多条曲线
* @param key 对应出参的key
* @param opValue 原始出参值
* @param data 对应多维数据的值数组
*/
public static void addHistory(OutPara parentOp, String nowValue, long[] data)
{
// 要在总控开关打开的前提下才要进行历史记录
if (! OpUIManager.gw_running)
{
return;
}
TagTimeEntry profilerEntry = opPerfManager.get(parentOp.getKey());
if (null == profilerEntry)
{
return;
}
if (parentOp.isMonitor()) // 有历史出参的告警
{
profilerEntry.setLastValue(nowValue);
int i = 0;
for (TagTimeEntry subEntry : profilerEntry.getChildren())
{
int seq = subEntry.add(data[i]);
// 阈值对象对本次输入值进行是否预备告警的记录
subEntry.getThresholdEntry().add(data[i], seq);
i++;
}
}
else // 没有记录历史出参的告警
{
int i = 0;
for (TagTimeEntry subEntry : profilerEntry.getChildren())
{
// 阈值对象对本次输入值进行是否预备告警的记录,暂不使用
subEntry.getThresholdEntry().add(data[i]);
i++;
}
}
}
// 全局的
public static OpWarningManager getOpWarningManager()
{
return opWarningManager;
}
/**
* @since 2.2
* 这个方法的实际作用是开始监控,并对要监控的出参的不同特点进行不同设置,
* 放在这里统一处理也是弥补两个方面问题:
* 1.客户端和服务端出参对象为了尽量一致,不带有性能统计对象属性,而本期不会对性能统计UI进行变更
* 2.职责是面向单位和是否多曲线,没有性能压力,就聚合在一个方法里处理了
* @param ov
*/
public static void registMonitor(OutPara ov) {
String key = ov.getKey();
if (ov.hasMonitorOnce) {
return;
}
Context context = GTApp.getContext();
if (key.equals("MEM")) {
OpPerfBridge.startProfier(ov,
Functions.PERF_DIGITAL_NORMAL, "ALL Used Memory(MB)", "MB");
} else if (key.equals("CPU")) {
OpPerfBridge.startProfier(ov, Functions.PERF_DIGITAL_CPU,
"ALL CPU occupy", "%");
} else if (key.equals("NET")) {
int[] funIds = { Functions.PERF_DIGITAL_MULT,
Functions.PERF_DIGITAL_MULT};
String[] subKeys = { "transmitted", "received"};
OpPerfBridge.startProfier(ov,
subKeys,funIds, "", "KB");
} else if (key.equals("Signal")) {
String[] sigSubKeys = { "net", "wifi" };
int[] sigFuncIds = { Functions.PERF_DIGITAL_MULT,
Functions.PERF_DIGITAL_MULT };
OpPerfBridge.startProfier(ov, sigSubKeys, sigFuncIds, "", "dbm");
}else if (key.equals("FPS")) {
OpPerfBridge.startProfier(ov,
Functions.PERF_DIGITAL_NORMAL, "FPS", "");
/*
* 插件的,需要转换成mV
*/
} else if (key.equals(GTBatteryEngine.OPU)) // 电压值,在GTBatteryActivity中定义的
{
OpPerfBridge.startProfier(ov,
Functions.PERF_DIGITAL_VOLT, "Volt value(mV)", "mV");
}
/*
* 插件的Pow,也要支持记录历史记录
*/
else if (key.equals(GTBatteryEngine.OPPow)) // 电压值,在GTBatteryActivity中定义的
{
OpPerfBridge.startProfier(ov,
Functions.PERF_DIGITAL_NORMAL, "Power value(%)", "%");
}
else {
String value = ov.getValue();
// value是空字符串时,经常是还没开始统计,这时不应该判定为不可监控
if (StringUtil.isNumeric(value) || "".equals(value)) {
OpPerfBridge.startProfier(ov,
Functions.PERF_DIGITAL_NORMAL, "", "");
} else {
// 非数字的不可监控
ov.setMonitor(false);
ov.hasMonitorOnce = false;
ToastUtil.ShowShortToast(context,
"observable OutPara value must be digit.");
return;
}
}
ov.hasMonitorOnce = true;
}
public static void setOutparaChangedListener(String smName,
ChangedListener changedListener) {
TagTimeEntry tte = getProfilerData(smName);
tte.setChangedListener(changedListener);
}
}