diff --git a/README.md b/README.md index 42c1879237650f49ab2a606130e89ad27c62f4ac..2e3f39ce25f46d5b9fa95a057c12803f342985eb 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ### 2. 组件交互 -![](http://image.huawei.com/tiny-lts/v1/images/457be9622fdd021c1fb5c9ac0531b770_565x427.png) +![](res/组件交互.png) 1. SDK->RemoteServer: 客户端SDK向后端server请求一个空闲云机实例 2. RemoteServer->SDK: 后端server按需求找到一个空闲云机实例信息返回给客户端SDK diff --git a/cloudphone/src/main/aidl/com/huawei/cloudphone/ICASAidlInterface.aidl b/cloudphone/src/main/aidl/com/huawei/cloudphone/ICASAidlInterface.aidl index 561f92e280aef55202820acee091f9aecd7d6c94..21b9d451e151403692b9110c0b85524424bbf284 100644 --- a/cloudphone/src/main/aidl/com/huawei/cloudphone/ICASAidlInterface.aidl +++ b/cloudphone/src/main/aidl/com/huawei/cloudphone/ICASAidlInterface.aidl @@ -52,7 +52,7 @@ interface ICASAidlInterface { void unregisterListener(); - boolean sendTouchEvent(in int id, in int action, in int x, in int y, in int pressure); + boolean sendTouchEvent(in int id, in int action, in int x, in int y, in int pressure, long time, int orientation, int height, int width); boolean sendKeyEvent(int keycode, int action); diff --git a/cloudphone/src/main/cpp/CasController.cpp b/cloudphone/src/main/cpp/CasController.cpp index 0b46d5944b0ea503860530619900ccf9f72013ec..02bbf973cbbf8919fd93eeb08870c9ca59252403 100644 --- a/cloudphone/src/main/cpp/CasController.cpp +++ b/cloudphone/src/main/cpp/CasController.cpp @@ -674,8 +674,9 @@ uint64_t CasController::GetLag() return 0; } -bool CasController::SendTouchEvent(int id, int action, int x, int y, int pressure) +bool CasController::SendTouchEvent(int id, int action, int x, int y, int pressure, long time, int orientation, int height, int width) { + int new_time = (int) time; std::lock_guard lockGuard(this->m_lock); if (this->GetState() == STOPPED) { INFO("Failed to send touch event because phone already stop."); @@ -689,7 +690,7 @@ bool CasController::SendTouchEvent(int id, int action, int x, int y, int pressur if (m_touch == nullptr) { return false; } - return m_touch->SendTouchEvent(id, action, x, y, pressure); + return m_touch->SendTouchEvent(id, action, x, y, pressure, new_time, orientation, height, width); } bool CasController::SendKeyEvent(uint16_t keycode, uint16_t action) diff --git a/cloudphone/src/main/cpp/CasController.h b/cloudphone/src/main/cpp/CasController.h index f7d61dba07abdda5ef9af1fd1cdd72e52c62e225..8711702b49e9becb18cf4c0d08e30326a5447422 100644 --- a/cloudphone/src/main/cpp/CasController.h +++ b/cloudphone/src/main/cpp/CasController.h @@ -53,7 +53,7 @@ public: void SetJniConf(std::string key, std::string value); - bool SendTouchEvent(int id, int action, int x, int y, int pressure); + bool SendTouchEvent(int id, int action, int x, int y, int pressure, long time, int orientation, int height, int width); bool SendKeyEvent(uint16_t keycode, uint16_t action); diff --git a/cloudphone/src/main/cpp/CasJniBridge.cpp b/cloudphone/src/main/cpp/CasJniBridge.cpp index ecf9ae1de148cfc6f71ff0b9630d05bf084d9c4b..8c4afd104b5af1845488d2bd633147963b79bc22 100644 --- a/cloudphone/src/main/cpp/CasJniBridge.cpp +++ b/cloudphone/src/main/cpp/CasJniBridge.cpp @@ -178,9 +178,9 @@ extern "C" JNIEXPORT jint JNICALL JNI(sendData)(JNIEnv *env, jclass clazz, jbyte } extern "C" JNIEXPORT jboolean JNICALL JNI(sendTouchEvent)(JNIEnv *env, jclass, jint id, jint action, jint x, jint y, - jint pressure) + jint pressure, jlong time, jint orientation, jint height, jint width) { - if (gJniApiCtrl->SendTouchEvent(id, action, x, y, pressure)) { + if (gJniApiCtrl->SendTouchEvent(id, action, x, y, pressure, time, orientation, height, width)) { return JNI_TRUE; } return JNI_FALSE; diff --git a/cloudphone/src/main/cpp/CasJniBridge.h b/cloudphone/src/main/cpp/CasJniBridge.h index 6cfa4da0d395fe4fd4f2630822b5ac4171b0e3b3..47a4c8d78b5e081bef95cf070e2e09c6e05125f7 100644 --- a/cloudphone/src/main/cpp/CasJniBridge.h +++ b/cloudphone/src/main/cpp/CasJniBridge.h @@ -40,7 +40,8 @@ JNIEXPORT jint JNICALL JNI(recvData)(JNIEnv *env, jclass, jbyte type, jbyteArray JNIEXPORT jint JNICALL JNI(sendData)(JNIEnv *env, jclass clazz, jbyte type, jbyteArray data, jint length); -JNIEXPORT jboolean JNICALL JNI(sendTouchEvent)(JNIEnv *env, jclass, int id, int action, int x, int y, int pressure); +JNIEXPORT jboolean JNICALL JNI(sendTouchEvent)(JNIEnv *env, jclass, int id, int action, int x, int y, int pressure, jlong time, + jint orientation, jint height, jint width); JNIEXPORT jboolean JNICALL JNI(sendKeyEvent)(JNIEnv *env, jclass, jint keycode, jint action); diff --git a/cloudphone/src/main/cpp/cas_common/CasMsg.h b/cloudphone/src/main/cpp/cas_common/CasMsg.h index 6414caf0d9f07f37a5ad8224bd4e706d4430cc5b..b4a5d9a2f55f93a3fb16e8ecb703dbd9944cdfab 100644 --- a/cloudphone/src/main/cpp/cas_common/CasMsg.h +++ b/cloudphone/src/main/cpp/cas_common/CasMsg.h @@ -84,7 +84,11 @@ typedef struct CasTouchEventMsg { uint16_t x; uint16_t y; uint16_t pressure; -} __packed CasTouchEventMsg; + int32_t time; + uint8_t orientation; + uint16_t height; + uint16_t width; +} __attribute__((packed)) cas_touch_event_msg_t; // 客户端遥控器指令消息体 typedef struct CasKeyEventMsg { diff --git a/cloudphone/src/main/cpp/cas_service/CasTouch.cpp b/cloudphone/src/main/cpp/cas_service/CasTouch.cpp index 3ca0d08eae77ba31e609dfac0bdeee2e1f980855..ca182ec00c4edd23da1f1c02385a46ae3e654984 100644 --- a/cloudphone/src/main/cpp/cas_service/CasTouch.cpp +++ b/cloudphone/src/main/cpp/cas_service/CasTouch.cpp @@ -31,7 +31,7 @@ void CasTouch::Init(CasSocket *casSocket) m_streamBuildSender = new CasStreamBuildSender(casSocket); } -bool CasTouch::SendTouchEvent(int id, int action, int x, int y, int pressure) +bool CasTouch::SendTouchEvent(int id, int action, int x, int y, int pressure, int time, int orientation, int height, int width) { CasTouchEventMsg touchEventMsg; touchEventMsg.id = static_cast(id); @@ -39,7 +39,12 @@ bool CasTouch::SendTouchEvent(int id, int action, int x, int y, int pressure) touchEventMsg.x = (unsigned short)htons(x); touchEventMsg.y = (unsigned short)htons(y); touchEventMsg.pressure = (unsigned short)htons(pressure); - + touchEventMsg.time = htonl(time); + touchEventMsg.orientation = static_cast(orientation); + touchEventMsg.height = (unsigned short)htons(height); + touchEventMsg.width = (unsigned short)htons(width); + DBG("time : %d", time); + if (m_streamBuildSender == nullptr) { return false; } diff --git a/cloudphone/src/main/cpp/cas_service/CasTouch.h b/cloudphone/src/main/cpp/cas_service/CasTouch.h index c1e22146e4586c4d77670d7fba60f5a255355bc3..c12ec48c31ec2c99e575debc6a3c876b016a4e64 100644 --- a/cloudphone/src/main/cpp/cas_service/CasTouch.h +++ b/cloudphone/src/main/cpp/cas_service/CasTouch.h @@ -27,7 +27,7 @@ public: void Init(CasSocket *casSocket); - bool SendTouchEvent(int id, int action, int x, int y, int pressure); + bool SendTouchEvent(int id, int action, int x, int y, int pressure, int time, int orientation, int height, int width); bool SendKeyEvent(uint16_t keycode, uint16_t action); 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 ca6d21cf730abd55f3c83ee90f435d5d9abc7bf3..3bec08737e92e67189c08ca396dceee313e72f9d 100644 --- a/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java +++ b/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java @@ -35,6 +35,7 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; +import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -64,6 +65,7 @@ import java.util.TimerTask; 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 android.view.KeyEvent.META_ALT_ON; 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; @@ -125,6 +127,10 @@ public class CloudPhoneImpl implements ICloudPhone { private boolean mIsNewCreated = false; private boolean mReconnecting = false; private int mBgTimeout = 60 * 1000; + private int mTouchCount = 0; + private VelocityTracker mVelocityTracker = VelocityTracker.obtain(); + + private long initTime = 0; public CloudPhoneImpl() { mCurrentState = STATE_DEINIT; @@ -398,20 +404,30 @@ public class CloudPhoneImpl implements ICloudPhone { int rawY; int pressure; int index; - + long time; + if (action == MotionEvent.ACTION_DOWN) { + initTime = event.getEventTime(); + } switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: + if (action == MotionEvent.ACTION_DOWN) { + mTouchCount = 1; + } else if (action == MotionEvent.ACTION_UP) { + mTouchCount ++; + CASLog.i(TAG, "mTouchCount = " +mTouchCount); + } action = event.getActionMasked(); index = event.getActionIndex(); id = event.getPointerId(index); pressure = (int) (event.getPressure(event.getActionIndex()) / ratio); rawX = (int) event.getX(index); rawY = (int) event.getY(index); - result = sendTouchEvent(id, action, rawX, rawY, pressure); + time = event.getEventTime() - initTime; + result = sendTouchEvent(id, action, rawX, rawY, pressure, time); break; case MotionEvent.ACTION_MOVE: final int historySize = event.getHistorySize(); @@ -422,7 +438,9 @@ public class CloudPhoneImpl implements ICloudPhone { rawX = (int) event.getHistoricalX(j, i); rawY = (int) event.getHistoricalY(j, i); pressure = (int) (event.getHistoricalPressure(j, i) / ratio); - result = sendTouchEvent(id, action, rawX, rawY, pressure); + time = event.getHistoricalEventTime(i) - initTime; + result = sendTouchEvent(id, action, rawX, rawY, pressure, time); + mTouchCount ++; } } for (int i = 0; i < pointerCount; i++) { @@ -430,7 +448,9 @@ public class CloudPhoneImpl implements ICloudPhone { rawX = (int) event.getX(i); rawY = (int) event.getY(i); pressure = (int) (event.getPressure(i) / ratio); - result = sendTouchEvent(id, action, rawX, rawY, pressure); + time = event.getEventTime() - initTime; + result = sendTouchEvent(id, action, rawX, rawY, pressure, time); + mTouchCount ++; } break; default: @@ -632,10 +652,9 @@ public class CloudPhoneImpl implements ICloudPhone { } } - private boolean sendTouchEvent(int id, int action, final int x1, final int y1, final int pressure) { - int x = 0; - int y = 0; + private boolean sendTouchEvent(int id, int action, final int x1, final int y1, final int pressure, long time) { int orientation = 0; + int new_orientation = 0; if (mActivity != null) { try { orientation = mActivity.getRequestedOrientation(); @@ -648,43 +667,24 @@ public class CloudPhoneImpl implements ICloudPhone { switch (orientation) { case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: - x = (int) (x1 / mInputXScale); - y = (int) (y1 / mInputYScale); + new_orientation = 0; break; case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: - x = (int) ((mDisplayHeight - y1) / mInputXScale); - y = (int) (x1 / mInputYScale); + new_orientation = 1; break; case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: - x = (int) ((mDisplayHeight - y1) / (mInputXScale)); - y = (int) ((mDisplayWidth - x1) / (mInputYScale)); + new_orientation = 2; break; case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: - x = (int) (y1 / mInputXScale); - y = (int) ((mDisplayWidth - x1) / mInputYScale); + new_orientation = 3; break; default: CASLog.i(TAG, "invalid directation " + orientation); break; } - if (action == MotionEvent.ACTION_MOVE) { - if (x < 0) { - x = 0; - action = MotionEvent.ACTION_CANCEL; - } else if (x > 720) { - x = 720; - action = MotionEvent.ACTION_CANCEL; - } - if (y < 0) { - y = 0; - action = MotionEvent.ACTION_CANCEL; - } else if (y > 1280) { - y = 1280; - action = MotionEvent.ACTION_CANCEL; - } - } - return mCASClient.sendTouchEvent(id, action, x, y, pressure); + + return mCASClient.sendTouchEvent(id, action, x1, y1, pressure, time, new_orientation, mDisplayHeight, mDisplayWidth); } public static class JNIState { diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/jniwrapper/JNIWrapper.java b/cloudphone/src/main/java/com/huawei/cloudphone/jniwrapper/JNIWrapper.java index f9d626541d1de10350b33a0298550c198191aea2..ccf80ac4da73ba1dc62e37e38f8d975328651e78 100644 --- a/cloudphone/src/main/java/com/huawei/cloudphone/jniwrapper/JNIWrapper.java +++ b/cloudphone/src/main/java/com/huawei/cloudphone/jniwrapper/JNIWrapper.java @@ -64,7 +64,7 @@ public class JNIWrapper { public static native int sendData(byte type, byte[] data, int length); - public static native boolean sendTouchEvent(final int id, final int action, final int x1, final int y1, final int pressure); + public static native boolean sendTouchEvent(final int id, final int action, final int x1, final int y1, final int pressure, long time, int orientation, int height, int width); public static native boolean sendKeyEvent(final int keycode, final int action); diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/jniwrapper/JniBridge.java b/cloudphone/src/main/java/com/huawei/cloudphone/jniwrapper/JniBridge.java index 9833f7589f19ba10237142e08eaa61f555d429ea..566e030f3f8f1bfb0f3ab03231f147e34be8fb1b 100644 --- a/cloudphone/src/main/java/com/huawei/cloudphone/jniwrapper/JniBridge.java +++ b/cloudphone/src/main/java/com/huawei/cloudphone/jniwrapper/JniBridge.java @@ -41,8 +41,8 @@ public class JniBridge { return JNIWrapper.recvData(type, data, length); } - public boolean sendTouchEvent(final int id, final int action, final int x1, final int y1, final int pressure) { - return JNIWrapper.sendTouchEvent(id, action, x1, y1, pressure); + public boolean sendTouchEvent(final int id, final int action, final int x1, final int y1, final int pressure, long time, int orientation, int height, int width) { + return JNIWrapper.sendTouchEvent(id, action, x1, y1, pressure, time, orientation, height, width); } public boolean sendKeyEvent(final int keycode, final int action) { diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/service/CASClient.java b/cloudphone/src/main/java/com/huawei/cloudphone/service/CASClient.java index 274b22c77ef71e53ae8f8071ae70feed48d52169..1bef8cda875dc655246e317844453d6f74e214fb 100644 --- a/cloudphone/src/main/java/com/huawei/cloudphone/service/CASClient.java +++ b/cloudphone/src/main/java/com/huawei/cloudphone/service/CASClient.java @@ -190,13 +190,13 @@ public class CASClient { } } - public boolean sendTouchEvent(int id, int action, int x, int y, int pressure) { + public boolean sendTouchEvent(int id, int action, int x, int y, int pressure, long time, int orientation, int height, int width) { if (mCasInterface == null) { return false; } boolean ret; try { - ret = mCasInterface.sendTouchEvent(id, action, x, y, pressure); + ret = mCasInterface.sendTouchEvent(id, action, x, y, pressure, time, orientation, height, width); } catch (RemoteException e) { CASLog.e(TAG, "filed to call sendTouchEvent"); ret = false; diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/service/CasProcessor.java b/cloudphone/src/main/java/com/huawei/cloudphone/service/CasProcessor.java index cf1682225eb3c82fed1e80e05393af37cd2163b7..a189ad4b15396a8c10dbc037bb37746b23c8f17d 100644 --- a/cloudphone/src/main/java/com/huawei/cloudphone/service/CasProcessor.java +++ b/cloudphone/src/main/java/com/huawei/cloudphone/service/CasProcessor.java @@ -175,8 +175,8 @@ public class CasProcessor extends ICASAidlInterface.Stub { } @Override - public boolean sendTouchEvent(int id, int action, int x, int y, int pressure) { - return JniBridge.getInstance().sendTouchEvent(id, action, x, y, pressure); + public boolean sendTouchEvent(int id, int action, int x, int y, int pressure, long time, int orientation, int height, int width) { + return JniBridge.getInstance().sendTouchEvent(id, action, x, y, pressure, time, orientation, height, width); } @Override diff --git "a/res/\347\273\204\344\273\266\344\272\244\344\272\222.png" "b/res/\347\273\204\344\273\266\344\272\244\344\272\222.png" new file mode 100644 index 0000000000000000000000000000000000000000..b622288c7c9d333735db9a662a3cc2c6f9a60a0a Binary files /dev/null and "b/res/\347\273\204\344\273\266\344\272\244\344\272\222.png" differ