diff --git a/app/build.gradle b/app/build.gradle index 176191d02eac7936b4cc073148d764564702d954..0146823d1110c3b3bb25a6e07802727b94783785 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 839ab18b2845cf6f14f778d82f3ebdb68fe37fd0..2421b1bd34793652cd0d049f811d93aa47aa5b8e 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 d4cd222fa961b4cac8c658f01aa00fd015c37938..30746f2fc929bcc18b6905814552dd8a4e8b1c44 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 2fdeeac72b04714f4f93efb327993f864783374d..30392fad0c4dd01c0414fd6c3df490a7b8b581bd 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 92b13625623d3af8d319223f2071951542d8660a..366cd2a9979e34aa76a8c6f70f82d9d1feb31468 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; @@ -68,14 +66,13 @@ import com.huawei.cloudphone.api.ICloudPhone; import com.huawei.cloudphone.virtualdevice.VirtualDeviceSession; import com.huawei.cloudphone.virtualdevice.common.RingBufferVirtualDeviceIO; +import java.net.BindException; 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 +83,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.BITRATE; +import static com.huawei.cloudphone.utils.CasConstantsUtil.FRAME_TYPE; 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.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 +132,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 +154,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 +175,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 +193,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(VIRTUAL_WIDTH, quality[1]); + config.put(VIRTUAL_HEIGHT, quality[2]); mCloudPhone.setMediaConfig(config); } if (ctrView != null && ctrView.getVisibility() == View.VISIBLE) { @@ -220,7 +219,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 +270,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.check(radioViewMain.getId()); qualityRadioViewGroup.setOnCheckedChangeListener(qualityCheckedChangeListener); setRotation(mOrientation); @@ -283,7 +282,6 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl try { mCloudPhone = CloudPhoneManager.createCloudPhoneInstance(); mCloudPhone.setDisplayMode(CloudPhoneParas.DisplayMode.DISPLAY_MODE_FILL); - mCloudPhone.init(this, DEV_PHONE); HashMap parasMap = new HashMap(); parasMap.put(IP, connectInfo.getConnectIp()); @@ -296,6 +294,8 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl parasMap.put(AVAILABLE_PLAYTIME, connectInfo.getAvailablePlayTime()); parasMap.put(USER_ID, connectInfo.getUserId()); parasMap.put(TOUCH_TIMEOUT, connectInfo.getTouchTimeout()); + + mCloudPhone.init(this, DEV_PHONE, parasMap); mCloudPhone.registerCloudPhoneStateListener(new CloudPhoneStateListenerImpl()); mCloudPhone.registerOnOrientationChangeListener(new CloudPhoneOrientationListener()); mCloudPhone.registerOnVirtualDevDataListener(new CloudPhoneVirtualDevDataListenerImpl()); @@ -305,16 +305,14 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl CASLog.i(TAG, "onRecvCloudAppData, data size: %d", data.length); } }); - - if (mediaConfig != null && mediaConfig.size() != 0) { - mCloudPhone.setMediaConfig(mediaConfig); - } - - mCloudPhone.startCloudPhone(this, mFrameLayout, parasMap); } catch (IllegalArgumentException e) { showDialog(getResources().getString(R.string.cas_phone_input_param_invalid)); + } catch (IllegalStateException e) { + showDialog(getResources().getString(R.string.cas_phone_init_state_error_tip_message)); + } catch (BindException | RuntimeException e) { + showDialog(getResources().getString(R.string.cas_phone_init_failed_tip_message)); } catch (Exception e) { - CASLog.e(TAG, "startCloudApp start failed." + e.getMessage()); + CASLog.e(TAG, "startCloudApp verify failed." + e.getMessage()); showDialog(getResources().getString(R.string.cas_phone_start_fail_tip_message)); } } @@ -392,6 +390,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 +420,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,7 +431,7 @@ 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: @@ -491,11 +491,48 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl case CasState.CAS_NOTOUCH_TIMEOUT: showDialog(getResources().getString(R.string.cas_notouch_timeout_tip_message)); break; + case CasState.CAS_VERIFY_SUCCESS: + startCloudPhone(msg); + break; default: break; } } + private void startCloudPhone(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(VIRTUAL_WIDTH, qualityStr[1]); + mMediaConfig.put(VIRTUAL_HEIGHT, qualityStr[2]); + if (!isSupportH265()) { + mFrameType = FRAME_TYPE_H264; + } + mMediaConfig.put(FRAME_TYPE, mFrameType); + mCloudPhone.setMediaConfig(mMediaConfig); + + try { + mCloudPhone.startCloudPhone(this, mFrameLayout); + } catch (Exception e) { + CASLog.e(TAG, "startCloudApp start failed." + e.getMessage()); + showDialog(getResources().getString(R.string.cas_phone_start_fail_tip_message)); + } + } + /** * set full screen display */ @@ -572,17 +609,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 +628,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)); - break; - case QUALITY_480P: - radioView480p.setTextColor(this.getResources().getColor(R.color.cas_white)); + case QUALITY_BASIC: + radioViewBasic.setTextColor(this.getResources().getColor(R.color.cas_white)); break; - case QUALITY_540P: - radioView540p.setTextColor(this.getResources().getColor(R.color.cas_white)); + case QUALITY_MAIN: + radioViewMain.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 +679,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 +849,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 0000000000000000000000000000000000000000..301d3c7040418772747f84103c4597080df2db0f --- /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 0000000000000000000000000000000000000000..78a72ffc02c91bc7f7661237134e39d02351318d --- /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 = "1500000,720,1280"; + private static final String H264_720P_BASIC = "1100000,544,960"; + + private static final String H264_1080P_BEST = "4000000,1080,1920"; + private static final String H264_1080P_MAIN = "3000000,1080,1920"; + private static final String H264_1080P_BASIC = "2200000,720,1280"; + + private static final String H265_720P_BEST = "1400000,720,1280"; + private static final String H265_720P_MAIN = "1000000,720,1280"; + private static final String H265_720P_BASIC = "800000,544,960"; + + private static final String H265_1080P_BEST = "2700000,1080,1920"; + private static final String H265_1080P_MAIN = "2000000,1080,1920"; + private static final String H265_1080P_BASIC = "1500000,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 6dcf8df46f5033852f42e0c8dd8b4a12d97a288d..465e9d127e9ac31d3d9a07aeee348b78fe2559ad 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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -