diff --git a/app/src/main/java/com/huawei/cloudapp/ui/activity/CasCloudPhoneActivity.java b/app/src/main/java/com/huawei/cloudapp/ui/activity/CasCloudPhoneActivity.java
index 3494f9cef125fc7841019b22804c034c45072f41..c525802df5bcabd9ffa40d513640950a2adf723b 100644
--- a/app/src/main/java/com/huawei/cloudapp/ui/activity/CasCloudPhoneActivity.java
+++ b/app/src/main/java/com/huawei/cloudapp/ui/activity/CasCloudPhoneActivity.java
@@ -181,6 +181,10 @@ public class CasCloudPhoneActivity extends FragmentActivity implements IHandleDa
private TextView mNavigationTextView;
private TextView mStatisticsTextView;
private CheckBox mStatisticsCheckBox;
+
+ private TextView mSensorInfoTextView;
+
+ private CheckBox mSensorInfoCheckBox;
private Timer mTimer = new Timer();
private boolean isReadyToExit;
private Toast mToast;
@@ -278,9 +282,26 @@ public class CasCloudPhoneActivity extends FragmentActivity implements IHandleDa
mTimer.schedule(new TimerTask() {
@Override
public void run() {
- runOnUiThread(() -> onUpdateStatisticInfo());
+ runOnUiThread(() -> {
+ onUpdateSensorInfo();
+ onUpdateStatisticInfo();
+ });
+ }
+ }, 1000, 1000);
+
+ mSensorInfoTextView = findViewById(R.id.cas_sensor_view);
+ mSensorInfoTextView.setTextColor(Color.GREEN);
+
+ mSensorInfoCheckBox = findViewById(R.id.cas_sensor_checkBox);
+ mSensorInfoCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ if (isChecked) {
+ mSensorInfoTextView.setVisibility(View.VISIBLE);
+ float density = getResources().getDisplayMetrics().density;
+ mSensorInfoTextView.setHeight((int) (50 * density));
+ } else {
+ mSensorInfoTextView.setVisibility(View.INVISIBLE);
}
- }, 1000, 1000); // 1000 毫秒后执行,之后每隔 1000 毫秒执行一次
+ });
mNavigationTextView = findViewById(R.id.cas_navigaiton);
mNavigationTextView.setOnTouchListener(new View.OnTouchListener() {
@@ -360,6 +381,16 @@ public class CasCloudPhoneActivity extends FragmentActivity implements IHandleDa
mStatisticsTextView.setText(str);
}
+ public void onUpdateSensorInfo() {
+ if (mSensorInfoTextView.getVisibility() != View.VISIBLE) {
+ return;
+ }
+
+ String str = "传感器启停状况>>";
+ str += mCloudPhone.getSensorStatusInfo();
+ mSensorInfoTextView.setText(str);
+ }
+
/**
* Activity:onStart
*/
@@ -732,6 +763,10 @@ public class CasCloudPhoneActivity extends FragmentActivity implements IHandleDa
return;
}
CASLog.d(TAG, "stop cloud phone");
+ if (mTimer != null) {
+ mTimer.cancel();
+ mTimer = null;
+ }
handler.removeCallbacksAndMessages(null);
mIsStopCloudPhoneCalled = true;
mProgressBar.setVisibility(View.VISIBLE);
diff --git a/app/src/main/res/layout/cas_activity_fullscreen.xml b/app/src/main/res/layout/cas_activity_fullscreen.xml
index f170d41be6a4fe2a3aa44692e9c778a827ba4cd1..dd685cb17503954d1927851601d3f22c34d574f1 100644
--- a/app/src/main/res/layout/cas_activity_fullscreen.xml
+++ b/app/src/main/res/layout/cas_activity_fullscreen.xml
@@ -24,18 +24,37 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="165dp"
+ android:layout_marginStart="20dp"
+ android:layout_gravity="start" />
+
+
+
+
GetCmdSendStats(&cmdSendStats)) {
+ WARN("GetCmdSendStats failed");
+ } else {
+ stream << "指令发送码率(需操作) : " << cmdSendStats.encBitrate << "kbps" << std::endl;
+ }
}
#endif
stream << "帧率 : " << GetCurrentFPS() << "fps" << std::endl;
diff --git a/cloudphone/src/main/cpp/libs/Arm64/libmtrans.a b/cloudphone/src/main/cpp/libs/Arm64/libmtrans.a
index af361d9ba15ba74d1dd334dee88284ea8cca3b87..1306a9e703a6f76f085da496d2aef1022cb0e303 100644
Binary files a/cloudphone/src/main/cpp/libs/Arm64/libmtrans.a and b/cloudphone/src/main/cpp/libs/Arm64/libmtrans.a differ
diff --git a/cloudphone/src/main/cpp/libs/mtrans/include/net_trans.h b/cloudphone/src/main/cpp/libs/mtrans/include/net_trans.h
index 6b11c44a087f2c447a03e5fd94dee624a10087e6..c7029119c7b8f5b21f454527ce04baa4cf6c3c23 100644
--- a/cloudphone/src/main/cpp/libs/mtrans/include/net_trans.h
+++ b/cloudphone/src/main/cpp/libs/mtrans/include/net_trans.h
@@ -54,6 +54,7 @@ public:
int GetVideoRecvStats(StreamRecvStats* stats);
int GetAudioRecvStats(StreamRecvStats* stats);
int GetRtt();
+ int GetCmdSendStats(StreamSendStats* stats);
private:
class NetTransPri;
diff --git a/cloudphone/src/main/cpp/libs/mtrans/include/net_trans_def.h b/cloudphone/src/main/cpp/libs/mtrans/include/net_trans_def.h
index f5c4331975f6fe04a45d8c525cd51a28fa6dd51e..cd9af0b8e1ae07e816114ac534e2a4c4b4627875 100644
--- a/cloudphone/src/main/cpp/libs/mtrans/include/net_trans_def.h
+++ b/cloudphone/src/main/cpp/libs/mtrans/include/net_trans_def.h
@@ -115,6 +115,33 @@ struct StreamRecvStats {
};
};
+struct VideoSendStats {
+ uint32_t sendFrameRate;
+ uint32_t availableEncBitrate;
+ uint32_t inputFrameCnt;
+ uint32_t sendFrameCnt;
+ uint32_t redRate;
+ uint32_t recvKeyRequestCnt;
+ uint32_t recvNackRequestCnt;
+ uint32_t nackResponsePktCnt;
+ uint32_t nackNotRspCnt;
+};
+
+struct StreamSendStats {
+ uint32_t encBitrate;
+ uint32_t fecBitrate;
+ uint32_t arqBitrate;
+ uint32_t packetRate;
+ uint32_t rtt;
+ uint32_t remoteJitter;
+ uint32_t remoteLostRate;
+ uint32_t pacingSendMaxDelay;
+ uint32_t pacingSendAveDelay;
+ uint32_t periodNotSendPktCnt;
+ uint64_t periodNotSendPktTime;
+ VideoSendStats videoStats;
+};
+
typedef int32_t (*RecvVideoDataCallback)(uint8_t* data, uint32_t length);
typedef int32_t (*RecvAudioDataCallback)(uint8_t* data, uint32_t length);
typedef int32_t (*RecvAudioDecodeCallback)(int32_t streamId, AudioJbDecode* audioJbDecode);
diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/api/ICloudPhone.java b/cloudphone/src/main/java/com/huawei/cloudphone/api/ICloudPhone.java
index dfb1c5db1f699f474b0654f6253de29fb238052a..dc0f818ff6ea4c0a54cbf6257d5a78dcdf18b3cf 100644
--- a/cloudphone/src/main/java/com/huawei/cloudphone/api/ICloudPhone.java
+++ b/cloudphone/src/main/java/com/huawei/cloudphone/api/ICloudPhone.java
@@ -154,4 +154,6 @@ public interface ICloudPhone {
int getState();
String getVideoStatisticInfo();
+
+ String getSensorStatusInfo();
}
diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java b/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java
index 734f7e06efc6ecddef4b39a907386ead85c944b4..1f2ed91eebbae317460619f5fe5c23c9aa2fd828 100644
--- a/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java
+++ b/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java
@@ -57,6 +57,7 @@ import com.huawei.cloudphone.virtualdevice.camera.VirtualCameraManager;
import com.huawei.cloudphone.virtualdevice.common.RingBufferVirtualDeviceIO;
import com.huawei.cloudphone.virtualdevice.common.VirtualDeviceManager;
import com.huawei.cloudphone.virtualdevice.common.VirtualDeviceProtocol;
+import com.huawei.cloudphone.virtualdevice.sensor.VirtualSensorManager;
import java.util.HashMap;
import java.util.Map;
@@ -67,6 +68,7 @@ import static android.view.KeyEvent.KEYCODE_BACK;
import static android.view.KeyEvent.KEYCODE_VOLUME_DOWN;
import static android.view.KeyEvent.KEYCODE_VOLUME_UP;
import static com.huawei.cloudphone.api.CloudPhoneParas.DEV_TYPE_CAMERA;
+import static com.huawei.cloudphone.api.CloudPhoneParas.DEV_TYPE_SENSOR;
import static com.huawei.cloudphone.api.CloudPhoneParas.DisplayMode.DISPLAY_MODE_FILL;
import static com.huawei.cloudphone.common.CasState.CAS_CONNECT_EXCEPTION;
import static com.huawei.cloudphone.utils.CasMediaUtils.isValidMediaConfig;
@@ -355,6 +357,19 @@ public class CloudPhoneImpl implements ICloudPhone {
}
}
+ @Override
+ public String getSensorStatusInfo() {
+ VirtualDeviceProtocol virtualDevice = mVirtualDeviceSession.getVirtualDevice();
+ if (virtualDevice == null) {
+ return "";
+ }
+ VirtualDeviceManager virtualDeviceManager = virtualDevice.getVirtualDeviceManager(DEV_TYPE_SENSOR);
+ if (virtualDeviceManager == null) {
+ return "";
+ }
+ return ((VirtualSensorManager) virtualDeviceManager).getSensorStatus();
+ }
+
@Override
public int getState() {
return mCurrentState;
diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/virtualdevice/sensor/VirtualSensor.java b/cloudphone/src/main/java/com/huawei/cloudphone/virtualdevice/sensor/VirtualSensor.java
index 4c148529af95cf5a9cb41a3400b0639cbb9f18fd..303e56ed0d47168ded34b602dbe33255a4634d90 100644
--- a/cloudphone/src/main/java/com/huawei/cloudphone/virtualdevice/sensor/VirtualSensor.java
+++ b/cloudphone/src/main/java/com/huawei/cloudphone/virtualdevice/sensor/VirtualSensor.java
@@ -23,11 +23,9 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
-import com.huawei.cloudphone.common.CASLog;
import com.huawei.cloudphone.virtualdevice.common.IVirtualDeviceDataListener;
-import com.huawei.cloudphone.virtualdevice.common.VirtualDeviceProtocol;
-import java.util.Arrays;
+import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -43,10 +41,56 @@ public class VirtualSensor implements SensorEventListener {
private boolean mIsStart = false;
private Map mSensorMap = new HashMap<>();
+ private Map mSensorActiveMap = new HashMap<>();
+
+ private Map mSensorTypeToNameMap = new HashMap(){{
+
+ put(Sensor.TYPE_PROXIMITY, "接近传感器");
+ put(Sensor.TYPE_GRAVITY, "重力传感器");
+ put(Sensor.TYPE_LINEAR_ACCELERATION, "线性加速度传感器");
+ put(Sensor.TYPE_ROTATION_VECTOR, "旋转矢量传感器");
+ put(Sensor.TYPE_RELATIVE_HUMIDITY, "湿度传感器");
+ put(Sensor.TYPE_AMBIENT_TEMPERATURE, "温度传感器");
+ put(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, "未校准磁力传感器");
+ put(Sensor.TYPE_GAME_ROTATION_VECTOR, "游戏矢量传感器");
+ put(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, "未校准陀螺仪");
+ put(Sensor.TYPE_SIGNIFICANT_MOTION, "大幅动作传感器");
+ put(Sensor.TYPE_STEP_DETECTOR, "步数检测器");
+ put(Sensor.TYPE_STEP_COUNTER, "计步器");
+ put(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, "地磁旋转矢量传感器");
+ put(Sensor.TYPE_HEART_RATE, "心率传感器");
+ put(Sensor.TYPE_POSE_6DOF, "6向姿势传感器");
+ put(Sensor.TYPE_STATIONARY_DETECT, "静止检测传感器");
+ put(Sensor.TYPE_MOTION_DETECT, "运动检测传感器");
+ put(Sensor.TYPE_HEART_BEAT, "心跳传感器");
+ put(Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, "低延迟离开身体检测");
+ put(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED, "未校准加速度传感器");
+ put(Sensor.TYPE_ACCELEROMETER, "加速度传感器");
+ put(Sensor.TYPE_MAGNETIC_FIELD, "磁力传感器");
+ put(Sensor.TYPE_ORIENTATION, "方向传感器");
+ put(Sensor.TYPE_GYROSCOPE, "陀螺仪");
+ put(Sensor.TYPE_LIGHT, "光线传感器");
+ put(Sensor.TYPE_PRESSURE, "压力传感器");
+ put(Sensor.TYPE_TEMPERATURE, "温度传感器2");
+ put(22, "倾斜检测传感器");
+ put(23, "手势唤醒传感器");
+ put(24, "快览手势传感器");
+ put(25, "唤醒手势传感器");
+ put(26, "抬腕倾斜传感器");
+ put(27, "设备方向传感器");
+ }};
public VirtualSensor(SensorManager sensorManager) {
mSensorManager = sensorManager;
mAccelerationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ List sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ for (Sensor sensor: sensorList) {
+ int type = sensor.getType();
+ if (type >= Sensor.TYPE_DEVICE_PRIVATE_BASE) {
+ continue;
+ }
+ mSensorActiveMap.put(type, false);
+ }
}
void registerSensorDataListener(IVirtualDeviceDataListener listener) {
@@ -75,6 +119,10 @@ public class VirtualSensor implements SensorEventListener {
public void startProcess(short sensorId) {
Log.i(TAG, "register sensor id " + sensorId);
+
+ if (mSensorActiveMap.containsKey((int) sensorId)) {
+ mSensorActiveMap.replace((int) sensorId, true);
+ }
if (sensorId == 1) {
mSensorManager.registerListener(this, mAccelerationSensor, SensorManager.SENSOR_DELAY_GAME, mHandler);
return;
@@ -85,6 +133,11 @@ public class VirtualSensor implements SensorEventListener {
public void stopProcess(short sensorId) {
Log.i(TAG, "unregister sensor id " + sensorId);
+
+ if (mSensorActiveMap.containsKey((int) sensorId)) {
+ mSensorActiveMap.replace((int) sensorId, false);
+ }
+
if (sensorId == 1) {
mSensorManager.unregisterListener(this, mAccelerationSensor);
}
@@ -92,6 +145,26 @@ public class VirtualSensor implements SensorEventListener {
mSensorManager.unregisterListener(this, mSensor);
}
+ public String getSensorStatus() {
+ StringBuilder status = new StringBuilder();
+
+ for (Map.Entry entry : mSensorActiveMap.entrySet()) {
+ status.append("\n");
+ status.append(getSensorNameByType(entry.getKey()));
+ status.append(" : ");
+ if (entry.getValue()) {
+ status.append("启用");
+ } else {
+ status.append("关闭");
+ }
+ }
+ return status.toString();
+ }
+
+ private String getSensorNameByType(Integer type) {
+ return mSensorTypeToNameMap.getOrDefault(type, type.toString());
+ }
+
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
if (mListener == null) {
diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/virtualdevice/sensor/VirtualSensorManager.java b/cloudphone/src/main/java/com/huawei/cloudphone/virtualdevice/sensor/VirtualSensorManager.java
index f93ce01034d8bb5c6d61394a5a3e6d61867e3421..40410e7dd3580228ab3fed7e01af7eeea8b6ab5a 100644
--- a/cloudphone/src/main/java/com/huawei/cloudphone/virtualdevice/sensor/VirtualSensorManager.java
+++ b/cloudphone/src/main/java/com/huawei/cloudphone/virtualdevice/sensor/VirtualSensorManager.java
@@ -24,7 +24,6 @@ import android.hardware.SensorEvent;
import android.hardware.SensorManager;
import android.util.Log;
-import com.huawei.cloudphone.common.CASLog;
import com.huawei.cloudphone.virtualdevice.common.IVirtualDeviceDataListener;
import com.huawei.cloudphone.virtualdevice.common.VirtualDeviceManager;
import com.huawei.cloudphone.virtualdevice.common.VirtualDeviceProtocol;
@@ -100,6 +99,10 @@ public class VirtualSensorManager extends VirtualDeviceManager {
mVirtualSensor.stop();
}
+ public String getSensorStatus() {
+ return mVirtualSensor.getSensorStatus();
+ }
+
class SensorDataListener implements IVirtualDeviceDataListener {
@Override
public void onRecvData(Object... args) {