From 7adea368bbd7b08b37e59ecd013ea9a1d0cf23e0 Mon Sep 17 00:00:00 2001 From: wangshuo <584363327@qq.com> Date: Mon, 10 Jul 2023 17:03:44 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E4=BA=91=E6=9C=BA?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=87=AA=E9=80=82=E5=BA=94=E9=9F=B3=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E5=8F=82=E6=95=B0=EF=BC=8C=E4=BC=98=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 + app/src/main/AndroidManifest.xml | 9 +- .../common/CasImageQualityManager.java | 8 +- .../cloudapp/ui/CasCloudMainActivity.java | 129 ++++---------- .../cloudapp/ui/CasCloudPhoneActivity.java | 167 ++++++++++-------- .../cloudapp/ui/CasCloudPhoneWebActivity.java | 120 +++++++++++++ .../huawei/cloudapp/utils/CasQualityUtil.java | 65 +++++++ .../res/layout/activity_cas_cloud_main.xml | 155 ++-------------- .../layout/activity_cas_cloud_phone_web.xml | 10 ++ app/src/main/res/layout/cas_ctrl_view.xml | 41 ++--- app/src/main/res/values/strings.xml | 9 +- app/src/main/res/values/styles.xml | 5 + cloudphone/src/main/cpp/CasCommon.h | 4 +- cloudphone/src/main/cpp/CasController.cpp | 95 +++++----- cloudphone/src/main/cpp/CasController.h | 7 +- .../main/cpp/cas_service/CasAppCtrlCmdUtils.h | 3 +- .../cas_service/CasHeartbeatController.cpp | 4 +- .../cloudphone/apiimpl/CloudPhoneImpl.java | 11 +- .../cloudphone/utils/CasConstantsUtil.java | 14 +- .../cloudphone/utils/CasMediaUtils.java | 24 ++- config.gradle | 2 +- 21 files changed, 466 insertions(+), 418 deletions(-) create mode 100644 app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneWebActivity.java create mode 100644 app/src/main/java/com/huawei/cloudapp/utils/CasQualityUtil.java create mode 100644 app/src/main/res/layout/activity_cas_cloud_phone_web.xml diff --git a/app/build.gradle b/app/build.gradle index 176191d..0146823 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,5 +73,7 @@ dependencies { implementation 'com.github.bumptech.glide:glide:4.13.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.14.0' implementation 'com.hyman:flowlayout-lib:1.1.2' + implementation 'com.android.support:design:28.0.0' + implementation 'com.github.Justson.AgentWeb:agentweb-core:v5.0.6-androidx' implementation project(':cloudphone') } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 839ab18..2421b1b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ package="com.huawei.cloudapp"> + @@ -35,12 +36,18 @@ android:label="@string/cas_title_activity_fullscreen" android:theme="@style/CasCloudAppMainActivityTheme" android:windowSoftInputMode="adjustResize" /> + + android:process=":remote" /> \ No newline at end of file diff --git a/app/src/main/java/com/huawei/cloudapp/common/CasImageQualityManager.java b/app/src/main/java/com/huawei/cloudapp/common/CasImageQualityManager.java index d4cd222..30746f2 100644 --- a/app/src/main/java/com/huawei/cloudapp/common/CasImageQualityManager.java +++ b/app/src/main/java/com/huawei/cloudapp/common/CasImageQualityManager.java @@ -18,11 +18,9 @@ package com.huawei.cloudapp.common; public class CasImageQualityManager { - public static final int QUALITY_1080P = 1080; - public static final int QUALITY_720P = 720; - public static final int QUALITY_540P = 540; - public static final int QUALITY_480P = 480; - public static final int QUALITY_AUTO = 0; + public static final int QUALITY_BEST = 0; + public static final int QUALITY_MAIN = 1; + public static final int QUALITY_BASIC = 2; private volatile static CasImageQualityManager manager = null; private int imageQualityStatus = 0; diff --git a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudMainActivity.java b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudMainActivity.java index 2fdeeac..30392fa 100644 --- a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudMainActivity.java +++ b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudMainActivity.java @@ -16,15 +16,11 @@ package com.huawei.cloudapp.ui; -import static com.huawei.cloudapp.ui.CasCloudPhoneActivity.MEDIA_CONFIG; -import static com.huawei.cloudapp.utils.CasConstantsUtil.ENCODE_TYPE; -import static com.huawei.cloudapp.utils.CasConstantsUtil.FRAME_TYPE; -import static com.huawei.cloudapp.utils.CasConstantsUtil.REMOTE_SCHEDULING_ELB_IP; -import static com.huawei.cloudapp.utils.CasConstantsUtil.REMOTE_SCHEDULING_ELB_PORT; - import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; +import android.content.IntentFilter; import android.os.Bundle; import android.text.InputFilter; import android.text.Spanned; @@ -33,9 +29,7 @@ import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.RadioGroup; +import android.widget.Button; import android.widget.TextView; import com.huawei.cloudapp.R; @@ -46,10 +40,7 @@ import com.zhy.view.flowlayout.FlowLayout; import com.zhy.view.flowlayout.TagAdapter; import com.zhy.view.flowlayout.TagFlowLayout; -import java.io.Serializable; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; public class CasCloudMainActivity extends Activity { @@ -57,16 +48,17 @@ public class CasCloudMainActivity extends Activity { private static final String TAG = "CasCloudMainActivity"; private AutoCompleteTextView mCloudPhoneIp; private AutoCompleteTextView mCloudPhonePort; - private RadioGroup mEncodeTypeGroup; - private int mEncodeType = 0; - private String mFrameType = "h264"; - private LinearLayout mRemoteEncodeServerIpLayout; - private LinearLayout mRemoteEncodeServerPortLayout; - private EditText mRemoteEncodeServerIp; - private EditText mRemoteEncodeServerPort; - private RadioGroup mFrameTypeGroup; private TagFlowLayout mFlowLayout; private CasHistory mCasHistory; + private Button appConnect; + private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals("com.huawei.cloudapp.ui.CasCloudPhoneActivity.destroyed")) { + appConnect.setEnabled(true); + } + } + }; @Override protected void onCreate(Bundle savedInstanceState) { @@ -83,6 +75,14 @@ public class CasCloudMainActivity extends Activity { initAutoCompleteTextView("ip", mCloudPhoneIp); initAutoCompleteTextView("port", mCloudPhonePort); setAdapter(mFlowLayout); + registerReceiver(mBroadcastReceiver, + new IntentFilter("com.huawei.cloudapp.ui.CasCloudPhoneActivity.destroyed")); + } + + @Override + protected void onPause() { + super.onPause(); + unregisterReceiver(mBroadcastReceiver); } private void initView() { @@ -90,63 +90,23 @@ public class CasCloudMainActivity extends Activity { initAutoCompleteTextView("ip", mCloudPhoneIp); mCloudPhonePort = findViewById(R.id.cloud_phone_port); initAutoCompleteTextView("port", mCloudPhonePort); - mEncodeTypeGroup = findViewById(R.id.encodeTypeRadioButtonGroup); - mFrameTypeGroup = findViewById(R.id.frameTypeRadioButtonGroup); - mRemoteEncodeServerIpLayout = findViewById(R.id.remote_ip_view_layout); - mRemoteEncodeServerPortLayout = findViewById(R.id.remote_port_view_layout); - mRemoteEncodeServerIp = findViewById(R.id.edit_text_remote_ip); - mRemoteEncodeServerPort = findViewById(R.id.edit_text_remote_port); mFlowLayout = findViewById(R.id.flow); setAdapter(mFlowLayout); + appConnect = findViewById(R.id.cloud_phone_connect); - mEncodeTypeGroup.check(R.id.radioButtonCpu); - mEncodeTypeGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(RadioGroup radioGroup, int i) { - switch (i) { - case R.id.radioButtonCpu: - mEncodeType = 1; - mRemoteEncodeServerIpLayout.setVisibility(View.GONE); - mRemoteEncodeServerPortLayout.setVisibility(View.GONE); - mRemoteEncodeServerIp.setText(""); - mRemoteEncodeServerPort.setText(""); - break; - case R.id.radioButtonGpu: - mEncodeType = 2; - mRemoteEncodeServerIpLayout.setVisibility(View.GONE); - mRemoteEncodeServerPortLayout.setVisibility(View.GONE); - mRemoteEncodeServerIp.setText(""); - mRemoteEncodeServerPort.setText(""); - break; - case R.id.radioButtonRemote: - mRemoteEncodeServerIpLayout.setVisibility(View.VISIBLE); - mRemoteEncodeServerPortLayout.setVisibility(View.VISIBLE); - break; - default: - mEncodeType = 0; - mRemoteEncodeServerIpLayout.setVisibility(View.GONE); - mRemoteEncodeServerPortLayout.setVisibility(View.GONE); - mRemoteEncodeServerIp.setText(""); - mRemoteEncodeServerPort.setText(""); - break; - } - } - }); - - mFrameTypeGroup.check(R.id.radioButtonH264); - mFrameTypeGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(RadioGroup radioGroup, int i) { - if (i == R.id.radioButtonH265) { - mFrameType = "h265"; - } else { - mFrameType = "h264"; - } - } - }); } public void cloudPhoneConnect(View view) { + startCloudPhoneActivity(CasCloudPhoneActivity.class); + appConnect.setEnabled(false); + } + + + public void cloudPhoneConnectWeb(View view) { + startCloudPhoneActivity(CasCloudPhoneWebActivity.class); + } + + private void startCloudPhoneActivity(Class cls) { String phoneIp = mCloudPhoneIp.getText().toString().trim(); if (TextUtils.isEmpty(phoneIp)) { CASLog.e(TAG, "输入Ip为空"); @@ -157,32 +117,11 @@ public class CasCloudMainActivity extends Activity { CASLog.e(TAG, "输入Port为空"); return; } - String remoteEncodeServerIp = mRemoteEncodeServerIp.getText().toString().trim(); - String remoteEncodeServerPort = mRemoteEncodeServerPort.getText().toString().trim(); - if (mEncodeType == 3) { - if (remoteEncodeServerIp.isEmpty() || remoteEncodeServerPort.isEmpty()) { - CASLog.e(TAG, "远编服务器信息不全"); - return; - } - } - - startCloudPhoneActivity(phoneIp, phonePort, remoteEncodeServerIp, remoteEncodeServerPort); - } - - private void startCloudPhoneActivity(String phoneIp, String phonePort, String remoteEncodeServerIp, String remoteEncodeServerPort) { - - Intent intent = new Intent(CasCloudMainActivity.this, CasCloudPhoneActivity.class); + Intent intent = new Intent(CasCloudMainActivity.this, cls); CasConnectInfo connectorInfo = getCasConnectorInfo(phoneIp, phonePort); - Map mediaConfig = new HashMap(); - mediaConfig.put(FRAME_TYPE, mFrameType); - mediaConfig.put(ENCODE_TYPE, String.valueOf(mEncodeType)); - if (!remoteEncodeServerIp.isEmpty() && !remoteEncodeServerPort.isEmpty()) { - mediaConfig.put(REMOTE_SCHEDULING_ELB_IP, remoteEncodeServerIp); - mediaConfig.put(REMOTE_SCHEDULING_ELB_PORT, remoteEncodeServerPort); - } intent.putExtra(CasConnectInfo.BUNDLE_KEY, connectorInfo); - intent.putExtra(MEDIA_CONFIG, (Serializable) mediaConfig); startActivity(intent); + overridePendingTransition(0, 0); } private CasConnectInfo getCasConnectorInfo(String phoneIp, String phonePort) { diff --git a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java index 92b1362..20f1eb6 100644 --- a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java +++ b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java @@ -16,7 +16,6 @@ package com.huawei.cloudapp.ui; -import android.Manifest; import android.app.Activity; import android.content.DialogInterface; import android.content.Intent; @@ -29,11 +28,8 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentActivity; -import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; import android.view.View; @@ -48,6 +44,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import com.google.gson.Gson; import com.huawei.cloudapp.BuildConfig; import com.huawei.cloudapp.R; import com.huawei.cloudapp.common.CASLog; @@ -58,6 +55,7 @@ import com.huawei.cloudapp.common.CasImageQualityManager; import com.huawei.cloudapp.common.CasListener; import com.huawei.cloudapp.common.CasState; import com.huawei.cloudapp.utils.CasAdaptPhoneUtils; +import com.huawei.cloudapp.utils.CasQualityUtil; import com.huawei.cloudphone.api.CloudAppDataListener; import com.huawei.cloudphone.api.CloudPhoneManager; import com.huawei.cloudphone.api.CloudPhoneOrientationChangeListener; @@ -70,12 +68,10 @@ import com.huawei.cloudphone.virtualdevice.common.RingBufferVirtualDeviceIO; import java.util.HashMap; -import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1; import static android.os.SystemClock.sleep; -import static com.huawei.cloudapp.common.CasImageQualityManager.QUALITY_480P; -import static com.huawei.cloudapp.common.CasImageQualityManager.QUALITY_540P; -import static com.huawei.cloudapp.common.CasImageQualityManager.QUALITY_720P; -import static com.huawei.cloudapp.common.CasImageQualityManager.QUALITY_AUTO; +import static com.huawei.cloudapp.common.CasImageQualityManager.QUALITY_MAIN; +import static com.huawei.cloudapp.common.CasImageQualityManager.QUALITY_BASIC; +import static com.huawei.cloudapp.common.CasImageQualityManager.QUALITY_BEST; import static com.huawei.cloudapp.utils.CasConstantsUtil.AES_KEY; import static com.huawei.cloudapp.utils.CasConstantsUtil.AUTH_TS; import static com.huawei.cloudapp.utils.CasConstantsUtil.AVAILABLE_PLAYTIME; @@ -86,9 +82,19 @@ import static com.huawei.cloudapp.utils.CasConstantsUtil.SESSION_ID; import static com.huawei.cloudapp.utils.CasConstantsUtil.TICKET; import static com.huawei.cloudapp.utils.CasConstantsUtil.TOUCH_TIMEOUT; import static com.huawei.cloudapp.utils.CasConstantsUtil.USER_ID; +import static com.huawei.cloudapp.utils.CasQualityUtil.DEFINITION_BEST; +import static com.huawei.cloudapp.utils.CasQualityUtil.DEFINITION_MAIN; +import static com.huawei.cloudapp.utils.CasQualityUtil.DEFINITION_BASIC; +import static com.huawei.cloudapp.utils.CasQualityUtil.FRAME_TYPE_H264; +import static com.huawei.cloudapp.utils.CasQualityUtil.FRAME_TYPE_H265; +import static com.huawei.cloudapp.utils.CasQualityUtil.RESOLUTION_1080P; import static com.huawei.cloudphone.api.CloudPhoneParas.DevType.DEV_PHONE; -import static com.huawei.cloudphone.utils.CasConstantsUtil.VIRTUAL_HEIGHT; -import static com.huawei.cloudphone.utils.CasConstantsUtil.VIRTUAL_WIDTH; +import static com.huawei.cloudphone.utils.CasConstantsUtil.BITRATE; +import static com.huawei.cloudphone.utils.CasConstantsUtil.FRAME_TYPE; +import static com.huawei.cloudphone.utils.CasConstantsUtil.STREAM_HEIGHT; +import static com.huawei.cloudphone.utils.CasConstantsUtil.STREAM_WIDTH; +import static com.huawei.cloudphone.utils.CasConstantsUtil.WIDTH; +import static com.huawei.cloudphone.utils.CasMediaUtils.isSupportH265; import static com.huawei.cloudphone.virtualdevice.camera.VirtualCameraManager.GRANT_CAMERA_PERMISSION_SUCCESS_ACTION; import static com.huawei.cloudphone.virtualdevice.common.VirtualDeviceManager.DEV_TYPE_CAMERA; import static com.huawei.cloudphone.virtualdevice.common.VirtualDeviceManager.DEV_TYPE_MICROPHONE; @@ -125,7 +131,7 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl public volatile boolean rebuildDone = false; public boolean doCheckConnection = false; private int mDevType; - private HashMap mediaConfig = null; + private HashMap mMediaConfig = null; private ImageView loadingView = null; private int currentRotation = -1; private CasCommonDialog quitDialog; @@ -147,13 +153,14 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl // intent trans value private CasConnectInfo connectInfo; private RadioGroup qualityRadioViewGroup; - private RadioButton radioView720p; - private RadioButton radioView540p; - private RadioButton radioView480p; - private RadioButton radioViewAuto; + private RadioButton radioViewBest; + private RadioButton radioViewMain; + private RadioButton radioViewBasic; private boolean bIsStart = false; private boolean isGotCameraAndRecordPermission = true; private int mOrientation = 0; + private String mFrameType = FRAME_TYPE_H265; + private String mResolution = RESOLUTION_1080P; private int mDisplayMode; private FrameLayout mFrameLayout = null; private FrameLayout mFloatContainer = null; @@ -167,27 +174,17 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl if (group.getCheckedRadioButtonId() != checkedId) { CASLog.e("CasMainActivity", "group.getCheckedRadioButtonId() != checkedId"); } else { - int selectType = QUALITY_720P; - String virtualWidth = "720"; - String virtualHeight = "1280"; - if (radioView720p.getId() == checkedId) { - selectType = QUALITY_720P; - virtualWidth = "720"; - virtualHeight = "1280"; - } else if (radioView540p.getId() == checkedId) { - selectType = QUALITY_540P; - - // 音视频层规范要求虚拟宽高为8的倍数 - virtualWidth = "544"; - virtualHeight = "960"; - } else if (radioView480p.getId() == checkedId) { - selectType = QUALITY_480P; - virtualWidth = "480"; - virtualHeight = "640"; - } else if (radioViewAuto.getId() == checkedId) { - selectType = QUALITY_AUTO; - virtualWidth = "720"; - virtualHeight = "1280"; + int selectType = QUALITY_BEST; + String[] quality = CasQualityUtil.GetQuality(mFrameType, mResolution, DEFINITION_BEST); + if (radioViewBest.getId() == checkedId) { + selectType = QUALITY_BEST; + quality = CasQualityUtil.GetQuality(mFrameType, mResolution, DEFINITION_BEST); + } else if (radioViewMain.getId() == checkedId) { + selectType = QUALITY_MAIN; + quality = CasQualityUtil.GetQuality(mFrameType, mResolution, DEFINITION_MAIN); + } else if (radioViewBasic.getId() == checkedId) { + selectType = QUALITY_BASIC; + quality = CasQualityUtil.GetQuality(mFrameType, mResolution, DEFINITION_BASIC); } int oldSelectType = CasImageQualityManager.getInstance().getImageQualityStatus(); @@ -195,8 +192,9 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl CasImageQualityManager.getInstance().setImageQualityStatus(selectType); checkImageQualityStatus(selectType); HashMap config = new HashMap<>(); - config.put(VIRTUAL_WIDTH, virtualWidth); - config.put(VIRTUAL_HEIGHT, virtualHeight); + config.put(BITRATE, quality[0]); + config.put(STREAM_WIDTH, quality[1]); + config.put(STREAM_HEIGHT, quality[2]); mCloudPhone.setMediaConfig(config); } if (ctrView != null && ctrView.getVisibility() == View.VISIBLE) { @@ -220,7 +218,7 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl showDialog(getResources().getString(R.string.cas_phone_play_timeout_tip_message)); break; case MSG_STATE_CHANGE: - processStateChangeMsg(msg.arg1); + processStateChangeMsg(msg.arg1, (String) msg.obj); break; case MSG_RECONNECT_FAILED: showDialog(getResources().getString(R.string.cas_phone_reconnect_server_fail_tip_message)); @@ -271,10 +269,10 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl mQuitCloudPhone.setOnClickListener(CasCloudPhoneActivity.this); // ctrlView qualityRadioViewGroup = findViewById(R.id.pic_quality_choose_layout); - radioView720p = findViewById(R.id.pic_quality_720p); - radioView540p = findViewById(R.id.pic_quality_540p); - radioView480p = findViewById(R.id.pic_quality_480p); - radioViewAuto = findViewById(R.id.pic_quality_auto); + radioViewBest = findViewById(R.id.pic_quality_best); + radioViewMain = findViewById(R.id.pic_quality_main); + radioViewBasic = findViewById(R.id.pic_quality_basic); + qualityRadioViewGroup.setVisibility(View.GONE); qualityRadioViewGroup.setOnCheckedChangeListener(qualityCheckedChangeListener); setRotation(mOrientation); @@ -306,8 +304,15 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl } }); - if (mediaConfig != null && mediaConfig.size() != 0) { - mCloudPhone.setMediaConfig(mediaConfig); + if (!isSupportH265()) { + if (mMediaConfig == null) { + mMediaConfig = new HashMap(); + } + mMediaConfig.put(FRAME_TYPE, "h264"); + } + + if (mMediaConfig != null && mMediaConfig.size() != 0) { + mCloudPhone.setMediaConfig(mMediaConfig); } mCloudPhone.startCloudPhone(this, mFrameLayout, parasMap); @@ -392,6 +397,8 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl } catch (Exception e) { CASLog.e(TAG, "destroy failed. " + e.getMessage()); } + Intent intent = new Intent("com.huawei.cloudapp.ui.CasCloudPhoneActivity.destroyed"); + sendBroadcast(intent); } @Override @@ -420,7 +427,7 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl mOrientation = bundle.getInt(ORIENTATION); mDisplayMode = bundle.getInt(DISPLAY_MODE); mDevType = bundle.getInt(DEV_TYPE); - mediaConfig = (HashMap) bundle.getSerializable(MEDIA_CONFIG); + mMediaConfig = (HashMap) bundle.getSerializable(MEDIA_CONFIG); } } @@ -431,13 +438,14 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl mVirtualDeviceSession.setVirtualDeviceIoHook(mRingBufferVirtualDeviceIO); } - private void processStateChangeMsg(int code) { + private void processStateChangeMsg(int code, String msg) { CASLog.i(TAG, "processStateChangeMsg code = " + code); switch (code) { case CasState.CAS_START_SUCCESS: lag.setVisibility(View.VISIBLE); loadingView.setVisibility(View.GONE); startSuccessThreadTask(); + handleStartSuccessMsg(msg); mCasHistory.setHistory("ip", connectInfo.getConnectIp()); mCasHistory.setHistory("port", connectInfo.getConnectPort()); mCasHistory.setHistory("ip:port", connectInfo.getConnectIp() + ":" + connectInfo.getConnectPort()); @@ -496,6 +504,31 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl } } + private void handleStartSuccessMsg(String msg) { + if (mMediaConfig == null) { + mMediaConfig = new HashMap(); + } + + Gson gson = new Gson(); + HashMap cloudMediaConfig = gson.fromJson(msg, new HashMap().getClass()); + mResolution = String.valueOf(((Double) cloudMediaConfig.get(WIDTH)).intValue()); + mFrameType = (String) cloudMediaConfig.get(FRAME_TYPE); + CASLog.i(TAG, "mResolution = " + mResolution + ", mFrameType = " + mFrameType); + if (mResolution.equals(RESOLUTION_1080P)) { + radioViewBest.setText(R.string.quality_UHD); + radioViewMain.setText(R.string.quality_HD); + radioViewBasic.setText(R.string.quality_SD); + } + String[] qualityStr = CasQualityUtil.GetQuality(mFrameType, mResolution, DEFINITION_MAIN); + + mMediaConfig.put(BITRATE, qualityStr[0]); + mMediaConfig.put(STREAM_WIDTH, qualityStr[1]); + mMediaConfig.put(STREAM_HEIGHT, qualityStr[2]); + mCloudPhone.setMediaConfig(mMediaConfig); + qualityRadioViewGroup.check(radioViewMain.getId()); + qualityRadioViewGroup.setVisibility(View.VISIBLE); + } + /** * set full screen display */ @@ -572,17 +605,14 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl */ private void checkImageQualityStatus(int selectType) { switch (selectType) { - case QUALITY_AUTO: - radioViewAuto.setTextColor(this.getResources().getColor(R.color.cas_colorAccent)); - break; - case QUALITY_480P: - radioView480p.setTextColor(this.getResources().getColor(R.color.cas_colorAccent)); + case QUALITY_BASIC: + radioViewBasic.setTextColor(this.getResources().getColor(R.color.cas_colorAccent)); break; - case QUALITY_540P: - radioView540p.setTextColor(this.getResources().getColor(R.color.cas_colorAccent)); + case QUALITY_MAIN: + radioViewMain.setTextColor(this.getResources().getColor(R.color.cas_colorAccent)); break; - case QUALITY_720P: - radioView720p.setTextColor(this.getResources().getColor(R.color.cas_colorAccent)); + case QUALITY_BEST: + radioViewBest.setTextColor(this.getResources().getColor(R.color.cas_colorAccent)); break; default: break; @@ -594,17 +624,14 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl */ private void resumeImageQualityStatus(int selectType) { switch (selectType) { - case QUALITY_AUTO: - radioViewAuto.setTextColor(this.getResources().getColor(R.color.cas_white)); + case QUALITY_BASIC: + radioViewBasic.setTextColor(this.getResources().getColor(R.color.cas_white)); break; - case QUALITY_480P: - radioView480p.setTextColor(this.getResources().getColor(R.color.cas_white)); + case QUALITY_MAIN: + radioViewMain.setTextColor(this.getResources().getColor(R.color.cas_white)); break; - case QUALITY_540P: - radioView540p.setTextColor(this.getResources().getColor(R.color.cas_white)); - break; - case QUALITY_720P: - radioView720p.setTextColor(this.getResources().getColor(R.color.cas_white)); + case QUALITY_BEST: + radioViewBest.setTextColor(this.getResources().getColor(R.color.cas_white)); break; default: break; @@ -648,18 +675,17 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl CASLog.d(TAG, "stop cloud phone"); doCheckConnection = false; // dismissAllDialogs(); - setResult(RESULT_OK); finish(); gAcitivity = null; + if (mVirtualDeviceSession != null) { + mVirtualDeviceSession.stop(); + } new Thread(new Runnable() { @Override public void run() { bIsStart = false; try { mCloudPhone.exitCloudPhone(); - if (mVirtualDeviceSession != null) { - mVirtualDeviceSession.stop(); - } } catch (Exception e) { CASLog.e(TAG, "stop cloud phone failed " + e.getMessage()); } @@ -819,6 +845,7 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl Message message = new Message(); message.what = MSG_STATE_CHANGE; message.arg1 = code; + message.obj = msg; handler.sendMessage(message); if (mCasListener != null) { mCasListener.onStateChange(code, msg); diff --git a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneWebActivity.java b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneWebActivity.java new file mode 100644 index 0000000..301d3c7 --- /dev/null +++ b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneWebActivity.java @@ -0,0 +1,120 @@ +package com.huawei.cloudapp.ui; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.os.Bundle; +import android.view.View; +import android.webkit.JavascriptInterface; +import android.webkit.WebSettings; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.huawei.cloudapp.R; +import com.huawei.cloudapp.common.CASLog; +import com.huawei.cloudapp.common.CasConnectInfo; +import com.huawei.cloudapp.common.CasHistory; +import com.just.agentweb.AgentWeb; +import com.just.agentweb.DefaultWebClient; +import com.just.agentweb.WebChromeClient; + +public class CasCloudPhoneWebActivity extends AppCompatActivity { + private static final String TAG = "CasCloudWebFragment"; + private AgentWeb mAgentWeb; + private LinearLayout mLinearLayout; + private CasConnectInfo mConnectInfo; + public static String urlStr = "https://110.41.19.175:10086/index?"; //h5 sdk部署地址 + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_cas_cloud_phone_web); + getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_FULLSCREEN); + mLinearLayout = findViewById(R.id.web_view); + + mAgentWeb = AgentWeb.with(this) + .setAgentWebParent(mLinearLayout, -1, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)) + .useDefaultIndicator(-1, 3) + .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK) + .setWebViewClient(mWebViewClient) + .setWebChromeClient(mWebChromeClient) + .setMainFrameErrorView(R.layout.agentweb_error_page, -1) + .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.DISALLOW) + .interceptUnkownUrl() + .createAgentWeb() + .ready() + .go(getConnectUrl()); + mAgentWeb.getWebCreator().getWebView().setLayerType(View.LAYER_TYPE_HARDWARE, null); + mAgentWeb.getJsInterfaceHolder().addJavaObject("CasCallback", new CasCallbackInterface()); + WebSettings webSettings = mAgentWeb.getWebCreator().getWebView().getSettings(); + webSettings.setJavaScriptEnabled(true); + webSettings.setDomStorageEnabled(true); + webSettings.setMediaPlaybackRequiresUserGesture(false); + } + + private com.just.agentweb.WebViewClient mWebViewClient = new com.just.agentweb.WebViewClient(); + private WebChromeClient mWebChromeClient = new WebChromeClient() { + @Override + public void onShowCustomView(View view, CustomViewCallback customViewCallback) { + super.onShowCustomView(view, customViewCallback); + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + }; + + @Override + public void onResume() { + if (mAgentWeb != null) { + mAgentWeb.getWebLifeCycle().onResume(); + } + super.onResume(); + } + + @Override + public void onPause() { + if (mAgentWeb != null) { + mAgentWeb.getWebLifeCycle().onPause(); + } + super.onPause(); + } + + @Override + public void onDestroy() { + if (mAgentWeb != null) { + mAgentWeb.getWebLifeCycle().onDestroy(); + } + super.onDestroy(); + } + + + /** + * get data with intent + */ + private String getConnectUrl() { + CASLog.i(TAG, "getIntentData"); + Intent intent = getIntent(); + Bundle bundle = intent.getExtras(); + if (bundle != null) { + mConnectInfo = intent.getParcelableExtra(CasConnectInfo.BUNDLE_KEY); + return urlStr + "ip=" + mConnectInfo.getConnectIp() + "&port=" + ((Integer.parseInt(mConnectInfo.getConnectPort()) + 1)); + } + return null; + } + + class CasCallbackInterface { + @JavascriptInterface + public void startSuccessCallback() { + CasHistory mCasHistory = new CasHistory(getSharedPreferences("input_history", MODE_PRIVATE)); + mCasHistory.setHistory("ip", mConnectInfo.getConnectIp()); + mCasHistory.setHistory("port", mConnectInfo.getConnectPort()); + mCasHistory.setHistory("ip:port", mConnectInfo.getConnectIp() + ":" + mConnectInfo.getConnectPort()); + } + + @JavascriptInterface + public void exit() { + CasCloudPhoneWebActivity.this.finish(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/huawei/cloudapp/utils/CasQualityUtil.java b/app/src/main/java/com/huawei/cloudapp/utils/CasQualityUtil.java new file mode 100644 index 0000000..d410c75 --- /dev/null +++ b/app/src/main/java/com/huawei/cloudapp/utils/CasQualityUtil.java @@ -0,0 +1,65 @@ +package com.huawei.cloudapp.utils; + +import java.util.HashMap; + +public class CasQualityUtil { + + public static final String FRAME_TYPE_H265 = "h265"; + public static final String FRAME_TYPE_H264 = "h264"; + + public static final String RESOLUTION_720P = "720"; + public static final String RESOLUTION_1080P = "1080"; + + public static final String DEFINITION_BEST = "best"; + public static final String DEFINITION_MAIN = "main"; + public static final String DEFINITION_BASIC = "basic"; + + private static final String H264_720P_BEST = "2000000,720,1280"; + private static final String H264_720P_MAIN = "1300000,720,1280"; + private static final String H264_720P_BASIC = "1000000,544,960"; + + private static final String H264_1080P_BEST = "4000000,1080,1920"; + private static final String H264_1080P_MAIN = "2600000,1080,1920"; + private static final String H264_1080P_BASIC = "2000000,720,1280"; + + private static final String H265_720P_BEST = "1300000,720,1280"; + private static final String H265_720P_MAIN = "1000000,720,1280"; + private static final String H265_720P_BASIC = "700000,544,960"; + + private static final String H265_1080P_BEST = "2600000,1080,1920"; + private static final String H265_1080P_MAIN = "2000000,1080,1920"; + private static final String H265_1080P_BASIC = "1400000,720,1280"; + + private static HashMap>> quality = + new HashMap>>(); + + static { + quality.put(FRAME_TYPE_H264, new HashMap>()); + + quality.get(FRAME_TYPE_H264).put(RESOLUTION_720P, new HashMap()); + quality.get(FRAME_TYPE_H264).get(RESOLUTION_720P).put(DEFINITION_BEST, H264_720P_BEST); + quality.get(FRAME_TYPE_H264).get(RESOLUTION_720P).put(DEFINITION_MAIN, H264_720P_MAIN); + quality.get(FRAME_TYPE_H264).get(RESOLUTION_720P).put(DEFINITION_BASIC, H264_720P_BASIC); + + quality.get(FRAME_TYPE_H264).put(RESOLUTION_1080P, new HashMap()); + quality.get(FRAME_TYPE_H264).get(RESOLUTION_1080P).put(DEFINITION_BEST, H264_1080P_BEST); + quality.get(FRAME_TYPE_H264).get(RESOLUTION_1080P).put(DEFINITION_MAIN, H264_1080P_MAIN); + quality.get(FRAME_TYPE_H264).get(RESOLUTION_1080P).put(DEFINITION_BASIC, H264_1080P_BASIC); + + quality.put(FRAME_TYPE_H265, new HashMap>()); + + quality.get(FRAME_TYPE_H265).put(RESOLUTION_720P, new HashMap()); + quality.get(FRAME_TYPE_H265).get(RESOLUTION_720P).put(DEFINITION_BEST, H265_720P_BEST); + quality.get(FRAME_TYPE_H265).get(RESOLUTION_720P).put(DEFINITION_MAIN, H265_720P_MAIN); + quality.get(FRAME_TYPE_H265).get(RESOLUTION_720P).put(DEFINITION_BASIC, H265_720P_BASIC); + + quality.get(FRAME_TYPE_H265).put(RESOLUTION_1080P, new HashMap()); + quality.get(FRAME_TYPE_H265).get(RESOLUTION_1080P).put(DEFINITION_BEST, H265_1080P_BEST); + quality.get(FRAME_TYPE_H265).get(RESOLUTION_1080P).put(DEFINITION_MAIN, H265_1080P_MAIN); + quality.get(FRAME_TYPE_H265).get(RESOLUTION_1080P).put(DEFINITION_BASIC, H265_1080P_BASIC); + } + + public static String[] GetQuality(String frameType, String resolution, String definition) { + return quality.get(frameType).get(resolution).get(definition).split(","); + } +} diff --git a/app/src/main/res/layout/activity_cas_cloud_main.xml b/app/src/main/res/layout/activity_cas_cloud_main.xml index 6dcf8df..465e9d1 100644 --- a/app/src/main/res/layout/activity_cas_cloud_main.xml +++ b/app/src/main/res/layout/activity_cas_cloud_main.xml @@ -65,150 +65,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -