diff --git a/OCH/taxi/taxi-unmanned-passenger/.gitignore b/OCH/taxi/taxi-unmanned-passenger/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/build.gradle b/OCH/taxi/taxi-unmanned-passenger/build.gradle
new file mode 100644
index 0000000000..ec58e06826
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/build.gradle
@@ -0,0 +1,66 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion rootProject.ext.android.compileSdkVersion
+ // buildToolsVersion rootProject.ext.android.buildToolsVersion
+ defaultConfig {
+ minSdkVersion rootProject.ext.android.minSdkVersion
+ targetSdkVersion rootProject.ext.android.targetSdkVersion
+ versionCode Integer.valueOf(VERSION_CODE)
+ versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION")
+
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles "consumer-rules.pro"
+
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = [AROUTER_MODULE_NAME: project.getName()]
+ }
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ lintOptions {
+ abortOnError false
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ debug {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: "libs", include: ["*.jar"])
+ implementation rootProject.ext.dependencies.kotlinstdlibjdk7
+ implementation rootProject.ext.dependencies.androidxappcompat
+ implementation rootProject.ext.dependencies.arouter
+ implementation rootProject.ext.dependencies.androidxrecyclerview
+ implementation rootProject.ext.dependencies.material
+ implementation rootProject.ext.dependencies.flexbox
+ annotationProcessor rootProject.ext.dependencies.aroutercompiler
+ implementation rootProject.ext.dependencies.rxandroid
+ implementation rootProject.ext.dependencies.androidxconstraintlayout
+ implementation rootProject.ext.dependencies.amapnavi3dmap
+ implementation rootProject.ext.dependencies.amapsearch
+
+ implementation project(":OCH:mogo-och-common-module")
+ compileOnly project(":libraries:mogo-map")
+ implementation project(':core:mogo-core-res')
+
+}
+
+apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/consumer-rules.pro b/OCH/taxi/taxi-unmanned-passenger/consumer-rules.pro
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/OCH/taxi/taxi-unmanned-passenger/gradle.properties b/OCH/taxi/taxi-unmanned-passenger/gradle.properties
new file mode 100644
index 0000000000..1aa38956f3
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/gradle.properties
@@ -0,0 +1,3 @@
+GROUP=com.mogo.och
+POM_ARTIFACT_ID=och-taxi-passenger
+VERSION_CODE=1
diff --git a/OCH/taxi/taxi-unmanned-passenger/proguard-rules.pro b/OCH/taxi/taxi-unmanned-passenger/proguard-rules.pro
new file mode 100644
index 0000000000..481bb43481
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/AndroidManifest.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..667dac6a6b
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/AndroidManifest.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/assets/style.data b/OCH/taxi/taxi-unmanned-passenger/src/main/assets/style.data
new file mode 100755
index 0000000000..a41c36c308
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/assets/style.data differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/assets/style_extra.data b/OCH/taxi/taxi-unmanned-passenger/src/main/assets/style_extra.data
new file mode 100755
index 0000000000..ca0eb5456f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/assets/style_extra.data differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/IMogoOCH.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/IMogoOCH.java
new file mode 100644
index 0000000000..c33547d928
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/IMogoOCH.java
@@ -0,0 +1,24 @@
+package com.mogo.och.taxi.passenger;
+
+import androidx.annotation.IdRes;
+import androidx.fragment.app.FragmentActivity;
+
+import com.mogo.eagle.core.function.api.base.IMoGoFunctionProvider;
+
+/**
+ *
+ * @author congtaowang
+ * @since 2021/1/15
+ *
+ * 网约车抽象接口
+ */
+public interface IMogoOCH extends IMoGoFunctionProvider {
+
+ /**
+ * 初始化网约车容器
+ *
+ * @param activity
+ * @param containerId 容器ID
+ */
+ void createCoverage(FragmentActivity activity, @IdRes int containerId);
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/MogoOCHTaxiPassenger.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/MogoOCHTaxiPassenger.java
new file mode 100644
index 0000000000..92f169a9ec
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/MogoOCHTaxiPassenger.java
@@ -0,0 +1,99 @@
+package com.mogo.och.taxi.passenger;
+
+import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI_P;
+
+import android.content.Context;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.mogo.eagle.core.function.call.setting.CallerMoGoUiSettingManager;
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
+import com.mogo.och.taxi.passenger.constant.TaxiPassengerConst;
+import com.mogo.och.taxi.passenger.ui.TaxiPassengerBaseFragment;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author congtaowang
+ * @since 2021/1/15
+ *
+ * 网约车-出租车-乘客端
+ */
+@Route(path = TaxiPassengerConst.PATH)
+public class MogoOCHTaxiPassenger implements IMogoOCH {
+
+ private static final String TAG = "MogoOCHTaxiPassenger";
+ private TaxiPassengerBaseFragment ochTaxiPassengerFragment;
+ private FragmentActivity mActivity;
+ private int mContainerId;
+
+ @Override
+ public void init(Context context) {
+ CallerLogger.INSTANCE.d(M_TAXI_P + TAG, "init");
+ }
+
+ /**
+ * 进入鹰眼模式,设置手势缩放地图失效
+ */
+ private void stepIntoVrMode() {
+ CallerLogger.INSTANCE.d(M_TAXI_P + TAG, "进入vr模式");
+ CallerMoGoUiSettingManager.INSTANCE.stepInNightMode();//夜间模式 状态栏字体颜色变黑
+ }
+
+ private void showFragment() {
+ FragmentManager supportFragmentManager = mActivity.getSupportFragmentManager();
+ if (ochTaxiPassengerFragment == null) {
+ CallerLogger.INSTANCE.d(M_TAXI_P + TAG, "准备add fragment======");
+ Fragment fragmentByTag = supportFragmentManager.findFragmentByTag(TaxiPassengerBaseFragment.TAG);
+ if (fragmentByTag instanceof TaxiPassengerBaseFragment){
+ ochTaxiPassengerFragment = (TaxiPassengerBaseFragment) fragmentByTag;
+ }else {
+ ochTaxiPassengerFragment = new TaxiPassengerBaseFragment();
+ }
+ if (!ochTaxiPassengerFragment.isAdded()){
+ supportFragmentManager.beginTransaction().add(mContainerId, ochTaxiPassengerFragment
+ ,TaxiPassengerBaseFragment.TAG).commitAllowingStateLoss();
+ }
+ return;
+ }
+ CallerLogger.INSTANCE.d(M_TAXI_P + TAG, "准备show fragment");
+ supportFragmentManager.beginTransaction().show(ochTaxiPassengerFragment).commitAllowingStateLoss();
+ }
+
+ private void hideFragment() {
+ if (ochTaxiPassengerFragment != null) {
+ mActivity.getSupportFragmentManager().beginTransaction().hide(ochTaxiPassengerFragment).commitAllowingStateLoss();
+ }
+ }
+
+ @Override
+ public void createCoverage(FragmentActivity activity, int containerId) {
+
+ }
+
+ @NotNull
+ @Override
+ public String getFunctionName() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public Fragment createCoverage(@Nullable FragmentActivity fragmentActivity, @Nullable Integer integer) {
+ this.mActivity = fragmentActivity;
+ this.mContainerId = integer;
+ showFragment();
+ return null;
+ }
+
+ @Override
+ public void onDestroy() {
+// 若不调用finish, 设置中打开关闭UITouch,会造成och fragment 重叠
+ if (mActivity == null) return;
+ mActivity.finish();
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerBaseRespBean.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerBaseRespBean.java
new file mode 100644
index 0000000000..817e735e93
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerBaseRespBean.java
@@ -0,0 +1,11 @@
+package com.mogo.och.taxi.passenger.bean;
+
+import com.mogo.eagle.core.data.BaseData;
+
+/**
+ * Created by pangfan on 2021/8/19
+ * 查询订单返回数据结构
+ */
+public class TaxiPassengerBaseRespBean extends BaseData {
+ public Object data;
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerCheckPhoneUpdateOrderReqBean.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerCheckPhoneUpdateOrderReqBean.java
new file mode 100644
index 0000000000..b4d6573bf5
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerCheckPhoneUpdateOrderReqBean.java
@@ -0,0 +1,16 @@
+package com.mogo.och.taxi.passenger.bean;
+
+/**
+ * Created by pangfan on 2021/8/19
+ * 验证手机号后四位同时流转订单状态
+ */
+public class TaxiPassengerCheckPhoneUpdateOrderReqBean {
+
+ public String orderNo;
+ public String phone;
+
+ public TaxiPassengerCheckPhoneUpdateOrderReqBean(String orderNo,String phone) {
+ this.orderNo = orderNo;
+ this.phone = phone;
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrderQueryReqBean.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrderQueryReqBean.java
new file mode 100644
index 0000000000..2cac9c0c99
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrderQueryReqBean.java
@@ -0,0 +1,16 @@
+package com.mogo.och.taxi.passenger.bean;
+
+/**
+ * Created by pangfan on 2021/8/19
+ * 查询订单信息请求数据结构
+ */
+public class TaxiPassengerOrderQueryReqBean {
+
+ public String driverSn;
+ public String orderNo;
+
+ public TaxiPassengerOrderQueryReqBean(String driverSn, String orderNo) {
+ this.driverSn = driverSn;
+ this.orderNo = orderNo;
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrderQueryRespBean.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrderQueryRespBean.java
new file mode 100644
index 0000000000..6b8ee1e58d
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrderQueryRespBean.java
@@ -0,0 +1,89 @@
+package com.mogo.och.taxi.passenger.bean;
+
+import com.mogo.eagle.core.data.BaseData;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Created by pangfan on 2021/8/19
+ * 查询订单返回数据结构
+ */
+public class TaxiPassengerOrderQueryRespBean extends BaseData {
+ public Result data;
+
+ public static class Result implements Comparable{
+ // 订单no
+ public String orderNo;
+ // 订单类型
+ public int orderType; //1即时单 2预约单
+ // 订单状态
+ public int orderStatus;
+ // 订单运营类型 (9出租车,10小巴)
+ public int businessType;
+ // 起始站点id
+ public int startSiteId;
+ // 起始站点名称
+ public String startSiteAddr;
+ // 起始站点坐标
+ public List startSitePoint; //wgs坐标,用于自动驾驶 [lon,lat]
+ public List startSiteGcjPoint; //高德坐标,用于本地计算距离 [lon,lat]
+ // 终点站点id
+ public int endSiteId;
+ // 终点站点名称
+ public String endSiteAddr;
+ // 终点站点坐标
+ public List endSitePoint; //wgs坐标,用于自动驾驶 [lon,lat]
+ public List endSiteGcjPoint; //高德坐标,用于计算距离 [lon,lat]
+
+ // 车牌号
+ public String carNumber;
+ //订单创建时间戳
+ public long createTime;
+ //开始服务时间戳:司机点击'开始服务'后订单状态更新成功的时间
+ public long startTime;
+ //预计用车时间:预约单=下单时的预约用车时间;即时单=派单成功的时间+预估的达到上车点的时间
+ public long bookingTime;
+ //乘客手机号
+ public String passengerPhone;
+ //订单多少乘客
+ public String passengerNum;
+
+ public long lineId = -1; //路线id,默认-1
+ public String csvFileUrl = ""; //轨迹文件下载的cos url,默认“”
+ public String csvFileMd5 = ""; //轨迹文件md5,默认“”
+ public String txtFileUrl = ""; //打点文件下载的cos url,默认“”
+ public String txtFileMd5 = ""; //轨迹文件md5,默认“”
+ public long contrailSaveTime; //上传轨迹完成时间戳ms:用于MEC本地手动导入轨迹验证时不会被云端轨迹覆盖
+ public String carModel = ""; //[optional] 车型号(如红旗H9),默认“”,暂不加入校验逻辑、用于人工排查问题
+ public String csvFileUrlDPQP = ""; //轨迹文件下载的cos url,默认“”
+ public String csvFileMd5DPQP = ""; //轨迹文件md5,默认“”
+ public String txtFileUrlDPQP = ""; //打点文件下载的cos url,默认“”
+ public String txtFileMd5DPQP = ""; //轨迹文件md5,默认“”
+ public long contrailSaveTimeDPQP; //上传轨迹完成时间戳ms:用于MEC本地手动导入轨迹验证时不会被云端轨迹覆盖
+
+ @Override
+ public int compareTo(Result o) {
+ boolean isEqual = this.orderNo.equals(o.orderNo);
+ return isEqual ? 0 : 1;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Result result = (Result) o;
+ return Objects.equals(orderNo, result.orderNo) &&
+ orderType == result.orderType &&
+ orderStatus == result.orderStatus &&
+ businessType == result.businessType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(orderNo, orderType, orderStatus, businessType, startSiteId,
+ startSiteAddr, startSitePoint, startSiteGcjPoint, endSiteId, endSiteAddr,
+ endSitePoint, endSiteGcjPoint, carNumber, createTime, startTime);
+ }
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrdersInServiceQueryRespBean.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrdersInServiceQueryRespBean.java
new file mode 100644
index 0000000000..7ac4a9ee6c
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerOrdersInServiceQueryRespBean.java
@@ -0,0 +1,17 @@
+package com.mogo.och.taxi.passenger.bean;
+
+import com.mogo.eagle.core.data.BaseData;
+
+import java.util.List;
+
+/**
+ * Created on 2021/9/8
+ * 查询全部服务中/待服务订单的返回数据
+ */
+public class TaxiPassengerOrdersInServiceQueryRespBean extends BaseData {
+ public Result data;
+
+ public static class Result {
+ public List servicing; //服务中订单
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerStartReqBean.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerStartReqBean.java
new file mode 100644
index 0000000000..741c9c2b69
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerStartReqBean.java
@@ -0,0 +1,23 @@
+package com.mogo.och.taxi.passenger.bean;
+
+/**
+ * Created by pangfan on 2021/8/19
+ * 司机端准备好或者乘客已验证上车请求参数
+ */
+public class TaxiPassengerStartReqBean {
+
+ public String orderNo;
+ public String sn;
+ public TaxiPassengerStartReqBean.Result loc;
+
+ public static class Result {
+ public Double lat;
+ public Double lon;
+ }
+
+ public TaxiPassengerStartReqBean(String sn, String orderNo, TaxiPassengerStartReqBean.Result point) {
+ this.sn = sn;
+ this.orderNo = orderNo;
+ this.loc = point;
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerVideoPlay.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerVideoPlay.kt
new file mode 100644
index 0000000000..a1caa20e79
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/bean/TaxiPassengerVideoPlay.kt
@@ -0,0 +1,3 @@
+package com.mogo.och.taxi.passenger.bean
+
+class TaxiPassengerVideoPlay(var url: String, var imageUrl: String, var title: String)
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/IOCHTaxiPassengerOrderStatusCallback.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/IOCHTaxiPassengerOrderStatusCallback.kt
new file mode 100644
index 0000000000..ba2fc56e72
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/IOCHTaxiPassengerOrderStatusCallback.kt
@@ -0,0 +1,21 @@
+package com.mogo.och.taxi.passenger.callback
+
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrderQueryRespBean
+
+/**
+ * Created on 2021/9/8
+ *
+ * Model->Presenter回调:订单相关(进行中/待服务单变更,当前进行单状态变更,新到预约单,抢单,抢单结果状态等等)
+ */
+interface IOCHTaxiPassengerOrderStatusCallback {
+ // 当前进行单状态变更:新到进行中订单、进行中单状态变更
+ fun onCurrentOrderStatusChanged(order: TaxiPassengerOrderQueryRespBean.Result?){}
+
+ // 当前位置距离上车点的距离(米)、预估时间(秒)
+ fun onCurrentOrderDistToEndChanged(meters: Long, timeInSecond: Long,stationDistance:Int){}
+
+ // 司机已确认开启自动驾驶环境
+ fun onDriverHasCheckedPilotCondition(isBoarded: Boolean){}
+
+ fun onMessageGo2OverMapview(){}
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/ITaxiPassengerCommonCallback.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/ITaxiPassengerCommonCallback.java
new file mode 100644
index 0000000000..937b4913b9
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/ITaxiPassengerCommonCallback.java
@@ -0,0 +1,5 @@
+package com.mogo.och.taxi.passenger.callback;
+
+public interface ITaxiPassengerCommonCallback {
+ void onCommonCallback();
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/ITaxiPassengerCommonValueCallback.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/ITaxiPassengerCommonValueCallback.java
new file mode 100644
index 0000000000..157925b458
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/callback/ITaxiPassengerCommonValueCallback.java
@@ -0,0 +1,5 @@
+package com.mogo.och.taxi.passenger.callback;
+
+public interface ITaxiPassengerCommonValueCallback {
+ void onCommonCallback(T t);
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/constant/TaxiPassengerConst.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/constant/TaxiPassengerConst.kt
new file mode 100644
index 0000000000..c1994b081d
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/constant/TaxiPassengerConst.kt
@@ -0,0 +1,37 @@
+package com.mogo.och.taxi.passenger.constant
+
+/**
+ * Created on 2021/12/6
+ */
+class TaxiPassengerConst {
+ companion object {
+
+ // OCH arouter 路由path
+ const val PATH = "/passenger/api"
+
+ // 开始服务启动自动驾驶等待时间(埋点上传)
+ const val LOOP_PERIOD_15S = 15 * 1000L
+
+ const val TAXI_AVERAGE_SPEED = 38
+
+
+ // 埋点key:接管后点击'自动驾驶'按钮启动
+ const val EVENT_KEY_RESTART_AUTOPILOT = "event_key_och_taxi_restart_autopilot"
+ // 埋点key:开始服务开启自动驾驶(成功/失败)
+ const val EVENT_KEY_START_SERVICE = "event_key_och_taxi_start_service"
+ const val EVENT_PARAM_SN = "sn"
+ const val EVENT_PARAM_TIME = "time"
+ const val EVENT_PARAM_START_NAME = "start_name"
+ const val EVENT_PARAM_END_NAME = "end_name"
+ const val EVENT_PARAM_ORDER_NUMBER = "order_num"
+ const val EVENT_PARAM_START_RESULT = "start_autopilot" // true/false
+ const val EVENT_PARAM_START_FAILURE_CODE = "start_autopilot_failure_code" // 启动自驾失败code
+ const val EVENT_PARAM_START_FAILURE_MSG = "start_autopilot_failure_msg" // 启动自驾失败原因
+ const val EVENT_PARAM_PLATE_NUM = "plate_number" // 车牌号
+ const val EVENT_PARAM_ENV_ONLINE = "env_online" // 是否线上环境:true/false
+
+ // 埋点key:开启自动驾驶前已识别的异常,会导致无法开启自驾
+ const val EVENT_KEY_AP_UNABLE_START_REASON = "event_key_och_taxi_ap_unable_start_reason"
+ const val EVENT_PARAM_UNABLE_START_REASON = "unable_start_reason";
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/constant/TaxiPassengerOrderStatusEnum.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/constant/TaxiPassengerOrderStatusEnum.kt
new file mode 100644
index 0000000000..19dfedc935
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/constant/TaxiPassengerOrderStatusEnum.kt
@@ -0,0 +1,47 @@
+package com.mogo.och.taxi.passenger.constant
+
+/**
+ * Created on 2021/12/7
+ *
+ * * Old code:START
+ * 未派单 0
+ * 去往上车站点 1
+ * 车辆已到达上车站点 2
+ * 乘客已到达上车站点 3
+ * 去往下车站点 4
+ * 到达下车站点 5
+ * 已完成 6
+ * 已取消 7
+ * Old code:END
+ *
+ * 0 订单创建(为派单),
+ * 10 已派上司机(司机去往上车点),
+ * 20 司机到达上车点,
+ * 30 乘客到达上车点,
+ * 40 服务中(去往目的地),
+ * 50 到达目的地,
+ * 60 已完成,
+ * 70 已取消
+ */
+enum class TaxiPassengerOrderStatusEnum(val code: Int) {
+ None( 0 ),
+ OnTheWayToStart( 10),
+ ArriveAtStart( 20),
+ UserArriveAtStart( 30),
+ OnTheWayToEnd( 40),
+ ArriveAtEnd( 50),
+ JourneyCompleted(60),//行程完成
+ Cancel( 70);
+
+ companion object {
+ @JvmStatic
+ fun valueOf(code: Int): TaxiPassengerOrderStatusEnum {
+ for (value in values()) {
+ if (value.code == code) {
+ return value
+ }
+ }
+ return None
+ }
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/model/AutopilotManager.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/model/AutopilotManager.kt
new file mode 100644
index 0000000000..85d06446d3
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/model/AutopilotManager.kt
@@ -0,0 +1,193 @@
+package com.mogo.och.taxi.passenger.model
+
+import com.elegant.network.utils.GsonUtil
+import com.mogo.commons.voice.AIAssist
+import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
+import com.mogo.eagle.core.data.config.FunctionBuildConfig
+import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
+import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
+import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
+import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
+import com.mogo.eagle.core.utilcode.util.ToastUtils
+import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
+import com.mogo.och.common.module.manager.OCHAdasAbilityManager
+import com.mogo.och.common.module.utils.PinYinUtil
+import com.mogo.och.common.module.voice.VoiceNotice
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerBaseRespBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerStartReqBean
+import com.mogo.och.taxi.passenger.constant.TaxiPassengerOrderStatusEnum
+import com.mogo.och.taxi.passenger.network.TaxiPassengerServiceManager
+import com.mogo.och.taxi.passenger.utils.TaxiPassengerAnalyticsManager
+
+object AutopilotManager : IMoGoAutopilotStatusListener {
+
+ private const val TAG = "AutopilotManager"
+
+ init {
+ CallerAutoPilotStatusListenerManager.addListener(TAG, this)
+ }
+ //检测当前订单
+ private fun checkCurrentOCHOrder(): Boolean {
+ return TaxiPassengerModel.currentOCHOrder != null && TaxiPassengerModel.currentOCHOrder!!.startSiteGcjPoint != null && TaxiPassengerModel.currentOCHOrder!!.endSiteGcjPoint != null
+ }
+
+
+ fun startAutopilot() {
+ if (!checkCurrentOCHOrder()) {
+ CallerLogger.e(
+ SceneConstant.M_TAXI_P + TAG,
+ "no order or order is empty."
+ )
+ ToastUtils.showShort("当前订单不存在或异常!")
+ return
+ }
+ if (TaxiPassengerModel.currentOCHOrder!!.orderStatus == TaxiPassengerOrderStatusEnum.UserArriveAtStart.code) {
+ startServicePilotDone()
+ }
+ if(CallerAutoPilotStatusListenerManager.getState()
+ == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING){
+ ToastUtils.showShort("自驾中、请勿重复启动")
+ return
+ }
+ if (!FunctionBuildConfig.isDemoMode && !OCHAdasAbilityManager.getInstance().autopilotAbilityStatus) {
+ ToastUtils.showLong(
+ OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason +
+ ", 请稍候重试"
+ )
+ TaxiPassengerAnalyticsManager.triggerUnableStartAPReasonEvent(
+ TaxiPassengerModel.currentOCHOrder!!.startSiteAddr,
+ TaxiPassengerModel.currentOCHOrder!!.endSiteAddr,
+ TaxiPassengerModel.currentOCHOrder!!.orderNo,
+ OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason
+ )
+ return
+ }
+ val parameters = initAutopilotControlParameters()
+ if (parameters == null) {
+ CallerLogger.d(
+ SceneConstant.M_TAXI_P + TAG,
+ "AutopilotControlParameters is empty."
+ )
+ return
+ }
+ CallerAutoPilotControlManager.startAutoPilot(parameters)
+ CallerLogger.d(
+ SceneConstant.M_TAXI_P + TAG,
+ "start autopilot with parameter: %s",
+ GsonUtil.jsonFromObject(parameters)
+ + " ,startSiteName=" + TaxiPassengerModel.currentOCHOrder!!.startSiteAddr
+ + " ,endSiteName=" + TaxiPassengerModel.currentOCHOrder!!.endSiteAddr
+ )
+ TaxiPassengerAnalyticsManager.triggerStartAutopilotEvent(false, false, TaxiPassengerModel.currentOCHOrder!!.startSiteAddr, TaxiPassengerModel.currentOCHOrder!!.endSiteAddr, TaxiPassengerModel.currentOCHOrder!!.orderNo)
+ }
+
+ private fun initAutopilotControlParameters(): AutopilotControlParameters? {
+ if (!checkCurrentOCHOrder()) {
+ CallerLogger.e(
+ SceneConstant.M_TAXI_P + TAG,
+ "no order or order is empty."
+ )
+ ToastUtils.showShort("当前订单不存在或异常!")
+ return null
+ }
+ val parameters = AutopilotControlParameters()
+ val startWgsLon = TaxiPassengerModel.currentOCHOrder!!.startSitePoint[0]
+ val startWgsLat = TaxiPassengerModel.currentOCHOrder!!.startSitePoint[1]
+ val endWgsLon = TaxiPassengerModel.currentOCHOrder!!.endSitePoint[0]
+ val endWgsLat = TaxiPassengerModel.currentOCHOrder!!.endSitePoint[1]
+ parameters.vehicleType = TaxiPassengerModel.currentOCHOrder!!.businessType
+ parameters.startName =
+ PinYinUtil.getPinYinHeadChar(TaxiPassengerModel.currentOCHOrder!!.startSiteAddr) // 起点名称拼音首字母大写:科学城B区2号门(KXCBQ2HM)
+ parameters.endName =
+ PinYinUtil.getPinYinHeadChar(TaxiPassengerModel.currentOCHOrder!!.endSiteAddr) // 终点名称拼音首字母大写:科学城C区三号门(KXCCQSHM)
+ parameters.startLatLon =
+ AutopilotControlParameters.AutoPilotLonLat(startWgsLat, startWgsLon)
+ parameters.endLatLon = AutopilotControlParameters.AutoPilotLonLat(endWgsLat, endWgsLon)
+ if (parameters.autoPilotLine == null) {
+ parameters.autoPilotLine = AutopilotControlParameters.AutoPilotLine(
+ TaxiPassengerModel.currentOCHOrder!!.lineId,
+ TaxiPassengerModel.currentOCHOrder!!.csvFileUrl,
+ TaxiPassengerModel.currentOCHOrder!!.csvFileMd5,
+ TaxiPassengerModel.currentOCHOrder!!.txtFileUrl,
+ TaxiPassengerModel.currentOCHOrder!!.txtFileMd5,
+ TaxiPassengerModel.currentOCHOrder!!.contrailSaveTime,
+ TaxiPassengerModel.currentOCHOrder!!.carModel,
+ TaxiPassengerModel.currentOCHOrder!!.csvFileUrlDPQP,
+ TaxiPassengerModel.currentOCHOrder!!.csvFileMd5DPQP,
+ TaxiPassengerModel.currentOCHOrder!!.txtFileUrlDPQP,
+ TaxiPassengerModel.currentOCHOrder!!.txtFileMd5DPQP,
+ TaxiPassengerModel.currentOCHOrder!!.contrailSaveTimeDPQP
+ )
+ }
+ return parameters
+ }
+
+ /**
+ * 将业务订单信息保存,鹰眼可取用
+ */
+ fun updateAutopilotControlParameters() {
+ val parameters = initAutopilotControlParameters()
+ if (null == parameters) {
+ CallerLogger.e(
+ SceneConstant.M_TAXI_P + TAG,
+ "AutopilotControlParameters is empty."
+ )
+ return
+ }
+ CallerLogger.d(
+ SceneConstant.M_TAXI_P + TAG,
+ "AutopilotControlParameters is update."
+ )
+ CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(parameters)
+ }
+
+ fun clearAutopilotControlParameters() {
+ CallerLogger.d(
+ SceneConstant.M_TAXI_P + TAG,
+ "AutopilotControlParameters is clear."
+ )
+ CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(null)
+ }
+
+ override fun onAutopilotStatusResponse(state: Int) {
+ // 启动自驾成功
+ when (state) {
+ IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING -> {
+ if (TaxiPassengerModel.currentOCHOrder != null && TaxiPassengerModel.curOrderStatus === TaxiPassengerOrderStatusEnum.UserArriveAtStart) {
+ TaxiPassengerAnalyticsManager.triggerStartAutopilotEvent(
+ false,
+ true,
+ TaxiPassengerModel.currentOCHOrder!!.startSiteAddr,
+ TaxiPassengerModel.currentOCHOrder!!.endSiteAddr,
+ TaxiPassengerModel.currentOCHOrder!!.orderNo
+ )
+ startServicePilotDone()
+ }
+ }
+ else -> {}
+ }
+ }
+
+ /**
+ * 乘客屏启动自动驾驶成功
+ */
+ fun startServicePilotDone() {
+ if (TaxiPassengerModel.currentOCHOrder == null) return
+ val result = TaxiPassengerStartReqBean.Result()
+ val currentLocation = CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02()
+ result.lat = currentLocation.latitude
+ result.lon = currentLocation.longitude
+ TaxiPassengerServiceManager.startServicePilotDone(
+ TaxiPassengerModel.currentOCHOrder!!.orderNo, result,
+ object : OchCommonServiceCallback {
+ override fun onSuccess(data: TaxiPassengerBaseRespBean) {
+ VoiceNotice.showNotice("坐稳扶好,我们出发咯!", AIAssist.LEVEL2)
+ }
+ override fun onFail(code: Int, msg: String) {}
+ })
+ }
+
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/model/TaxiPassengerModel.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/model/TaxiPassengerModel.kt
new file mode 100644
index 0000000000..b788ef9dd5
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/model/TaxiPassengerModel.kt
@@ -0,0 +1,382 @@
+package com.mogo.och.taxi.passenger.model
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.net.ConnectivityManager
+import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
+import com.mogo.commons.module.intent.IMogoIntentListener
+import com.mogo.commons.module.intent.IntentManager
+import com.mogo.commons.voice.AIAssist
+import com.mogo.eagle.core.data.map.MogoLocation
+import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxEventListener
+import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager
+import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxEventListenerManager
+import com.mogo.eagle.core.function.call.order.CallerOrderListenerManager
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_TAXI_P
+import com.mogo.eagle.core.utilcode.util.NetworkUtils
+import com.mogo.eagle.core.utilcode.util.ToastUtils
+import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
+import com.mogo.och.common.module.callback.OchAdasStartFailureCallback
+import com.mogo.och.common.module.manager.AbnormalFactorsLoopManager
+import com.mogo.och.common.module.manager.OCHAdasAbilityManager
+import com.mogo.och.common.module.manager.distancemamager.IDistanceListener
+import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceManager
+import com.mogo.och.common.module.manager.loopmanager.BizLoopManager
+import com.mogo.och.common.module.manager.loopmanager.LoopInfo
+import com.mogo.och.common.module.utils.RxUtils
+import com.mogo.och.common.module.voice.VoiceNotice
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerBaseRespBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrderQueryRespBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrdersInServiceQueryRespBean
+import com.mogo.och.taxi.passenger.callback.IOCHTaxiPassengerOrderStatusCallback
+import com.mogo.och.taxi.passenger.callback.ITaxiPassengerCommonCallback
+import com.mogo.och.taxi.passenger.constant.TaxiPassengerConst
+import com.mogo.och.taxi.passenger.constant.TaxiPassengerOrderStatusEnum
+import com.mogo.och.taxi.passenger.constant.TaxiPassengerOrderStatusEnum.Companion.valueOf
+import com.mogo.och.taxi.passenger.network.TaxiPassengerServiceManager
+import com.mogo.och.taxi.passenger.utils.TaxiPassengerAnalyticsManager
+import java.util.concurrent.ConcurrentHashMap
+
+/**
+ * Created by pangfan on 2021/8/19
+ *
+ * 网约车 - 出租车业务逻辑处理
+ */
+@SuppressLint("StaticFieldLeak")
+object TaxiPassengerModel {
+
+ private var mContext: Context? = null
+
+ private val TAG = TaxiPassengerModel::class.java.simpleName
+
+ private const val STARTREADYTOAUTOPILOT = "startReadyToAutopilot"
+ private const val MINANDWAITSERVICE = "mInAndWaitService"
+
+ // 获取当前订单
+ @Volatile
+ var currentOCHOrder: TaxiPassengerOrderQueryRespBean.Result? = null//当前订单
+
+ private val mOrderStatusCallbackMap: MutableMap = ConcurrentHashMap()
+
+ fun setOrderStatusCallback(tag: String?, callback: IOCHTaxiPassengerOrderStatusCallback?) {
+ if (tag == null || "" == tag) return
+ if (callback == null) {
+ mOrderStatusCallbackMap.remove(tag)
+ return
+ }
+ mOrderStatusCallbackMap[tag] = callback
+ }
+
+ fun init(context: Context) {
+ mContext = context.applicationContext
+ initListeners()
+ RxUtils.errCatch()
+ startOrStopOrderLoop()
+ }
+
+ /**
+ * 订单轮询 初始化主Fragment的Presenter init 调用
+ */
+ private fun startOrStopOrderLoop() {
+ if (NetworkUtils.isConnected(mContext)) {
+ startOrStopOrderLoop(true)
+ }
+ }
+
+ /**
+ * 关闭订单轮训 页面摧毁时
+ */
+ fun release() {
+ startOrStopOrderLoop(false)
+ //startOrStopQueryOrderRemaining(false)
+ releaseListeners()
+ }
+
+ private fun initListeners() {
+
+ // 2021.11.1重构自动驾驶 实现接口 IMoGoAutopilotStatusListener 注册监听 替换IMogoAdasOCHCallback接口
+ IntentManager.getInstance().registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener)
+
+ AbnormalFactorsLoopManager.startLoopAbnormalFactors(mContext!!)
+
+ //开启自驾后 异常信息返回
+ OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(mAdasStartFailureListener)
+ CallerMsgBoxEventListenerManager.addListener(TAG, iMsgBoxEventListener)
+ TrajectoryAndDistanceManager.addDistanceListener(TAG, distanceListener)
+ }
+
+ private fun releaseListeners() {
+ MogoAiCloudSocketManager.getInstance(mContext).unregisterLifecycleListener(10010)
+ AbnormalFactorsLoopManager.stopLoopAbnormalFactors()
+ OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(null)
+ CallerMsgBoxEventListenerManager.removeListener(iMsgBoxEventListener)
+ TrajectoryAndDistanceManager.removeListener(TAG)
+ }
+
+ /**
+ * 订单轮训
+ * @param start true 开启订单轮训
+ * false 关闭订单轮训
+ */
+ private fun startOrStopOrderLoop(start: Boolean) {
+ d(M_TAXI_P + TAG, "startOrStopOrderLoop() $start")
+ if (start) {
+ BizLoopManager.setLoopFunction(MINANDWAITSERVICE,LoopInfo(2, TaxiPassengerModel::queryInAndWaitOrders))
+ } else {
+ BizLoopManager.removeLoopFunction(MINANDWAITSERVICE)
+ }
+ }
+
+ /**
+ * 查询订单状态:进行中/待服务(轮询防止因crash导致应用重启、断网没收到推送等)
+ *
+ * 注:只有在本地缓存mCurrentOCHOrder为null时(已完成or已取消有明确结果)或id相同且status不同时,
+ * 才更新最新进行中单到本地
+ */
+ private fun queryInAndWaitOrders() {
+ TaxiPassengerServiceManager.queryOrdersInAndWaitService(
+ object : OchCommonServiceCallback {
+ override fun onSuccess(data: TaxiPassengerOrdersInServiceQueryRespBean) {
+ if (data.data == null) {
+ if(currentOCHOrder!=null){
+ queryCurOrderStatus()
+ }
+ return
+ }
+ //1. 处理进行中订单
+ if (data.data.servicing != null && data.data.servicing.isNotEmpty()) {
+ // 1.1. 当存在进行中单时:对本地currentOrder进行更新
+ val currentOrder = data.data.servicing[0]
+ if(currentOCHOrder==null||currentOCHOrder?.orderStatus!=currentOrder.orderStatus){
+ currentOCHOrder = currentOrder
+ orderStatusChange()
+ }else {
+ currentOCHOrder = currentOrder
+ }
+ }else{
+ if(currentOCHOrder!=null){
+ queryCurOrderStatus()
+ }
+ }
+ }
+
+ override fun onError() {
+ e(M_TAXI_P + TAG, "queryInAndWaitOrders onError")
+ }
+ override fun onFail(code: Int, msg: String) {
+ e(M_TAXI_P + TAG, "queryInAndWaitOrders$code$msg")
+ }
+ })
+ }
+
+ //仅用于轮询时查到本地有mCurrentOCHOrder但请求结果无进行中单or orderId不一致是复查本地currentOrder
+ private fun queryCurOrderStatus() {
+ currentOCHOrder?.orderNo?.let {
+ TaxiPassengerServiceManager.queryOrderById(
+ mContext!!, it,
+ object : OchCommonServiceCallback {
+ override fun onSuccess(data: TaxiPassengerOrderQueryRespBean) {
+ if (data.data != null && currentOCHOrder != null && currentOCHOrder!!.orderNo == data.data.orderNo) {
+ if (data.data.orderStatus == TaxiPassengerOrderStatusEnum.Cancel.code || data.data.orderStatus == TaxiPassengerOrderStatusEnum.JourneyCompleted.code || data.data.orderStatus == TaxiPassengerOrderStatusEnum.None.code) {
+ currentOCHOrder = data.data
+ orderStatusChange()
+ currentOCHOrder = null
+ } else {
+ currentOCHOrder = data.data
+ orderStatusChange()
+ }
+ }
+ }
+
+ override fun onFail(code: Int, msg: String) {}
+ })
+ }
+ }
+
+ // 获取当前订单状态
+ val curOrderStatus: TaxiPassengerOrderStatusEnum
+ get() {
+ val order: TaxiPassengerOrderQueryRespBean.Result =
+ currentOCHOrder
+ ?: return TaxiPassengerOrderStatusEnum.None
+ return valueOf(order.orderStatus)
+ }
+
+ //监听网络变化,避免启动机器时无网导致无法更新订单信息
+ private val distanceListener: IDistanceListener = object : IDistanceListener {
+ var allDistance = 0f
+ override fun stationDistanceCallback(stationDistance: Float) {
+ allDistance = stationDistance
+ }
+
+ override fun distanceCallback(distance: Float) {
+
+ val lastTime: Double = distance / TaxiPassengerConst.TAXI_AVERAGE_SPEED * 3.6 //秒
+
+ for (callback in mOrderStatusCallbackMap.values) {
+ callback.onCurrentOrderDistToEndChanged(distance.toLong(),lastTime.toLong(),allDistance.toInt())
+ }
+ }
+ }
+ private val mNetWorkIntentListener = IMogoIntentListener { intentStr, intent ->
+ d(M_TAXI_P + TAG, "onIntentReceived = %s", intentStr)
+ if (ConnectivityManager.CONNECTIVITY_ACTION == intentStr) {
+ if (NetworkUtils.isConnected(mContext)) {
+ startOrStopOrderLoop(true)
+ }
+ }
+ }
+
+ private val mAdasStartFailureListener: OchAdasStartFailureCallback = object : OchAdasStartFailureCallback {
+ override fun onStartAutopilotFailure(startFailedCode: String, startFailedMessage: String) {
+ TaxiPassengerAnalyticsManager.triggerStartAutopilotFailureEventByAdas(startFailedCode, startFailedMessage)
+ }
+ }
+ private val iMsgBoxEventListener: IMsgBoxEventListener = object : IMsgBoxEventListener {
+ override fun onSummaryClickEvent() {
+ if (currentOCHOrder == null) {
+ ToastUtils.showLong("行程已结束")
+ } else {
+ for (callback in mOrderStatusCallbackMap.values) {
+ callback.onMessageGo2OverMapview()
+ }
+ }
+ }
+ }
+
+ fun checkPhoneAndUpdateStatus(
+ phoneTail: String?,
+ commonCallback: ITaxiPassengerCommonCallback?
+ ) {
+ if (currentOCHOrder == null) return
+ TaxiPassengerServiceManager.checkPhoneAndUpdateOrderStatus(
+ currentOCHOrder!!.orderNo,
+ phoneTail, object : OchCommonServiceCallback {
+ override fun onSuccess(data: TaxiPassengerBaseRespBean) {
+ if (data.code == 0 && currentOCHOrder != null) {
+ currentOCHOrder!!.orderStatus = TaxiPassengerOrderStatusEnum.UserArriveAtStart.code
+ //乘客验证成功,更新订单状态为 "乘客已上车", 立马弹出乘客开始行程页面,不再等待轮询
+ orderStatusChange()
+ VoiceNotice.showNotice("验证成功!关闭车门并佩戴安全带后开启行程吧!", AIAssist.LEVEL2)
+ }
+ commonCallback?.onCommonCallback()
+ }
+
+ override fun onFail(code: Int, msg: String) {
+ ToastUtils.showLong("当前网络异常,请重新验证;若始终异常,请您在手机端取消行程,给您带来不便,十分抱歉!")
+ e(
+ M_TAXI_P + TAG,
+ "提交用户输入的手机后4位、并进行状态扭转 后台结果错误$code$msg"
+ )
+ }
+ })
+ }
+
+ fun orderStatusChange(){
+ orderStatusChangeInner()
+ if (mOrderStatusCallbackMap.isNotEmpty()) {
+ d(M_TAXI_P + TAG, "最新的状态${curOrderStatus}")
+ for (callback in mOrderStatusCallbackMap.values) {
+ callback.onCurrentOrderStatusChanged(currentOCHOrder)
+ }
+ }
+ }
+
+ private fun orderStatusChangeInner() {
+ when (curOrderStatus) {
+ TaxiPassengerOrderStatusEnum.OnTheWayToStart -> {
+ }
+ TaxiPassengerOrderStatusEnum.ArriveAtStart -> {
+ }
+ TaxiPassengerOrderStatusEnum.UserArriveAtStart -> {
+ //开启轮询司机是否已准备好开启自动驾驶的环境
+ setStation()
+ }
+ TaxiPassengerOrderStatusEnum.OnTheWayToEnd -> {
+ CallerFuncBizManager.bizProvider.queryV2XEvents() //全览模式的V2X事件轮询开始
+ //startOrStopQueryOrderRemaining(true)
+ AutopilotManager.updateAutopilotControlParameters()
+ startOrStopReadyToAutopilotLoop(false)
+ setStation()
+ CallerOrderListenerManager.invokeOrderStatus(true)
+ }
+ TaxiPassengerOrderStatusEnum.ArriveAtEnd -> {
+ AutopilotManager.clearAutopilotControlParameters()
+ //startOrStopQueryOrderRemaining(false)
+ CallerOrderListenerManager.invokeOrderStatus(false)
+ cleanStation()
+ }
+ TaxiPassengerOrderStatusEnum.JourneyCompleted -> {
+ AutopilotManager.clearAutopilotControlParameters()
+ //startOrStopQueryOrderRemaining(false)
+ cleanStation()
+ }
+ TaxiPassengerOrderStatusEnum.Cancel -> {
+ AutopilotManager.clearAutopilotControlParameters()
+ //startOrStopQueryOrderRemaining(false)
+ startOrStopReadyToAutopilotLoop(false)
+ cleanStation()
+ }
+ TaxiPassengerOrderStatusEnum.None -> TODO()
+ }
+ }
+
+ /**
+ * 查询司机是否已确认可开启自动驾驶
+ */
+ private fun loopQueryPilotStatus() {
+ if (currentOCHOrder == null) return
+ TaxiPassengerServiceManager.queryPilotStatus(
+ currentOCHOrder!!.orderNo,
+ object : OchCommonServiceCallback {
+ override fun onSuccess(data: TaxiPassengerBaseRespBean) {
+ if (data.code == 0 && data.data == true) {
+ updateAutopilotStatus(true)
+ startOrStopReadyToAutopilotLoop(false)
+ }
+ }
+
+ override fun onFail(code: Int, msg: String) {
+ updateAutopilotStatus(false)
+ }
+ })
+ }
+
+ fun updateAutopilotStatus(isBoarded: Boolean) {
+ if (mOrderStatusCallbackMap.isNotEmpty()) {
+ for (callback in mOrderStatusCallbackMap.values) {
+ callback.onDriverHasCheckedPilotCondition(isBoarded)
+ }
+ }
+ }
+
+ fun startOrStopReadyToAutopilotLoop(isStart: Boolean) {
+ if (isStart) {
+ BizLoopManager.setLoopFunction(STARTREADYTOAUTOPILOT, LoopInfo(1, TaxiPassengerModel::loopQueryPilotStatus))
+ CallerLogger.i(M_TAXI_P + TAG, "startReadyToAutopilot()")
+ } else {
+ BizLoopManager.removeLoopFunction(STARTREADYTOAUTOPILOT)
+ CallerLogger.i(M_TAXI_P + TAG, "stopReadyToAutopilot()")
+ }
+ }
+
+ fun setStation() {
+ if (currentOCHOrder != null) {
+ val startStation = MogoLocation()
+ startStation.longitude = currentOCHOrder!!.startSiteGcjPoint[0]
+ startStation.latitude = currentOCHOrder!!.startSiteGcjPoint[1]
+ val endStation = MogoLocation()
+ endStation.longitude = currentOCHOrder!!.endSiteGcjPoint[0]
+ endStation.latitude = currentOCHOrder!!.endSiteGcjPoint[1]
+ TrajectoryAndDistanceManager.setStationPoint(startStation, endStation, currentOCHOrder!!.lineId)
+ }
+ }
+
+ fun cleanStation() {
+ TrajectoryAndDistanceManager.setStationPoint(null, null, -1L)
+ }
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/network/TaxiPassengerServiceApi.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/network/TaxiPassengerServiceApi.kt
new file mode 100644
index 0000000000..df1d43e9a0
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/network/TaxiPassengerServiceApi.kt
@@ -0,0 +1,92 @@
+package com.mogo.och.taxi.passenger.network
+
+import com.mogo.cloud.passport.MoGoAiCloudClientConfig
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerBaseRespBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerCheckPhoneUpdateOrderReqBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrderQueryReqBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrderQueryRespBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrdersInServiceQueryRespBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerStartReqBean
+import io.reactivex.Observable
+import retrofit2.http.Body
+import retrofit2.http.GET
+import retrofit2.http.Header
+import retrofit2.http.Headers
+import retrofit2.http.POST
+import retrofit2.http.Query
+
+/**
+ * Created by pangfan on 2021/8/19
+ *
+ * 网约车-出租车接口定义
+ */
+internal interface TaxiPassengerServiceApi {
+ /**
+ * 查询全部服务中/待服务订单(没有的时候返回code 0,空列表)
+ * @param driverSn
+ * @return
+ */
+ @Headers("Content-type:application/json;charset=UTF-8")
+ @GET("/autopilot-car-hailing/order/v2/driver/taxi/passenger/orderInService/query")
+ fun queryOrdersInAndWaitService(
+ @Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
+ @Header("ticket") ticket: String=MoGoAiCloudClientConfig.getInstance().token,
+ @Query("driverSn") driverSn: String
+ ): Observable
+
+ /**
+ * 通过orderNo查询订单信息(用于本地已经有orderNo时)
+ * @param data
+ * @return
+ */
+ @Headers("Content-type:application/json;charset=UTF-8")
+ @POST("/autopilot-car-hailing/order/v2/driver/taxi/passenger/queryOrderById")
+ fun queryOrderById(
+ @Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
+ @Header("ticket") ticket: String=MoGoAiCloudClientConfig.getInstance().token,
+ @Body data: TaxiPassengerOrderQueryReqBean
+ ): Observable
+
+ /**
+ * 提交用户输入的手机后4位、并进行状态扭转
+ * @param data
+ * @return
+ */
+ @Headers("Content-type:application/json;charset=UTF-8")
+ @POST("/autopilot-car-hailing/cab/flow/v1/driver/taxi/passenger/verification/phone")
+ fun checkPhoneAndUpdateOrderStatus(
+ @Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
+ @Header("ticket") ticket: String=MoGoAiCloudClientConfig.getInstance().token,
+ @Body data: TaxiPassengerCheckPhoneUpdateOrderReqBean?
+ ): Observable
+
+ /**
+ * 查询司机是否已确认可开启自动驾驶
+ * @param appId
+ * @param ticket
+ * @param orderNo
+ * @return
+ */
+ @Headers("Content-type:application/json;charset=UTF-8")
+ @GET("/autopilot-car-hailing/cab/flow/v1/driver/taxi/pilot/status")
+ fun queryPilotStatus(
+ @Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
+ @Header("ticket") ticket: String=MoGoAiCloudClientConfig.getInstance().token,
+ @Query("orderNo") orderNo: String
+ ): Observable
+
+ /**
+ * 乘客屏启动自动驾驶成功
+ * @param appId
+ * @param ticket
+ * @param data
+ * @return
+ */
+ @Headers("Content-type:application/json;charset=UTF-8")
+ @POST("/autopilot-car-hailing/cab/flow/v1/driver/taxi/passenger/startServicePilot")
+ fun startServicePilotDone(
+ @Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
+ @Header("ticket") ticket: String= MoGoAiCloudClientConfig.getInstance().token,
+ @Body data: TaxiPassengerStartReqBean
+ ): Observable
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/network/TaxiPassengerServiceManager.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/network/TaxiPassengerServiceManager.kt
new file mode 100644
index 0000000000..661c7c6873
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/network/TaxiPassengerServiceManager.kt
@@ -0,0 +1,127 @@
+package com.mogo.och.taxi.passenger.network
+
+import android.content.Context
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrdersInServiceQueryRespBean
+import com.mogo.commons.AbsMogoApplication
+import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerBaseRespBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerCheckPhoneUpdateOrderReqBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerStartReqBean
+import com.mogo.eagle.core.network.MoGoRetrofitFactory
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_TAXI_P
+import com.mogo.och.common.module.biz.constant.OchCommonConst
+import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
+import com.mogo.och.common.module.biz.network.OchCommonSubscribeImpl
+import com.mogo.och.common.module.biz.network.interceptor.transformTry
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrderQueryReqBean
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrderQueryRespBean
+
+/**
+ * Created by pangfan on 2021/8/19
+ */
+object TaxiPassengerServiceManager {
+
+ private val mOCHTaxiServiceApi: TaxiPassengerServiceApi =
+ MoGoRetrofitFactory.getInstance(OchCommonConst.getBaseUrl()).create(TaxiPassengerServiceApi::class.java)
+
+ private const val TAG = "TaxiPassengerServiceManager"
+
+ private var draiverSnCacher = ""
+
+ /**
+ * 获取Bus司机端的sn
+ * @return
+ */
+ val draiverSn: String
+ get(){
+ val serverToken = CallerTelematicManager.getServerToken()
+ if (serverToken != draiverSnCacher && serverToken.isNotEmpty()) {
+ draiverSnCacher = serverToken
+ }
+ return draiverSnCacher
+ }
+ val context:Context
+ get() {
+ return AbsMogoApplication.getApp()
+ }
+
+ private fun beforeNet():Boolean{
+ if (draiverSn.isBlank()) {
+ CallerLogger.e(M_TAXI_P + TAG, "没有司机屏sn 请稍等在请求")
+ return true
+ }
+ return false
+ }
+ /**
+ * 查询全部服务中/待服务订单列表
+ * @param callback
+ */
+ @JvmStatic
+ fun queryOrdersInAndWaitService(
+ callback: OchCommonServiceCallback?
+ ) {
+ if(beforeNet()){
+ return
+ }
+ mOCHTaxiServiceApi.queryOrdersInAndWaitService(driverSn = draiverSn) //获取到司机端的sn
+ .transformTry()
+ .subscribe(OchCommonSubscribeImpl(context, callback, "queryOrdersInAndWaitService"))
+ }
+
+ @JvmStatic
+ fun checkPhoneAndUpdateOrderStatus(
+ orderNo: String?,
+ phone: String?,
+ callback: OchCommonServiceCallback?
+ ) {
+ mOCHTaxiServiceApi.checkPhoneAndUpdateOrderStatus(data= TaxiPassengerCheckPhoneUpdateOrderReqBean(orderNo, phone))
+ .transformTry()
+ .subscribe(OchCommonSubscribeImpl(context, callback, "checkPhoneAndUpdateOrderStatus"))
+ }
+
+ @JvmStatic
+ fun queryPilotStatus(
+ orderNo: String,
+ callback: OchCommonServiceCallback?
+ ) {
+ mOCHTaxiServiceApi.queryPilotStatus(orderNo = orderNo)
+ .transformTry()
+ .subscribe(OchCommonSubscribeImpl(context, callback, "queryPilotStatus"))
+ }
+ @JvmStatic
+ fun startServicePilotDone(
+ orderNo: String?, loc: TaxiPassengerStartReqBean.Result?,
+ callback: OchCommonServiceCallback?
+ ) {
+ if(beforeNet()){
+ return
+ }
+ mOCHTaxiServiceApi.startServicePilotDone(data = TaxiPassengerStartReqBean(draiverSn, orderNo, loc))
+ .transformTry()
+ .subscribe(OchCommonSubscribeImpl(context, callback, "startServicePilotDone"))
+ }
+
+ /**
+ * 通过orderId查询订单信息(用于本地已经有orderId时)
+ * @param context
+ * @param orderNo
+ * @param callback
+ */
+ @JvmStatic
+ fun queryOrderById(
+ context: Context, orderNo: String?,
+ callback: OchCommonServiceCallback?
+ ) {
+ if(beforeNet()){
+ return
+ }
+ mOCHTaxiServiceApi.queryOrderById(
+ data=TaxiPassengerOrderQueryReqBean(draiverSn, orderNo)
+ )
+ .transformTry()
+ .subscribe(OchCommonSubscribeImpl(context, callback, "queryOrderById"))
+ }
+
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/presenter/BaseTaxiPassengerPresenter.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/presenter/BaseTaxiPassengerPresenter.kt
new file mode 100644
index 0000000000..99d7e9e28c
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/presenter/BaseTaxiPassengerPresenter.kt
@@ -0,0 +1,153 @@
+package com.mogo.och.taxi.passenger.presenter
+
+import androidx.lifecycle.LifecycleOwner
+import com.mogo.commons.AbsMogoApplication
+import com.mogo.commons.mvp.Presenter
+import com.mogo.eagle.core.function.call.biz.CallerFuncBizManager
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
+import com.mogo.eagle.core.utilcode.util.UiThreadHandler
+import com.mogo.och.common.module.manager.OCHAdasAbilityManager
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrderQueryRespBean
+import com.mogo.och.taxi.passenger.callback.IOCHTaxiPassengerOrderStatusCallback
+import com.mogo.och.taxi.passenger.constant.TaxiPassengerOrderStatusEnum
+import com.mogo.och.taxi.passenger.model.AutopilotManager
+import com.mogo.och.taxi.passenger.model.TaxiPassengerModel
+import com.mogo.och.taxi.passenger.ui.TaxiPassengerBaseFragment
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/3/4
+ */
+class BaseTaxiPassengerPresenter(view: TaxiPassengerBaseFragment?) :
+ Presenter(view), IOCHTaxiPassengerOrderStatusCallback {
+
+ init {
+ TaxiPassengerModel.init(AbsMogoApplication.getApp())
+ OCHAdasAbilityManager.getInstance().init(AbsMogoApplication.getApp())
+ initListeners()
+ }
+
+ override fun onCreate(owner: LifecycleOwner) {
+ super.onCreate(owner)
+ d(SceneConstant.M_TAXI_P + TAG, "网约车-出租车拿到订单")
+ }
+
+ override fun onDestroy(owner: LifecycleOwner) {
+ super.onDestroy(owner)
+ releaseListeners()
+ TaxiPassengerModel.release()
+ OCHAdasAbilityManager.getInstance().release()
+ }
+
+ private fun initListeners() {
+ TaxiPassengerModel.setOrderStatusCallback("BaseTaxiPassengerPresenter", this)
+ }
+
+ private fun releaseListeners() {
+ TaxiPassengerModel.setOrderStatusCallback("BaseTaxiPassengerPresenter", null)
+ }
+
+ override fun onCurrentOrderStatusChanged(order: TaxiPassengerOrderQueryRespBean.Result?) {
+ order?.let {
+ updateOrderView(order)
+ }
+ }
+
+ override fun onCurrentOrderDistToEndChanged(
+ meters: Long,
+ timeInSecond: Long,
+ stationDistance: Int
+ ) {
+ }
+
+ private fun updateOrderView(order: TaxiPassengerOrderQueryRespBean.Result?) {
+ order?.let {
+ setItineraryVisibility()
+ when (TaxiPassengerModel.curOrderStatus) {
+ TaxiPassengerOrderStatusEnum.ArriveAtStart -> {
+ // 20 司机到达上车点
+ mView?.showOrHideArrivedEndLayout(isShow = false)
+ mView?.showOrHidePressengerCheckPager(true, order.startSiteAddr,
+ order.endSiteAddr, order.passengerNum, order.passengerPhone)
+ mView?.showOrHideStartAutopilotView(isShow = false)
+ }
+
+ TaxiPassengerOrderStatusEnum.UserArriveAtStart -> {
+ // 30 乘客到达上车点
+ mView?.showOrHideArrivedEndLayout(isShow = false)
+ mView?.showOrHidePressengerCheckPager(isShow = false)
+ mView?.showOrHideStartAutopilotView(isShow = true)
+ }
+
+ TaxiPassengerOrderStatusEnum.OnTheWayToEnd -> {
+ // 服务中(去往目的地)
+ mView?.showOrHideArrivedEndLayout(isShow = false)
+ mView?.showOrHidePressengerCheckPager(isShow = false)
+ mView?.showOrHideStartAutopilotView(isShow = false)
+ overMapViewShow()
+ }
+
+ TaxiPassengerOrderStatusEnum.ArriveAtEnd -> {
+ // 50 到达终点 乘客可以评价
+ mView?.showOrHideArrivedEndLayout(true)
+ mView?.showOrHidePressengerCheckPager(isShow = false)
+ mView?.showOrHideStartAutopilotView(isShow = false)
+ overMapViewClear()
+ }
+ TaxiPassengerOrderStatusEnum.JourneyCompleted -> {
+ // 60 行程完成
+ mView?.showOrHideStartAutopilotView(isShow = false)
+ mView?.showOrHidePressengerCheckPager(isShow = false)
+ mView?.showOrHideArrivedEndLayout(false)
+ overMapViewClear()
+ }
+ TaxiPassengerOrderStatusEnum.Cancel -> {
+ // 70 取消订单
+ mView?.showOrHideStartAutopilotView(isShow = false)
+ mView?.showOrHidePressengerCheckPager(isShow = false)
+ mView?.showOrHideArrivedEndLayout(isShow = false)
+ overMapViewClear()
+ }
+ else -> {}
+ }
+ }
+ }
+
+ private fun overMapViewShow(){
+ CallerFuncBizManager.bizProvider.getAllV2XEvents()
+ }
+ private fun overMapViewClear(){
+ CallerFuncBizManager.bizProvider.stopQueryV2XEvents()
+ mView?.showOrHideOverMapView()
+ }
+
+ fun checkAndUpdateStatus(phone: String?) {
+ TaxiPassengerModel.checkPhoneAndUpdateStatus(phone) {
+ mView?.showOrHidePressengerCheckPager(isShow = false)
+ }
+ }
+
+ fun setItineraryVisibility() {
+ UiThreadHandler.post {
+ when (TaxiPassengerModel.curOrderStatus) {
+ TaxiPassengerOrderStatusEnum.None,
+ TaxiPassengerOrderStatusEnum.OnTheWayToStart,
+ TaxiPassengerOrderStatusEnum.ArriveAtStart,
+ TaxiPassengerOrderStatusEnum.JourneyCompleted,
+ TaxiPassengerOrderStatusEnum.ArriveAtEnd,
+ TaxiPassengerOrderStatusEnum.Cancel -> mView?.showOrHideServingOrderFragment(false)
+ TaxiPassengerOrderStatusEnum.UserArriveAtStart,
+ TaxiPassengerOrderStatusEnum.OnTheWayToEnd -> mView?.showOrHideServingOrderFragment(true)
+ }
+ }
+ }
+
+ override fun onMessageGo2OverMapview() {
+ mView?.showOverMapView()
+ }
+
+ companion object {
+ private val TAG = BaseTaxiPassengerPresenter::class.java.simpleName
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/provider/StatusViewManager.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/provider/StatusViewManager.java
new file mode 100644
index 0000000000..97c9108e3a
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/provider/StatusViewManager.java
@@ -0,0 +1,33 @@
+package com.mogo.och.taxi.passenger.provider;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.mogo.eagle.core.data.constants.MogoServicePaths;
+import com.mogo.eagle.core.function.api.hmi.view.IStatusViewLayout;
+import com.mogo.och.taxi.passenger.ui.statusview.StatusBarView;
+
+/**
+ * @author congtaowang
+ * @since 2020-01-06
+ *
+ * 根据优先级控制显示 window view.
+ */
+@Route( path = MogoServicePaths.PATH_STATUS_VIEW_MANAGER )
+public class StatusViewManager implements IStatusViewLayout {
+
+
+ @NonNull
+ @Override
+ public View getStatusView(Context context) {
+ return new StatusBarView(context);
+ }
+
+ @Override
+ public void init(Context context) {
+
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPSettingView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPSettingView.kt
new file mode 100644
index 0000000000..9f7b164b0f
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPSettingView.kt
@@ -0,0 +1,180 @@
+package com.mogo.och.taxi.passenger.ui
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.Intent
+import android.graphics.drawable.ClipDrawable
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.LayerDrawable
+import android.media.AudioManager
+import android.provider.Settings
+import android.text.TextUtils
+import android.util.AttributeSet
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.SeekBar
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.content.ContextCompat
+import com.mogo.commons.module.intent.IMogoIntentListener
+import com.mogo.commons.module.intent.IntentManager
+import com.mogo.commons.module.receiver.MogoReceiver
+import com.mogo.commons.module.receiver.MogoReceiver.ACTION_VOLUME_CHANGE
+import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
+import com.mogo.eagle.core.function.call.setting.CallerRequestActivityHandleManager
+import com.mogo.eagle.core.utilcode.util.BrightnessUtils
+import com.mogo.eagle.core.utilcode.util.ThreadUtils
+import com.mogo.och.common.module.wigets.MineGradientDrawable
+import com.mogo.och.taxi.passenger.R
+import kotlinx.android.synthetic.main.taxi_p_setting_view.view.*
+import me.jessyan.autosize.utils.AutoSizeUtils
+
+class TaxiPSettingView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener,
+ IMogoIntentListener {
+
+ companion object {
+ const val TAG = "TaxiPSettingView"
+ }
+
+ init {
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_setting_view, this, true)
+ initView()
+ }
+
+ private var mAudioManager: AudioManager? = null
+ private var mMaxVolume: Int? = 15
+
+ @SuppressLint("NewApi")
+ private fun initView() {
+ sb_light_bar.setProgressDrawableTiled(getDrawable())
+ sb_light_bar.max = 100
+ sb_light_bar.min = 5
+ sb_light_bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
+ tvSoundPer.text = "$progress%"
+ if (fromUser) {
+ if (!Settings.System.canWrite(context)) {
+ CallerRequestActivityHandleManager.requestPermission(
+ TAG,
+ Settings.ACTION_MANAGE_WRITE_SETTINGS
+ )
+ return
+ }
+ if (BrightnessUtils.isAutoBrightnessEnabled()) {
+ BrightnessUtils.setBrightness(((progress.toFloat() / 100) * 255).toInt())
+ } else {
+ BrightnessUtils.setAutoBrightnessEnabled(true)
+ }
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {}
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {}
+ })
+ sb_light_bar.progress = (BrightnessUtils.getBrightness() * 100) / 255
+
+ sb_voice_bar.setProgressDrawableTiled(getDrawable())
+ sb_voice_bar.max = 100
+ sb_voice_bar.min = 5
+ sb_voice_bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
+ tvVoicePer.text = "$progress%"
+ if (fromUser) {
+ mMaxVolume?.let {
+ var currentValue = ((progress.toFloat() / 100) * it).toInt()
+ if (currentValue <= 0) {
+ currentValue = 1
+ }
+ mAudioManager?.setStreamVolume(
+ AudioManager.STREAM_MUSIC,
+ currentValue,
+ AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE
+ )
+ }
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {}
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {}
+ })
+
+ context?.let {
+ mAudioManager = it.getSystemService(Context.AUDIO_SERVICE) as AudioManager
+ mMaxVolume = mAudioManager?.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
+ updateVolume()
+ }
+ }
+
+ private fun updateVolume() {
+ val mCurrentVolume = mAudioManager?.getStreamVolume(AudioManager.STREAM_MUSIC)
+ mMaxVolume?.let { max ->
+ mCurrentVolume?.let { current ->
+ if (current == 1) {
+ sb_voice_bar.progress = 5
+ tvVoicePer.text = "5%"
+ } else {
+ val fl = current.toFloat() / max * 100
+ sb_voice_bar.progress = fl.toInt()
+ tvVoicePer.text = "${fl.toInt()}%"
+ }
+ }
+ }
+ }
+
+ private fun getDrawable(): Drawable {
+ val dp2px = AutoSizeUtils.dp2px(context, 26f)//进度条高度
+ val color2CBFFC = ContextCompat.getColor(context, R.color.taxi_p_2CBFFC)
+ val color1060FF = ContextCompat.getColor(context, R.color.taxi_p_1060ff)
+ val color96A5C2 = ContextCompat.getColor(context, R.color.taxi_p_96a5c2)
+ val temp03 = MineGradientDrawable(color2CBFFC, color1060FF, dp2px)
+ val clipDrawable3 = ClipDrawable(temp03, Gravity.START, ClipDrawable.HORIZONTAL)
+ val temp01 = MineGradientDrawable(color96A5C2, color96A5C2, dp2px)
+ val arr = arrayOf(temp01, clipDrawable3)
+ val ld = LayerDrawable(arr)
+ ld.setDrawableByLayerId(android.R.id.background, temp01)
+ ld.setDrawableByLayerId(android.R.id.progress, clipDrawable3)
+ return ld
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ IntentManager.getInstance().registerIntentListener(ACTION_VOLUME_CHANGE, this)
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ IntentManager.getInstance().unregisterIntentListener(ACTION_VOLUME_CHANGE, this)
+ }
+
+ override fun onWindowVisibilityChanged(visibility: Int) {
+ super.onWindowVisibilityChanged(visibility)
+ if (visibility == View.VISIBLE) {
+ sb_light_bar.progress = (BrightnessUtils.getBrightness() * 100) / 255
+ }
+ }
+
+ override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
+ super.onWindowFocusChanged(hasWindowFocus)
+ if (hasWindowFocus) {
+ sb_light_bar.progress = (BrightnessUtils.getBrightness() * 100) / 255
+ }
+ }
+
+ override fun onIntentReceived(intentStr: String?, intent: Intent?) {
+ if (TextUtils.equals(ACTION_VOLUME_CHANGE, intentStr)) {
+ if (intent!!.getIntExtra(
+ MogoReceiver.EXTRA_VOLUME_STREAM_TYPE, -1
+ ) == AudioManager.STREAM_MUSIC
+ ) {
+ ThreadUtils.runOnUiThread {
+ updateVolume()
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerBaseFragment.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerBaseFragment.kt
new file mode 100644
index 0000000000..e9e82fcb11
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerBaseFragment.kt
@@ -0,0 +1,344 @@
+package com.mogo.och.taxi.passenger.ui
+
+import android.os.Bundle
+import android.view.View
+import com.mogo.commons.mvp.MvpFragment
+import com.mogo.commons.voice.AIAssist
+import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
+import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
+import com.mogo.eagle.core.utilcode.kotlin.onClick
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_TAXI_P
+import com.mogo.eagle.core.utilcode.util.DeviceUtils
+import com.mogo.eagle.core.utilcode.util.OverlayViewUtils
+import com.mogo.map.listener.IMogoMapListener
+import com.mogo.map.uicontroller.VisualAngleMode
+import com.mogo.och.common.module.utils.RxUtils
+import com.mogo.och.common.module.voice.VoiceNotice
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.callback.ITaxiPassengerCommonValueCallback
+import com.mogo.och.taxi.passenger.presenter.BaseTaxiPassengerPresenter
+import com.mogo.och.taxi.passenger.ui.arrived.ArrivedView
+import com.mogo.och.taxi.passenger.ui.bottom.BottomBar
+import com.mogo.och.taxi.passenger.ui.check.TaxiPassengerCheckView
+import com.mogo.och.taxi.passenger.ui.startautopilot.StartAutopilotView
+import com.mogo.och.taxi.passenger.widget.animutils.AnimationsContainer
+import kotlinx.android.synthetic.main.taxi_p_base_fragment.*
+import java.lang.ref.WeakReference
+
+/**
+ * 网约车基础Fragment,主要负责布局通用界面,处理站点面板和通话面板互斥情况
+ *
+ *
+ * 部分业务放在了此处处理
+ *
+ * @author tongchenfei
+ */
+class TaxiPassengerBaseFragment() :
+ MvpFragment(), IMogoMapListener,
+ TaxiPassengerTaxiView {
+
+ /**
+ * 到达目的地
+ */
+ private var mArrivedEndView: WeakReference? = null
+
+ /**
+ * 手机号后四位验证
+ */
+ private var mArrivedCheckView: WeakReference? = null
+
+ /**
+ * 启动自驾页面
+ */
+ private var mStartAutopilotView: WeakReference? = null
+
+ private var createProgressDialogAnim: AnimationsContainer?=null
+
+ override fun getLayoutId(): Int {
+ return R.layout.taxi_p_base_fragment
+ }
+
+ override fun getTagName(): String {
+ return "BaseOchTaxiPassengerFragment"
+ }
+
+ override fun initViews() {
+ initListener()
+ }
+
+ override fun initViews(savedInstanceState: Bundle?) {
+ super.initViews(savedInstanceState)
+ mapBizView!!.onCreate(savedInstanceState)
+ overMapView.onCreateView(savedInstanceState)
+ overMapView.hideResetView()
+
+ createProgressDialogAnim = AnimationsContainer(R.array.xiaozhi_normal, 20,aciv_xiaozhi_normal)
+ createProgressDialogAnim?.setOnAnimStopListener(object :AnimationsContainer.OnAnimationStoppedListener{
+ override fun AnimationStopped() {
+ CallerLogger.d(M_TAXI_P + TAG, "动画暂停")
+ }
+ })
+ }
+
+ private fun initListener() {
+ ck_setting.isChecked = false
+ ck_setting.setOnCheckedChangeListener { _, isChecked ->
+ clSettingView.visibility = if(isChecked) View.VISIBLE else View.GONE
+ }
+ bottom.setOverMapApplyClick(object : BottomBar.ApplyClickLintener{
+ override fun onApplyClick(selectItem: BottomBar.SelectView) {
+ when (selectItem) {
+ BottomBar.SelectView.PRECISIONMAP -> {
+ overMapView.visibility = View.GONE
+ mapBizView.visibility = View.VISIBLE
+ presenter?.setItineraryVisibility()
+ ck_setting.visibility = View.VISIBLE
+ if (DeviceUtils.isLenovoModel() || DeviceUtils.isEB5Model()) {
+ romaPView.visibility = View.VISIBLE
+ } else {
+ romaPView.visibility = View.GONE
+ }
+ rv_location_center.visibility = View.VISIBLE
+ pcnActionView.visibility = View.VISIBLE
+ CallerHmiManager.showTrafficLightView()
+ infoVideoView.visibility = View.GONE
+ CallerHmiManager.showTurnLightView()
+ }
+ BottomBar.SelectView.OVERMAPVIEW -> {
+ overMapView.visibility = View.VISIBLE
+ mapBizView.visibility = View.GONE
+ presenter?.setItineraryVisibility()
+ ck_setting.visibility = View.VISIBLE
+ romaPView.visibility = View.GONE
+ rv_location_center.visibility = View.VISIBLE
+ pcnActionView.visibility = View.VISIBLE
+ CallerHmiManager.showTrafficLightView()
+ infoVideoView.visibility = View.GONE
+ CallerHmiManager.showTurnLightView()
+ }
+ BottomBar.SelectView.VIDEO -> {
+ overMapView.visibility = View.GONE
+ mapBizView.visibility = View.GONE
+ presenter?.setItineraryVisibility()
+ ck_setting.visibility = View.GONE
+ ck_setting.isChecked = false
+ romaPView.visibility = View.GONE
+ rv_location_center.visibility = View.GONE
+ pcnActionView.visibility = View.GONE
+ CallerHmiManager.hideTrafficLightView()
+ infoVideoView.visibility = View.VISIBLE
+ CallerHmiManager.hideTurnLightView()
+ }
+
+ else -> {}
+ }
+
+ }
+ })
+
+ rv_location_center.onClick {
+ when (bottom.getCurrentPage()) {
+ BottomBar.SelectView.PRECISIONMAP -> {
+ val controller = CallerMapUIServiceManager.getMapUIController()
+ if (controller != null) {
+ //切换到地图中间
+ controller.changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null)
+ // 切换缩放到中视角
+ controller.changeZoom2(0.8f)
+ }
+ }
+ BottomBar.SelectView.OVERMAPVIEW -> {
+ overMapView.displayCustomOverView()
+ }
+
+ else -> {}
+ }
+
+ }
+ view?.viewTreeObserver?.addOnWindowFocusChangeListener {
+ if(it){
+ CallerLogger.d(M_TAXI_P + TAG, "windows获取焦点")
+ createProgressDialogAnim?.start()
+ }else{
+ CallerLogger.d(M_TAXI_P + TAG, "window失去焦点")
+ createProgressDialogAnim?.stop()
+ }
+ }
+ }
+
+ private fun initCheckView() {
+ mArrivedCheckView = WeakReference(TaxiPassengerCheckView(context))
+ mArrivedCheckView!!.get()!!.iTaxiPassengerCommonValueCallback =
+ ITaxiPassengerCommonValueCallback { phoneTail: String? ->
+ getPresenter()!!.checkAndUpdateStatus(phoneTail)
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ mapBizView!!.onResume()
+ overMapView.onResume()
+ CallerLogger.d(M_TAXI_P + TAG, "onResume")
+
+ createProgressDialogAnim?.start()
+ }
+
+ override fun createPresenter(): BaseTaxiPassengerPresenter {
+ return BaseTaxiPassengerPresenter(this)
+ }
+
+ override fun onLowMemory() {
+ super.onLowMemory()
+ mapBizView!!.onLowMemory()
+ }
+
+ override fun onSaveInstanceState(outState: Bundle) {
+ super.onSaveInstanceState(outState)
+ mapBizView!!.onSaveInstanceState(outState)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ mapBizView!!.onPause()
+ overMapView?.onPause()
+ CallerLogger.d(M_TAXI_P + TAG, "onPause")
+ createProgressDialogAnim?.stop()
+ }
+
+ override fun onDestroyView() {
+ mapBizView!!.onDestroy()
+ overMapView?.onDestroy()
+ super.onDestroyView()
+ }
+
+ /**
+ * 显示或隐藏订单信息
+ *
+ * @param isShow
+ */
+ fun showOrHideServingOrderFragment(isShow: Boolean) {
+ when (bottom.getCurrentPage()) {
+ BottomBar.SelectView.OVERMAPVIEW,BottomBar.SelectView.PRECISIONMAP -> {
+ if (isShow) {
+ if(itinerary.visibility!=View.VISIBLE) {
+ itinerary.visibility = View.VISIBLE
+ }
+ } else {
+ if(itinerary.visibility!=View.GONE) {
+ itinerary.visibility = View.GONE
+ }
+ }
+ }
+ BottomBar.SelectView.VIDEO,BottomBar.SelectView.NONE -> {
+ if(itinerary.visibility!=View.GONE) {
+ itinerary.visibility = View.GONE
+ }
+ }
+ }
+ }
+
+ /**
+ * 显示或者隐藏乘客可点击自动驾驶页面
+ * 乘客验证成功,页面显示,按钮置于不可点击
+ * 司机端确认可点击开启自动驾驶, 按钮置为可点击
+ * 订单前往目的地,页面消失
+ *
+ * @param isShow
+ */
+ fun showOrHideStartAutopilotView(isShow: Boolean) {
+ if (isShow) {
+ exitFullVideoScreen(false)
+ if (mStartAutopilotView == null || mStartAutopilotView!!.get() == null) {
+ mStartAutopilotView = WeakReference(StartAutopilotView(requireContext()))
+ }
+ mStartAutopilotView?.get()?.let {
+ OverlayViewUtils.showOverlayView(activity, it)
+ it.handleStartAutopilotBtnStatus(false)
+ }
+ } else {
+ mStartAutopilotView?.get()?.closeAllAnimsAndView()
+ mStartAutopilotView = null
+ }
+ }
+
+ /**
+ * 显示或者隐藏到达乘客站点的洁面
+ * ① 取消订单 可有可无
+ * ② 到达上车点 隐藏到达终点的页面(上一个订单没有评价)
+ * ③ 到达目的地 显示到达终点的页面
+ * ④ debug 使用
+ *
+ * @param isShow true 展示 false 隐藏
+ */
+ fun showOrHideArrivedEndLayout(isShow: Boolean) {
+ if (isShow) {
+ exitFullVideoScreen(true)
+ if (mArrivedEndView == null || mArrivedEndView!!.get() == null) {
+ mArrivedEndView = WeakReference(ArrivedView(context))
+ }
+ mArrivedEndView?.get()?.let {
+ OverlayViewUtils.showOverlayView(activity, it, R.style.och_window_anim_alpha)
+ RxUtils.createSubscribe(500) {
+ it.setDataAndStartAnimation()
+ VoiceNotice.showNotice("已到达目的地,带好随身物品,右侧下车更安全!期待下次再见", AIAssist.LEVEL2)
+ }
+ }
+ } else {
+ mArrivedEndView?.get()?.let {
+ OverlayViewUtils.dismissOverlayView(it)
+ }
+ }
+ }
+
+ private fun exitFullVideoScreen(resetVideoPlayer: Boolean) {
+ infoVideoView.exitFullScreenMode(resetVideoPlayer)
+ }
+
+ fun showOrHideOverMapView(){
+ overMapView?.clearV2XMarkers()
+ overMapView?.clearCustomPolyline()
+ }
+
+ /**
+ * ① 取消订单 到达上车点后乘客取消订单 隐藏乘客验证页面
+ * ② 司机到达上车点 到达上车点 展示乘客验证页面
+ * ③ 乘客到达上车点 手机号验证成功后 隐藏乘客验证页面
+ * ④ debug 使用
+ */
+ fun showOrHidePressengerCheckPager(
+ isShow: Boolean,
+ startSiteAddr: String? = "",
+ endSiteAddr: String? = "",
+ passengerNum: String? = "",
+ phone: String? = ""
+ ) {
+ try {
+ if (isShow) {
+ exitFullVideoScreen(false)
+ if (mArrivedCheckView == null || mArrivedCheckView!!.get() == null) {
+ initCheckView()
+ }
+ mArrivedCheckView!!.get()!!
+ .setData(startSiteAddr, endSiteAddr, passengerNum, phone)
+ OverlayViewUtils.showOverlayView(activity, mArrivedCheckView!!.get())
+ } else {
+ if (mArrivedCheckView == null || mArrivedCheckView!!.get() == null) {
+ return
+ }
+ OverlayViewUtils.dismissOverlayView(mArrivedCheckView!!.get())
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ fun showOverMapView() {
+ bottom.setCheckIndex(BottomBar.SelectView.OVERMAPVIEW)
+ }
+
+ companion object {
+ @JvmField
+ val TAG = "TaxiPassengerBaseFragment"
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerTaxiView.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerTaxiView.java
new file mode 100644
index 0000000000..502d981399
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/TaxiPassengerTaxiView.java
@@ -0,0 +1,13 @@
+package com.mogo.och.taxi.passenger.ui;
+
+import com.mogo.commons.mvp.IView;
+
+
+/**
+ * @author congtaowang
+ * @since 2021/1/18
+ *
+ * 描述
+ */
+public interface TaxiPassengerTaxiView extends IView {
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/ArrivedView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/ArrivedView.kt
new file mode 100644
index 0000000000..127d87a9fc
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/ArrivedView.kt
@@ -0,0 +1,130 @@
+package com.mogo.och.taxi.passenger.ui.arrived
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.lifecycle.ViewModelProvider
+import com.mogo.commons.AbsMogoApplication
+import com.mogo.eagle.core.utilcode.kotlin.onClick
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
+import com.mogo.eagle.core.utilcode.util.OverlayViewUtils
+import com.mogo.och.common.module.utils.RxUtils
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.widget.WindowRelativeLayout
+import com.mogo.och.taxi.passenger.widget.animutils.AnimationsContainer
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
+import io.reactivex.disposables.Disposable
+import kotlinx.android.synthetic.main.taxi_p_arrived_end_panel.view.aciv_close
+import kotlinx.android.synthetic.main.taxi_p_arrived_end_panel.view.actv_endstation
+import kotlinx.android.synthetic.main.taxi_p_arrived_end_panel.view.iv_xiaozhi_belt
+import kotlinx.android.synthetic.main.taxi_p_arrived_end_panel.view.svp_frame
+import kotlinx.android.synthetic.main.taxi_p_arrived_end_panel.view.v_video_right_rear_view
+
+
+/**
+ *
+ * 评价View
+ * Created on 2022/5/16
+ */
+class ArrivedView : WindowRelativeLayout, ArrivedViewModel.ArrivedViewCallback {
+
+ constructor(context: Context?) : super(context)
+
+ constructor(context: Context?, attributeSet: AttributeSet) : super(context, attributeSet)
+
+ constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
+
+ constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
+
+ private var subscribe: Disposable?=null
+
+ private val gsyVideoOptionBuilder = GSYVideoOptionBuilder()
+
+ private var taxiPxiaozhiLove: AnimationsContainer?=null
+
+ private fun initView() {
+ d(SceneConstant.M_TAXI_P + TAG, "initView")
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_arrived_end_panel, this, true)
+ svp_frame.setBackgroundResource(R.drawable.tail_ani_0000)
+ svp_frame.setIsTouchWiget(false)
+ svp_frame.setIsTouchWigetFull(false)
+ svp_frame.enableshowProgressDialog = false
+ svp_frame.enableDoubleClick = false
+ GSYVideoManager.instance().enableRawPlay(AbsMogoApplication.getApp())
+ val url = "android.resource://" + context.packageName + "/" + R.raw.end_video
+ gsyVideoOptionBuilder.setUrl(url)
+ .setCacheWithPlay(false)
+ .setPlayTag("TaxiPassengerArrivedView")
+ .build(svp_frame)
+
+ aciv_close.onClick {
+ OverlayViewUtils.dismissOverlayView(this)
+ }
+
+ taxiPxiaozhiLove = AnimationsContainer(R.array.xiaozhi_love, 20,iv_xiaozhi_belt)
+ taxiPxiaozhiLove?.setOnAnimStopListener(object :AnimationsContainer.OnAnimationStoppedListener{
+ override fun AnimationStopped() {
+ d(SceneConstant.M_TAXI_P + TAG, "动画暂停")
+ }
+ })
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ val viewModel = ViewModelProvider(this).get(ArrivedViewModel::class.java)
+ viewModel.setViewCallback(this)
+ taxiPxiaozhiLove?.start()
+ v_video_right_rear_view.resetView()
+ }
+
+ override fun onDetachedFromWindow() {
+ svp_frame.setBackgroundResource(R.drawable.tail_ani_0000)
+ svp_frame.setVideoAllCallBack(null)
+ svp_frame.onVideoReset()
+ svp_frame.release()
+ taxiPxiaozhiLove?.stop()
+ v_video_right_rear_view.resetView()
+
+ super.onDetachedFromWindow()
+ subscribe?.let {
+ if (!it.isDisposed) {
+ it.dispose()
+ }
+ }
+ }
+
+ /**
+ * 设置目的地重置星星状态
+ */
+ fun setDataAndStartAnimation() {
+ svp_frame.setVideoAllCallBack(object : GSYSampleCallBack() {
+ override fun onAutoComplete(url: String?, vararg objects: Any?) {
+ svp_frame.setBackgroundResource(R.drawable.tail_ani_0090)
+ }
+ })
+ svp_frame.startPlayLogic()
+ RxUtils.createSubscribe(60_000) {
+ OverlayViewUtils.dismissOverlayView(this@ArrivedView)
+ }
+ }
+
+ companion object {
+ const val TAG = "TaxiPassengerArrivedView"
+ }
+
+ init {
+ try {
+ initView()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun setEndStation(stationName: String) {
+ actv_endstation.text = stationName
+ }
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/ArrivedViewModel.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/ArrivedViewModel.kt
new file mode 100644
index 0000000000..0181c883ac
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/ArrivedViewModel.kt
@@ -0,0 +1,32 @@
+package com.mogo.och.taxi.passenger.ui.arrived
+
+import androidx.lifecycle.ViewModel
+import com.mogo.och.taxi.passenger.model.TaxiPassengerModel
+
+class ArrivedViewModel: ViewModel() {
+
+ private val TAG = ArrivedViewModel::class.java.simpleName
+
+ private var viewCallback:ArrivedViewCallback?=null
+
+ init {
+
+ }
+
+ fun setViewCallback(viewCallback: ArrivedViewCallback){
+ this.viewCallback = viewCallback
+ TaxiPassengerModel.currentOCHOrder?.endSiteAddr?.let {
+ this.viewCallback?.setEndStation(it)
+ }
+ }
+
+ override fun onCleared() {
+ super.onCleared()
+ this.viewCallback = null
+ }
+
+
+ interface ArrivedViewCallback{
+ fun setEndStation(stationName:String)
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/RightRearCamView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/RightRearCamView.kt
new file mode 100644
index 0000000000..6449fc6f0c
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/arrived/RightRearCamView.kt
@@ -0,0 +1,162 @@
+package com.mogo.och.taxi.passenger.ui.arrived
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.drawable.BitmapDrawable
+import android.util.AttributeSet
+import android.util.Log
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.mogo.eagle.core.function.api.autopilot.IMoGoBackCameraVideoListener
+import com.mogo.eagle.core.function.api.autopilot.IMoGoRoboBusJinlvM1StitchedVideoListener
+import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.setIsSubscribeBackCameraVideoVideo
+import com.mogo.eagle.core.function.call.autopilot.CallerBackCameraVideoListenerManager
+import com.mogo.eagle.core.function.call.autopilot.CallerRoboBusJinlvM1StitchedVideoListenerManager
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
+import com.mogo.eagle.core.utilcode.util.UiThreadHandler
+import com.mogo.eagle.core.widget.media.video.TextureVideoViewOutlineProvider
+import com.mogo.och.taxi.passenger.R
+import kotlinx.android.synthetic.main.taxi_p_right_rear_cam.view.actv_cam_position_group
+import kotlinx.android.synthetic.main.taxi_p_right_rear_cam.view.v_video_right_rear
+
+/**
+ *
+ * 评价View
+ * Created on 2022/5/16
+ */
+class RightRearCamView : ConstraintLayout , IMoGoBackCameraVideoListener,
+ IMoGoRoboBusJinlvM1StitchedVideoListener,Runnable {
+
+ constructor(context: Context) : super(context)
+
+ constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
+
+ constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
+
+ constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
+
+ private var mBitmap: Bitmap? = null
+
+ private var mBitmapOptions: BitmapFactory.Options? = null //Bitmap管理类,可有效减少Bitmap的OOM问题
+
+
+ private fun initView() {
+ d(SceneConstant.M_TAXI_P + TAG, "initView")
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_right_rear_cam, this, true)
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ setIsSubscribeBackCameraVideoVideo(1, true)
+ CallerBackCameraVideoListenerManager.addListener(TAG, this)
+ CallerRoboBusJinlvM1StitchedVideoListenerManager.addListener(TAG, this)
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ setIsSubscribeBackCameraVideoVideo(1, false)
+ CallerBackCameraVideoListenerManager.removeListener(this)
+ CallerRoboBusJinlvM1StitchedVideoListenerManager.removeListener(this)
+ }
+
+ companion object {
+ const val TAG = "RightRearCamView"
+ }
+
+ init {
+ try {
+ initView()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ fun resetView(){
+ actv_cam_position_group.visibility = GONE
+ v_video_right_rear.setImageResource(R.drawable.taxi_p_right_rear_cam)
+ }
+
+ override fun onBackCameraVideo(data: ByteArray) {
+ decodeData(data)
+ }
+
+ override fun onRoboBusJinlvM1StitchedVideo(data: ByteArray) {
+ decodeData(data)
+ }
+
+ var preTime :Long=System.currentTimeMillis()
+
+ @Synchronized
+ private fun decodeData(data: ByteArray){
+ val currentTimeMillis = System.currentTimeMillis()
+ val dexTime = currentTimeMillis - preTime
+ preTime = currentTimeMillis
+ if(dexTime<20){
+ return
+ }
+ d(SceneConstant.M_TAXI_P + TAG, "图片频率:$dexTime")
+ if (mBitmapOptions == null) {
+ val bmp = (v_video_right_rear.drawable as BitmapDrawable).bitmap
+ val width = bmp.width
+ val height = bmp.height
+ val config = bmp.config
+ mBitmap = Bitmap.createBitmap(width, height, config)
+ mBitmapOptions = BitmapFactory.Options()
+ //设置Bitmap内存复用
+ mBitmapOptions!!.inBitmap = mBitmap //Bitmap复用内存块,类似对象池,避免不必要的内存分配和回收
+ mBitmapOptions!!.inMutable = true //解码时返回可变Bitmap
+
+ val options = BitmapFactory.Options()
+ options.inJustDecodeBounds = true
+ BitmapFactory.decodeByteArray(data, 0, data.size, options)
+ mBitmapOptions!!.inSampleSize = calculateInSampleSize(options, width, height)
+ }
+ mBitmapOptions?.let {
+ try {
+ val preTime = System.currentTimeMillis()
+ BitmapFactory.decodeByteArray(data, 0, data.size, mBitmapOptions)
+ d(SceneConstant.M_TAXI_P + TAG, "decode时间:${System.currentTimeMillis()-preTime}")
+ UiThreadHandler.post(this)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ private fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
+ val width = options.outWidth
+ val height = options.outHeight
+ Log.i(TAG, "calculateInSampleSize: out width and height is $width height $height")
+ var inSampleWidth = 1
+ if (height > reqHeight || width > reqWidth) {
+ val halfHeight = height / 2
+ val halfWidth = width / 2
+ // 采样率设置为2的指数
+ while (halfHeight / inSampleWidth >= reqHeight && halfWidth / inSampleWidth >= reqWidth) {
+ inSampleWidth *= 2
+ }
+ }
+
+ while (width/inSampleWidth>reqWidth||height/inSampleWidth>reqHeight){
+ inSampleWidth++
+ }
+
+ return inSampleWidth
+ }
+
+
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
+ super.onSizeChanged(w, h, oldw, oldh)
+ outlineProvider = TextureVideoViewOutlineProvider(36f)
+ clipToOutline = true
+ }
+
+ override fun run() {
+ if(actv_cam_position_group?.visibility == GONE) {
+ actv_cam_position_group?.visibility = VISIBLE
+ }
+ v_video_right_rear?.setImageBitmap(mBitmap)
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/bottom/BottomBar.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/bottom/BottomBar.kt
new file mode 100644
index 0000000000..49681bafa2
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/bottom/BottomBar.kt
@@ -0,0 +1,81 @@
+package com.mogo.och.taxi.passenger.ui.bottom
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.mogo.och.taxi.passenger.R
+import kotlinx.android.synthetic.main.taxi_p_bottom_bar.view.actv_overmap
+import kotlinx.android.synthetic.main.taxi_p_bottom_bar.view.actv_precisionmap
+import kotlinx.android.synthetic.main.taxi_p_bottom_bar.view.actv_video
+
+class BottomBar @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+
+ private var checkIndex = SelectView.NONE
+ private var overMapViewApply:ApplyClickLintener?=null
+
+ init {
+ isClickable = true
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_bottom_bar, this, true)
+ setBackgroundResource(R.drawable.taxi_p_bottom_bar_bg)
+ actv_precisionmap.setOnClickListener {
+ setCheckIndex(SelectView.PRECISIONMAP)
+ }
+ actv_overmap.setOnClickListener {
+ setCheckIndex(SelectView.OVERMAPVIEW)
+ }
+ actv_video.setOnClickListener {
+ setCheckIndex(SelectView.VIDEO)
+ }
+ }
+
+ fun getCurrentPage():SelectView{
+ return checkIndex
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ setCheckIndex(SelectView.PRECISIONMAP)
+ }
+
+ fun setOverMapApplyClick(overMapViewApply:ApplyClickLintener){
+ this.overMapViewApply = overMapViewApply
+ }
+
+ fun setCheckIndex(index: SelectView){
+ if(checkIndex==index){
+ return
+ }else{
+ checkIndex = index
+ }
+ overMapViewApply?.onApplyClick(checkIndex)
+ if(checkIndex == SelectView.OVERMAPVIEW){
+ actv_overmap.setCheckItem(true)
+ }else{
+ actv_overmap.setCheckItem(false)
+ }
+ if(checkIndex == SelectView.VIDEO){
+ actv_video.setCheckItem(true)
+ }else{
+ actv_video.setCheckItem(false)
+ }
+ if(checkIndex == SelectView.PRECISIONMAP){
+ actv_precisionmap.setCheckItem(true)
+ }else{
+ actv_precisionmap.setCheckItem(false)
+ }
+ }
+
+ enum class SelectView{
+ NONE,PRECISIONMAP,OVERMAPVIEW,VIDEO
+ }
+
+ interface ApplyClickLintener{
+ fun onApplyClick(selectItem:SelectView)
+ }
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/bottom/BottomCheckView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/bottom/BottomCheckView.kt
new file mode 100644
index 0000000000..78dd252f72
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/bottom/BottomCheckView.kt
@@ -0,0 +1,92 @@
+package com.mogo.och.bus.passenger.ui.view.bottom
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.content.ContextCompat
+import com.mogo.och.taxi.passenger.R
+import kotlinx.android.synthetic.main.m1_bottom_check.view.aciv_center_image
+import kotlinx.android.synthetic.main.m1_bottom_check.view.actv_title
+
+open class BottomCheckView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+
+ companion object {
+ private const val TAG = "StopSiteView"
+ }
+
+ private var backageViewId: Int = -1
+ private var bottomTitle: String = ""
+ private var selectedDrawable: Int = -1
+ private var normalDrawable: Int = -1
+ private var bottomTitleNormalColor:Int = -1
+ private var bottomTitleCheckedColor:Int = -1
+ private var backageView: View? = null
+
+ private var isCheck = false
+
+ init {
+ LayoutInflater.from(context).inflate(R.layout.m1_bottom_check, this, true)
+ try {
+ val typedArray = context.obtainStyledAttributes(attrs, R.styleable.BottomSelectView)
+ backageViewId = typedArray.getResourceId(R.styleable.BottomSelectView_backageViewId, -1)
+ bottomTitle = typedArray.getString(R.styleable.BottomSelectView_bottomTitle) ?: ""
+ selectedDrawable = typedArray.getResourceId(R.styleable.BottomSelectView_selectedDrawable, -1)
+ normalDrawable = typedArray.getResourceId(R.styleable.BottomSelectView_normalDrawable, -1)
+ bottomTitleNormalColor = typedArray.getColor(R.styleable.BottomSelectView_bottomTitleNormalColor,
+ ContextCompat.getColor(context,R.color.white))
+ bottomTitleCheckedColor = typedArray.getColor(R.styleable.BottomSelectView_bottomTitleCheckedColor,
+ ContextCompat.getColor(context,R.color.white))
+ typedArray.recycle()
+ initView(context)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+
+ }
+
+ private fun initView(context: Context) {
+ if (selectedDrawable > 0) {
+ aciv_center_image.setImageResource(normalDrawable)
+ }
+ actv_title.text = bottomTitle
+ }
+
+ fun setCheckItem(isCheck: Boolean) {
+ if (isCheck != this.isCheck) {
+ this.isCheck = isCheck
+ notifiBackageView()
+ }
+ }
+
+ private fun notifiBackageView() {
+ if (isCheck) {
+ backageView?.visibility = View.VISIBLE
+ aciv_center_image.setImageResource(selectedDrawable)
+ actv_title.setTextColor(bottomTitleCheckedColor)
+ } else {
+ backageView?.visibility = View.GONE
+ aciv_center_image.setImageResource(normalDrawable)
+ actv_title.setTextColor(bottomTitleNormalColor)
+ }
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ parent?.let {
+ if (parent is ConstraintLayout) {
+ if (backageViewId > 0) {
+ backageView = (parent as ConstraintLayout).findViewById(backageViewId)
+ }
+ }
+ }
+ if (isCheck) {
+ backageView?.visibility = View.VISIBLE
+ }
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/check/TaxiPassengerCheckView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/check/TaxiPassengerCheckView.kt
new file mode 100644
index 0000000000..07330f40d6
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/check/TaxiPassengerCheckView.kt
@@ -0,0 +1,250 @@
+package com.mogo.och.taxi.passenger.ui.check
+
+import android.content.Context
+import android.graphics.Typeface
+import android.text.Spannable
+import android.text.SpannableStringBuilder
+import android.text.style.TextAppearanceSpan
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.RelativeLayout
+import android.widget.TextView
+import androidx.core.content.ContextCompat
+import com.mogo.commons.voice.AIAssist
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
+import com.mogo.eagle.core.utilcode.util.ToastUtils
+import com.mogo.och.common.module.voice.VoiceNotice
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.callback.ITaxiPassengerCommonValueCallback
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_passenger_count
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_passenger_end
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_passenger_start
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_back
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_eight
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_first
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_five
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_four
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_fourth
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_nine
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_one
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_second
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_seven
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_six
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_submit
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_third
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_three
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_two
+import kotlinx.android.synthetic.main.taxi_p_passenger_check_panel.view.tv_taxi_passenger_number_zero
+
+/**
+ * V2X预警事件view:通过FloatWindow呈现,无需加入到自定义layout中
+ *
+ * Created on 2022/3/16
+ */
+class TaxiPassengerCheckView :RelativeLayout, View.OnClickListener {
+
+ constructor(context: Context?) : super(context)
+
+ constructor(context: Context?, attributeSet: AttributeSet) : super(context, attributeSet)
+
+ constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
+
+ constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
+
+ var iTaxiPassengerCommonValueCallback: ITaxiPassengerCommonValueCallback?=null
+
+
+ private var index = 0
+ private var phone = ""
+ private val numSelect = arrayOfNulls(4)
+ private val numSelectTextView = arrayOfNulls(4)
+
+ private fun initView(context: Context) {
+ d(SceneConstant.M_TAXI_P + TAG, "initView")
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_passenger_check_panel, this, true)
+ keyBoardLogic()
+ numSelectTextView[0] = tv_taxi_passenger_number_first
+ numSelectTextView[1] = tv_taxi_passenger_number_second
+ numSelectTextView[2] = tv_taxi_passenger_number_third
+ numSelectTextView[3] = tv_taxi_passenger_number_fourth
+ }
+
+ private fun keyBoardLogic() {
+ tv_taxi_passenger_number_one.setOnClickListener(this)
+ tv_taxi_passenger_number_two.setOnClickListener(this)
+ tv_taxi_passenger_number_three.setOnClickListener(this)
+ tv_taxi_passenger_number_four.setOnClickListener(this)
+ tv_taxi_passenger_number_five.setOnClickListener(this)
+ tv_taxi_passenger_number_six.setOnClickListener(this)
+ tv_taxi_passenger_number_seven.setOnClickListener(this)
+ tv_taxi_passenger_number_eight.setOnClickListener(this)
+ tv_taxi_passenger_number_nine.setOnClickListener(this)
+ tv_taxi_passenger_number_zero.setOnClickListener(this)
+ tv_taxi_passenger_number_back.setOnClickListener(this)
+ tv_taxi_passenger_number_submit.setOnClickListener(this)
+
+ tv_taxi_passenger_number_first.setOnClickListener(this)
+ tv_taxi_passenger_number_second.setOnClickListener(this)
+ tv_taxi_passenger_number_third.setOnClickListener(this)
+ tv_taxi_passenger_number_fourth.setOnClickListener(this)
+
+ }
+
+ override fun onClick(v: View?) {
+ when (v?.id) {
+ R.id.tv_taxi_passenger_number_one -> {showNumver(1)}
+ R.id.tv_taxi_passenger_number_two -> {showNumver(2)}
+ R.id.tv_taxi_passenger_number_three-> {showNumver(3)}
+ R.id.tv_taxi_passenger_number_four-> {showNumver(4)}
+ R.id.tv_taxi_passenger_number_five -> {showNumver(5)}
+ R.id.tv_taxi_passenger_number_six -> {showNumver(6)}
+ R.id.tv_taxi_passenger_number_seven -> {showNumver(7)}
+ R.id.tv_taxi_passenger_number_eight -> {showNumver(8)}
+ R.id.tv_taxi_passenger_number_nine -> {showNumver(9)}
+ R.id.tv_taxi_passenger_number_zero -> {showNumver(0)}
+ R.id.tv_taxi_passenger_number_back -> {deleteNumver()}
+ R.id.tv_taxi_passenger_number_first -> {selectIndex(0)}
+ R.id.tv_taxi_passenger_number_second -> {selectIndex(1)}
+ R.id.tv_taxi_passenger_number_third -> {selectIndex(2)}
+ R.id.tv_taxi_passenger_number_fourth -> {selectIndex(3)}
+ R.id.tv_taxi_passenger_number_submit -> {clearNumber()}
+ else -> {}
+ }
+ }
+
+ private fun checkAndCommit() {
+ val numberStr = "${numSelect[0]}${numSelect[1]}${numSelect[2]}${numSelect[3]}"
+ if(!phone.endsWith(numberStr)){
+ ToastUtils.showLong("请输入正确的手机尾号")
+ VoiceNotice.showNotice("验证失败!再检查一下吧~", AIAssist.LEVEL2)
+ return
+ }
+ iTaxiPassengerCommonValueCallback?.onCommonCallback(numberStr)
+ }
+
+ private fun selectIndex(i: Int) {
+ index = i
+ changeStyle()
+ }
+
+ private fun showNumver(number: Int) {
+ if (index in 0..3) {
+ numSelect[index] = number
+ numSelectTextView[index]!!.text = number.toString()
+ if(index!=3){
+ index++
+ }
+ changeStyle()
+ numSelect.forEach {
+ if(it==null){
+ return
+ }
+ }
+
+ checkAndCommit()
+ }
+ }
+
+ private fun clearNumber(){
+ for(i in numSelect.indices){
+ numSelect[i] = null
+ }
+ numSelectTextView.forEach {
+ it?.text = ""
+ }
+ index = 0
+ changeStyle()
+ }
+
+ private fun deleteNumver() {
+ if (index in 0..3) {
+ if(numSelect[index]==null){
+ if(index!=0){
+ index--
+ }
+ changeStyle()
+ //return
+ }
+ numSelect[index] = null
+ numSelectTextView[index]!!.text = ""
+ }
+ }
+
+ private fun changeStyle() {
+ numSelectTextView.forEachIndexed { indexIn, textView ->
+ if(indexIn==index){
+ numSelectTextView[index]!!.setBackgroundResource(R.drawable.bg_taxi_p_checked_input_background)
+
+ numSelectTextView[index]!!.setTextColor(
+ ContextCompat.getColor(
+ context,
+ R.color.taxi_p_check_keyboard_input_field_checked
+ )
+ )
+ numSelectTextView[index]!!.setShadowLayer(
+ 0f, 0f, 0f,
+ ContextCompat.getColor(
+ context,
+ R.color.taxi_p_check_keyboard_input_field_checked_text_shadow
+ )
+ )
+ }else{
+ numSelectTextView[indexIn]!!.setBackgroundResource(R.drawable.bg_taxi_p_check_input_background)
+ numSelectTextView[indexIn]!!.setTextColor(
+ ContextCompat.getColor(
+ context,
+ R.color.taxi_p_check_keyboard_input_field
+ )
+ )
+ numSelectTextView[indexIn]!!.setShadowLayer(
+ 20f,
+ 0f,
+ 2f,
+ ContextCompat.getColor(
+ context,
+ R.color.taxi_p_check_keyboard_input_field_checked_text_shadow
+ )
+ )
+ }
+ }
+
+ }
+
+ fun setData(
+ startSiteAddr: String?,
+ endSiteAddr: String?,
+ passengerNum: String?,
+ phone: String?
+ ) {
+ this.phone = phone?:""
+ val sb = SpannableStringBuilder("乘客数:$passengerNum 位") // 包装字体内容
+ sb.setSpan(
+ TextAppearanceSpan("default",
+ Typeface.NORMAL,100,
+ ContextCompat.getColorStateList(context,R.color.taxi_p_check_passenger_number) ,null ),
+ 4, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
+ tv_passenger_count.text = sb
+ tv_passenger_start.text = "起 点 : $startSiteAddr"
+ tv_passenger_end.text = "终 点 : $endSiteAddr"
+ for(i in numSelect.indices){
+ numSelect[i] = null
+ }
+ numSelectTextView.forEach {
+ it?.text = ""
+ }
+ }
+
+ companion object {
+ const val TAG = "TaxiPassengerCheckView"
+ }
+
+ init {
+ try {
+ initView(context)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/debug/DebugEvent.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/debug/DebugEvent.kt
new file mode 100644
index 0000000000..ce7b533953
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/debug/DebugEvent.kt
@@ -0,0 +1,4 @@
+package com.mogo.och.taxi.passenger.ui.debug
+
+class DebugEvent {
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/debug/DebugView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/debug/DebugView.kt
new file mode 100644
index 0000000000..37e39176a3
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/debug/DebugView.kt
@@ -0,0 +1,80 @@
+package com.mogo.och.taxi.passenger.ui.debug
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.fragment.app.FragmentActivity
+import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
+import com.mogo.eagle.core.utilcode.kotlin.onClick
+import com.mogo.eagle.core.utilcode.util.ActivityUtils
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.ui.TaxiPassengerBaseFragment
+import kotlinx.android.synthetic.main.taxi_p_debug.view.tv_show_arrive
+import kotlinx.android.synthetic.main.taxi_p_debug.view.tv_show_phone_check
+import kotlinx.android.synthetic.main.taxi_p_debug.view.tv_show_start_autopilot
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+
+class DebugView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener {
+
+ companion object {
+ const val TAG = "DebugView"
+ }
+
+ init {
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_debug, this, true)
+ visibility = GONE
+ }
+
+ private var fragment:TaxiPassengerBaseFragment?=null
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+
+ EventBus.getDefault().register(this)
+
+ val activityByContext = ActivityUtils.getActivityByContext(context)
+ if(activityByContext is FragmentActivity){
+ val fragment =
+ activityByContext.supportFragmentManager.findFragmentByTag(TaxiPassengerBaseFragment.TAG)
+ if(fragment is TaxiPassengerBaseFragment){
+ this.fragment = fragment
+ }
+ }
+
+ tv_show_arrive.onClick {
+ fragment?.showOrHideArrivedEndLayout(true)
+ }
+ tv_show_phone_check.onClick {
+ fragment?.showOrHidePressengerCheckPager(isShow = true,"13号路口终(鹰眼专用)","13号路口终(鹰眼专用)","2","18811539480")
+ }
+ tv_show_start_autopilot.onClick {
+ fragment?.showOrHideStartAutopilotView(true)
+ }
+
+ }
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ fun changeOverview(debugEvent: DebugEvent) {
+ if(visibility== VISIBLE){
+ visibility = GONE
+ }else{
+ visibility = VISIBLE
+ }
+ }
+
+
+
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ EventBus.getDefault().unregister(this)
+ }
+
+}
+
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/orderinfo/ItineraryView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/orderinfo/ItineraryView.kt
new file mode 100644
index 0000000000..3eb347961b
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/orderinfo/ItineraryView.kt
@@ -0,0 +1,148 @@
+package com.mogo.och.taxi.passenger.ui.orderinfo
+
+import android.content.Context
+import android.graphics.drawable.GradientDrawable
+import android.graphics.drawable.LayerDrawable
+import android.graphics.drawable.ScaleDrawable
+import android.os.Build
+import android.util.AttributeSet
+import android.view.Gravity
+import android.view.LayoutInflater
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.content.ContextCompat
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.findViewTreeViewModelStoreOwner
+import com.mogo.och.taxi.passenger.R
+import kotlinx.android.synthetic.main.taxi_p_itinerary.view.actv_arrived_time
+import kotlinx.android.synthetic.main.taxi_p_itinerary.view.actv_distance
+import kotlinx.android.synthetic.main.taxi_p_itinerary.view.actv_distance_unit
+import kotlinx.android.synthetic.main.taxi_p_itinerary.view.actv_endstation
+import kotlinx.android.synthetic.main.taxi_p_itinerary.view.actv_speed_value
+import kotlinx.android.synthetic.main.taxi_p_itinerary.view.actv_surplus_time
+import kotlinx.android.synthetic.main.taxi_p_itinerary.view.actv_surplus_time_unit
+import kotlinx.android.synthetic.main.taxi_p_itinerary.view.progress_distance
+import me.jessyan.autosize.utils.AutoSizeUtils
+
+class ItineraryView : ConstraintLayout, OrderInfoViewModel.ItineraryViewCallback {
+
+ private val TAG = "ItineraryView"
+
+ constructor(context: Context) : super(context)
+
+ constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
+
+ constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
+
+ constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
+
+ private fun initView() {
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_itinerary, this, true)
+ setDrawable(true)
+
+ progress_distance.progress = 0
+ progress_distance.max = 100
+
+ }
+
+ private fun setDrawable(normal:Boolean) {
+ val gradientDrawable = GradientDrawable()
+ gradientDrawable.shape = GradientDrawable.RECTANGLE
+ val corner = AutoSizeUtils.dp2px(context, 40f).toFloat()
+ val cornerTop = AutoSizeUtils.dp2px(context, 20f).toFloat()
+ if(normal) {
+ gradientDrawable.cornerRadii =
+ floatArrayOf(0f, 0f, cornerTop, cornerTop, cornerTop, cornerTop, corner, corner)
+ }else {
+ gradientDrawable.cornerRadii =
+ floatArrayOf(0f, 0f, 0f, 0f, corner, corner, corner, corner)
+ }
+ val firstColor = ContextCompat.getColor(context, R.color.taxi_p_OF5FFF)
+ val setondColor = ContextCompat.getColor(context, R.color.taxi_p_44C8FF)
+ val thirdColor = ContextCompat.getColor(context, R.color.taxi_p_8AE4ED)
+ val fourceColor = ContextCompat.getColor(context, R.color.taxi_p_C8F3F4)
+ val bottomColor = ContextCompat.getColor(context, R.color.taxi_p_66476FBE)
+ gradientDrawable.colors = intArrayOf(firstColor, setondColor, thirdColor, fourceColor)
+ gradientDrawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT
+
+ val temp01 = GradientDrawable()
+ temp01.cornerRadii = floatArrayOf(0f, 0f, 0f, 0f, corner, corner, corner, corner)
+ temp01.colors = intArrayOf(bottomColor, bottomColor)
+
+ val scaleDrawable3 = ScaleDrawable(gradientDrawable, Gravity.START, 1f, -1f)
+ val arr = arrayOf(temp01, scaleDrawable3)
+ val ld = LayerDrawable(arr)
+ ld.setDrawableByLayerId(android.R.id.background, temp01)
+ ld.setDrawableByLayerId(android.R.id.progress, scaleDrawable3)
+ progress_distance.setProgressDrawableTiled(ld)
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+
+ val viewModel = findViewTreeViewModelStoreOwner()?.let {
+ ViewModelProvider(it).get(OrderInfoViewModel::class.java)
+ }
+
+ viewModel?.setDistanceCallback(this)
+ }
+
+ override fun setSpeed(speedValue:String){
+ actv_speed_value.text = speedValue
+ }
+ override fun setEndStation(endStation:String){
+ if(endStation.length>9){
+ actv_endstation.text = "${endStation.subSequence(0,9)}…"
+ }else {
+ actv_endstation.text = endStation
+ }
+ }
+
+ var prePercentage = 0f
+ val needChangeStyleNumber = 0.99
+
+ override fun setDistanceInfo(surplusdistance:String,distanceUnit:String,
+ surplusTime:String,surplusTimeUnit:String,
+ arrivedTime:String,alreadyGone:Int,stationDistance:Int
+ ){
+ actv_distance.text = surplusdistance
+ actv_distance_unit.text = distanceUnit
+ actv_surplus_time .text= surplusTime
+ actv_surplus_time_unit.text = surplusTimeUnit
+ actv_arrived_time.text= arrivedTime
+
+ if(stationDistance>0&&alreadyGoneneedChangeStyleNumber) xor (currentPercentage>needChangeStyleNumber)){
+ if(currentPercentage>needChangeStyleNumber){
+ setDrawable(false)
+ }else{
+ setDrawable(true)
+ }
+ progress_distance.progress = alreadyGone
+ }else{
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ progress_distance.setProgress(alreadyGone,true)
+ }else{
+ progress_distance.progress = alreadyGone
+ }
+ }
+ prePercentage = currentPercentage
+ }
+
+ }
+
+ init {
+ try {
+ initView()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/orderinfo/OrderInfoViewModel.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/orderinfo/OrderInfoViewModel.kt
new file mode 100644
index 0000000000..11f3e8a07d
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/orderinfo/OrderInfoViewModel.kt
@@ -0,0 +1,106 @@
+package com.mogo.och.taxi.passenger.ui.orderinfo
+
+import androidx.lifecycle.ViewModel
+import com.mogo.commons.AbsMogoApplication
+import com.mogo.eagle.core.data.map.MogoLocation
+import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
+import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
+import com.mogo.eagle.core.utilcode.util.UiThreadHandler
+import com.mogo.och.common.module.utils.DateTimeUtil
+import com.mogo.och.common.module.utils.NumberFormatUtil
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerOrderQueryRespBean
+import com.mogo.och.taxi.passenger.callback.IOCHTaxiPassengerOrderStatusCallback
+import com.mogo.och.taxi.passenger.constant.TaxiPassengerOrderStatusEnum
+import com.mogo.och.taxi.passenger.model.TaxiPassengerModel
+import kotlin.math.abs
+import kotlin.math.ceil
+
+class OrderInfoViewModel: ViewModel(), IMoGoChassisLocationGCJ02Listener,
+ IOCHTaxiPassengerOrderStatusCallback {
+
+ private val TAG = OrderInfoViewModel::class.java.simpleName
+
+ private var viewCallback:ItineraryViewCallback?=null
+
+ private var disUnit:String
+ private var surplusTimeUnit:String
+
+ init {
+ disUnit = AbsMogoApplication.getApp().getString(R.string.taxi_p_distance_unit_km)
+ surplusTimeUnit = AbsMogoApplication.getApp().getString(R.string.taxi_p_surplustime)
+ // 设置起点和终点marker和实时车辆位置
+ CallerChassisLocationGCJ02ListenerManager.addListener(TAG, 4, this)
+ TaxiPassengerModel.setOrderStatusCallback(TAG,this)
+ }
+
+ fun setDistanceCallback(viewCallback:ItineraryViewCallback){
+ this.viewCallback = viewCallback
+ }
+
+ override fun onCleared() {
+ super.onCleared()
+ this.viewCallback = null
+ TaxiPassengerModel.setOrderStatusCallback(TAG,null)
+ }
+
+ override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
+ mogoLocation?.let {
+ UiThreadHandler.post {
+ val speedKM = (abs(it.gnssSpeed) * 3.6f).toInt()
+ viewCallback?.setSpeed(speedKM.toString())
+ }
+ }
+ }
+
+ interface ItineraryViewCallback{
+ fun setDistanceInfo(surplusdistance:String,distanceUnit:String,
+ surplusTime:String,surplusTimeUnit:String,
+ arrivedTime:String,alreadyGone:Int,distance:Int
+ )
+ fun setEndStation(endStation:String)
+ fun setSpeed(speedValue:String)
+ }
+
+ override fun onCurrentOrderStatusChanged(order: TaxiPassengerOrderQueryRespBean.Result?) {
+ order?.endSiteAddr?.let {
+ UiThreadHandler.post {
+ viewCallback?.setEndStation(it)
+ }
+ }
+ when (TaxiPassengerModel.curOrderStatus) {
+ TaxiPassengerOrderStatusEnum.OnTheWayToEnd -> {
+
+ }
+ else ->{
+ UiThreadHandler.post {
+ viewCallback?.setDistanceInfo(
+ "--", disUnit, "--", surplusTimeUnit, "--", 0, 100
+ )
+ }
+ }
+ }
+ }
+
+ override fun onCurrentOrderDistToEndChanged(meters: Long, timeInSecond: Long,stationDistance:Int) {
+ var dis: String? = "0"
+ var disUnit = "KM"
+ if (meters > 0) {
+ if (meters / 1000 < 1) {
+ disUnit = AbsMogoApplication.getApp().getString(R.string.taxi_p_distance_unit_m)
+ dis = Math.round(meters.toFloat()).toString()
+ } else {
+ disUnit = AbsMogoApplication.getApp().getString(R.string.taxi_p_distance_unit_km)
+ dis = NumberFormatUtil.formatLong(meters.toDouble() / 1000)
+ }
+ }
+ val time = ceil(timeInSecond / 60f).toInt()
+ val arriveTime = DateTimeUtil.getAfterSecondTime(timeInSecond.toInt())
+
+ UiThreadHandler.post {
+ viewCallback?.setDistanceInfo(
+ dis!!,disUnit,time.toString(),surplusTimeUnit,arriveTime,stationDistance-meters.toInt(),stationDistance)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/startautopilot/StartAutopilotView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/startautopilot/StartAutopilotView.kt
new file mode 100644
index 0000000000..6a4625de3e
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/startautopilot/StartAutopilotView.kt
@@ -0,0 +1,245 @@
+package com.mogo.och.taxi.passenger.ui.startautopilot
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import androidx.core.content.ContextCompat
+import androidx.core.content.res.ResourcesCompat
+import androidx.lifecycle.ViewModelProvider
+import com.elegant.utils.UiThreadHandler
+import com.mogo.eagle.core.utilcode.kotlin.onClick
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
+import com.mogo.eagle.core.utilcode.util.OverlayViewUtils
+import com.mogo.eagle.core.utilcode.util.ToastUtils
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.widget.WindowRelativeLayout
+import com.mogo.och.taxi.passenger.widget.animutils.AnimationsContainer
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.actv_front_left_door
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.actv_front_right_door
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.actv_orderinfo
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.actv_rear_left_door
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.actv_rear_right_door
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.iv_xiaozhi_belt
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.starting_autopilot_view_close
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.taxi_p_autopilot_btn_bg
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.taxi_p_autopilot_starting
+import kotlinx.android.synthetic.main.taxi_p_start_autopilot_view.view.taxi_p_start_autopilot
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/6/14
+ */
+class StartAutopilotView : WindowRelativeLayout, StartAutopilotViewModel.StartAutopilotCallback{
+
+ constructor(context: Context) : super(context)
+
+ constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
+
+ constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
+
+ constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
+
+ companion object {
+ private val TAG = StartAutopilotView::class.java.simpleName
+ private const val TIMER_START_AUTOPILOT_INTERVAL = 20 * 1000L
+ }
+
+ var isStarting = false
+
+ private var taxiPStartAutopilot: AnimationsContainer?=null
+ private var taxiPStartAutopilotCar: AnimationsContainer?=null
+ private var taxiPXiaozhiBelt: AnimationsContainer?=null
+
+
+ init {
+ initView()
+ }
+
+ private fun initView() {
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_start_autopilot_view, this, true)
+ taxiPStartAutopilotCar = AnimationsContainer(R.array.taxi_p_start_autopilot_car, 20,taxi_p_autopilot_starting)
+ taxiPStartAutopilotCar?.setOnAnimStopListener(object :AnimationsContainer.OnAnimationStoppedListener{
+ override fun AnimationStopped() {
+ CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "动画暂停")
+ }
+ })
+ taxiPStartAutopilot = AnimationsContainer(R.array.taxi_p_start_autopilot, 15,taxi_p_autopilot_btn_bg)
+ taxiPStartAutopilot?.setOnAnimStopListener(object :AnimationsContainer.OnAnimationStoppedListener{
+ override fun AnimationStopped() {
+ CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "动画暂停")
+ }
+ })
+ taxiPXiaozhiBelt = AnimationsContainer(R.array.xiaozhi_belt, 15,iv_xiaozhi_belt)
+ taxiPXiaozhiBelt?.setOnAnimStopListener(object :AnimationsContainer.OnAnimationStoppedListener{
+ override fun AnimationStopped() {
+ CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "动画暂停")
+ }
+ })
+ }
+
+ fun startAutopilotBgAnimatorDrawable(isStart: Boolean) {
+ if (isStart) {
+ taxiPStartAutopilot?.start()
+ } else {
+ taxiPStartAutopilot?.stop()
+ }
+ }
+
+ @SuppressLint("UseCompatLoadingForDrawables")
+ override fun handleStartAutopilotBtnStatus(isBoarded: Boolean) {
+ taxi_p_autopilot_starting?.setImageResource(R.drawable.light_00003)
+ updateStartAutopilotBtnStatus(isBoarded)
+ if (isBoarded) { //高亮可点击状态下动画一直进行
+ startAutopilotBgAnimatorDrawable(true)
+ } else { // 置灰色可点击状态下动画停止
+ startAutopilotBgAnimatorDrawable(false)
+ }
+ }
+
+ override fun setOrderInfo(show: String) {
+ actv_orderinfo.text = show
+ }
+
+ override fun setDoorStatus(
+ doorPosition: StartAutopilotViewModel.DoorPosition,
+ isOpen: Boolean
+ ) {
+ when (doorPosition) {
+ StartAutopilotViewModel.DoorPosition.FRONT_LEFT -> {
+ if(isOpen){
+ actv_front_left_door.visibility = VISIBLE
+ }else{
+ actv_front_left_door.visibility = GONE
+ }
+ }
+ StartAutopilotViewModel.DoorPosition.FRONT_RIGHT -> {
+ if(isOpen){
+ actv_front_right_door.visibility = VISIBLE
+ }else{
+ actv_front_right_door.visibility = GONE
+ }
+ }
+ StartAutopilotViewModel.DoorPosition.REAR_LEFT -> {
+ if(isOpen){
+ actv_rear_left_door.visibility = VISIBLE
+ }else{
+ actv_rear_left_door.visibility = GONE
+ }
+ }
+ StartAutopilotViewModel.DoorPosition.REAR_RIGHT -> {
+ if(isOpen){
+ actv_rear_right_door.visibility = VISIBLE
+ }else{
+ actv_rear_right_door.visibility = GONE
+ }
+ }
+ else ->{
+
+ }
+ }
+ }
+
+ fun closeAllAnimsAndView() {
+ isStarting = false
+ clearStartingAnimFrame()
+ clearBgAnimDrawable()
+ OverlayViewUtils.dismissOverlayView(this)
+ }
+
+ fun updateStartAutopilotBtnStatus(isBoarded: Boolean) {
+ taxi_p_start_autopilot?.let {
+ if (isBoarded) {
+ it.setTextColor(ContextCompat.getColor(context,R.color.taxi_p_start_autopilot_txt_color))
+ it.background = null
+ } else {
+ it.background = ResourcesCompat.getDrawable(resources,R.drawable.taxi_p_start_autopilot_txt_btn_bg,null)
+ taxi_p_autopilot_btn_bg!!.background = null
+ it.setTextColor( ContextCompat.getColor(context,R.color.taxi_p_start_autopilot_txt_un_color))
+ }
+ it.tag = isBoarded
+ it.text = resources.getString(R.string.taxi_p_start_autopilot_txt)
+ }
+ }
+
+
+
+ private fun startingCarBgAnimatorDrawable(isStart: Boolean) {
+ if (isStart) {
+ taxi_p_autopilot_starting!!.setImageResource(0)
+ taxiPStartAutopilotCar?.start()
+ } else {
+ taxiPStartAutopilotCar?.stop()
+ taxi_p_autopilot_starting!!.setImageResource(R.drawable.light_00003)
+ }
+ }
+
+ private fun startOrStopLoadingAnim(start: Boolean) {
+ startingCarBgAnimatorDrawable(start)
+ if (start) {
+ isStarting = true
+ taxi_p_start_autopilot?.text = resources.getString(R.string.taxi_p_start_autopilot_loading)
+ taxi_p_start_autopilot?.setTextColor(ContextCompat.getColor(context,R.color.taxi_p_start_autopilot_txt_color))
+ startingAutopilotCountDown()
+ } else {
+ clearBgAnimDrawable()
+ isStarting = false
+ handleStartAutopilotBtnStatus(true)
+ }
+ }
+
+ private fun clearBgAnimDrawable() {
+ taxiPStartAutopilot?.stop()
+ }
+
+ fun clearStartingAnimFrame() {
+ taxiPStartAutopilotCar?.stop()
+ }
+
+ private fun startingAutopilotCountDown() {
+ UiThreadHandler.postDelayed({
+ //未启动成功20s后做处理
+ if (isStarting) { //判断动画是否在进行
+ ToastUtils.showLong(R.string.taxi_p_start_autopilot_fail_10s_tip)
+ updateStatusCountDownOver()
+ }
+ }, TIMER_START_AUTOPILOT_INTERVAL)
+ }
+
+ private fun updateStatusCountDownOver() {
+ isStarting = false
+ startingCarBgAnimatorDrawable(false)
+ taxi_p_start_autopilot?.text = resources.getString(R.string.taxi_p_start_autopilot_txt)
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ val viewModel = ViewModelProvider(this).get(StartAutopilotViewModel::class.java)
+ viewModel.setStartAutopilotCallback(this)
+ taxi_p_start_autopilot.onClick {
+ //开启动画和自动驾驶
+ if (!(taxi_p_start_autopilot!!.tag as Boolean)) {
+ ToastUtils.showLong(R.string.taxi_p_start_autopilot_un_click_tip)
+ return@onClick
+ }
+ if (!isStarting) {
+ startOrStopLoadingAnim(true)
+ viewModel.startAutopilot()
+ }
+ }
+ starting_autopilot_view_close.onClick {
+ closeAllAnimsAndView()
+ }
+ taxiPXiaozhiBelt?.start()
+ }
+
+
+ override fun onDetachedFromWindow() {
+ isStarting = false
+ clearStartingAnimFrame()
+ clearBgAnimDrawable()
+ taxiPXiaozhiBelt?.stop()
+ super.onDetachedFromWindow()
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/startautopilot/StartAutopilotViewModel.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/startautopilot/StartAutopilotViewModel.kt
new file mode 100644
index 0000000000..27ee557d20
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/startautopilot/StartAutopilotViewModel.kt
@@ -0,0 +1,125 @@
+package com.mogo.och.taxi.passenger.ui.startautopilot
+
+import androidx.lifecycle.ViewModel
+import chassis.Chassis.DoorNumber
+import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisDoorStateListener
+import com.mogo.eagle.core.function.call.autopilot.CallerChassisDoorStateListenerManager
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
+import com.mogo.eagle.core.utilcode.util.UiThreadHandler
+import com.mogo.och.taxi.passenger.callback.IOCHTaxiPassengerOrderStatusCallback
+import com.mogo.och.taxi.passenger.model.AutopilotManager
+import com.mogo.och.taxi.passenger.model.TaxiPassengerModel
+
+class StartAutopilotViewModel : ViewModel(), IOCHTaxiPassengerOrderStatusCallback,
+ IMoGoChassisDoorStateListener {
+
+ private val TAG = StartAutopilotViewModel::class.java.simpleName
+
+ private var viewCallback: StartAutopilotCallback? = null
+
+ init {
+ TaxiPassengerModel.setOrderStatusCallback(TAG, this)
+ CallerChassisDoorStateListenerManager.addListener(TAG, this)
+ }
+
+ fun setStartAutopilotCallback(viewCallback: StartAutopilotCallback) {
+ this.viewCallback = viewCallback
+ TaxiPassengerModel.startOrStopReadyToAutopilotLoop(true)
+ setOrderInfo()
+ setDoorInfo()
+ }
+
+ private fun setDoorInfo() {
+ val doorList = CallerChassisDoorStateListenerManager.getDoorList()
+ CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "门太变化初始化:${doorList}")
+ doorList?.forEach {
+ exchangeEnum(it.number,it.status==1)
+ }
+ }
+
+ private fun setOrderInfo() {
+ val currentOCHOrder = TaxiPassengerModel.currentOCHOrder
+ currentOCHOrder?.let {
+ val phone = it.passengerPhone
+ val show = if (phone.length > 8) {
+ //截取电话号码前三位
+ val phoneNumPre = phone.substring(0, 3)
+ //截取电话号码后四位
+ val phoneNumFix = phone.substring(7)
+
+ "用户:$phoneNumPre****$phoneNumFix 目的地:${it.endSiteAddr}"
+ } else {
+ "用户:${phone} 目的地:${it.endSiteAddr}"
+ }
+ viewCallback?.setOrderInfo(show)
+ }
+ }
+
+ override fun onCleared() {
+ super.onCleared()
+ this.viewCallback = null
+ TaxiPassengerModel.setOrderStatusCallback(TAG, null)
+ CallerChassisDoorStateListenerManager.removeListener(TAG)
+ }
+
+ override fun onDriverHasCheckedPilotCondition(isBoarded: Boolean) {
+ viewCallback?.handleStartAutopilotBtnStatus(isBoarded)
+ }
+
+ /**
+ * 开启自动驾驶
+ */
+ fun startAutopilot() {
+ AutopilotManager.startAutopilot()
+ }
+
+ override fun onAutopilotSingleDoorState(num: DoorNumber, open: Boolean) {
+ super.onAutopilotSingleDoorState(num, open)
+ CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "门太变化:${num}--${open}")
+ exchangeEnum(num,open)
+ }
+
+ private fun exchangeEnum(num: DoorNumber,open: Boolean){
+ when (num) {
+ DoorNumber.FRONT_LEFT -> {
+ runMain(DoorPosition.FRONT_LEFT,open)
+ }
+
+ DoorNumber.FRONT_RIGHT -> {
+ runMain(DoorPosition.FRONT_RIGHT,open)
+ }
+
+ DoorNumber.REAR_LEFT -> {
+ runMain(DoorPosition.REAR_LEFT,open)
+ }
+
+ DoorNumber.REAR_RIGHT -> {
+ runMain(DoorPosition.REAR_RIGHT,open)
+ }
+
+ DoorNumber.MIDDLE -> {
+ runMain(DoorPosition.MIDDLE,open)
+ }
+
+ else -> {}
+ }
+ }
+
+ private fun runMain(posttion:DoorPosition,isOpen: Boolean){
+ UiThreadHandler.post {
+ viewCallback?.setDoorStatus(posttion,isOpen)
+ }
+ }
+
+
+ interface StartAutopilotCallback {
+ fun handleStartAutopilotBtnStatus(isBoarded: Boolean)
+ fun setOrderInfo(show: String)
+ fun setDoorStatus(doorPosition: DoorPosition,isOpen:Boolean)
+ }
+
+ enum class DoorPosition {
+ FRONT_LEFT, FRONT_RIGHT, REAR_LEFT, REAR_RIGHT, MIDDLE
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/statusview/StatusBarView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/statusview/StatusBarView.kt
new file mode 100644
index 0000000000..c1a34b2e2d
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/statusview/StatusBarView.kt
@@ -0,0 +1,102 @@
+package com.mogo.och.taxi.passenger.ui.statusview
+
+import android.content.Context
+import android.os.SystemClock
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.fragment.app.FragmentActivity
+import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
+import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
+import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
+import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
+import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager
+import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView
+import com.mogo.eagle.core.utilcode.util.ActivityUtils
+import com.mogo.och.common.module.manager.debug.DebugViewWatchDogFragment
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.ui.debug.DebugEvent
+import kotlinx.android.synthetic.main.taxi_p_statusview.view.iv_biz_icon
+import kotlinx.android.synthetic.main.taxi_p_statusview.view.vShowDebugView
+import me.jessyan.autosize.utils.AutoSizeUtils
+import org.greenrobot.eventbus.EventBus
+import java.lang.ref.WeakReference
+
+class StatusBarView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener {
+
+ companion object {
+ const val TAG = "StatusBarView"
+ private const val COUNTS = 4 // 点击次数
+ private const val DURATION: Long = 1000 // 规定有效时间
+ }
+
+ private var debugViewWatchDogFragment: WeakReference? = null
+
+ private var mHits = LongArray(COUNTS)
+
+ private fun continuousClick() {
+ if (ToggleDebugView.toggleDebugView.isShowIng()) {
+ ToggleDebugView.toggleDebugView.dismiss()
+ return
+ }
+ //每次点击时,数组向前移动一位
+ System.arraycopy(mHits, 1, mHits, 0, mHits.size - 1)
+ //为数组最后一位赋值
+ mHits[mHits.size - 1] = SystemClock.uptimeMillis()
+ if (mHits[0] >= (SystemClock.uptimeMillis() - DURATION)) {
+ mHits = LongArray(COUNTS) //重新初始化数组
+ showDebugView()
+ }
+ }
+
+ init {
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_statusview, this, true)
+ setBackgroundResource(R.drawable.taxi_p_status_bg)
+ isClickable = true
+ isFocusable = true
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ post {
+ val params: ViewGroup.LayoutParams = layoutParams
+ params.height = AutoSizeUtils.dp2px(context,120f)
+ layoutParams = params
+ }
+
+ CallerAutoPilotStatusListenerManager.addListener(TAG, this)
+
+ iv_biz_icon.setOnClickListener { continuousClick() }
+ vShowDebugView.setOnLongClickListener {
+ EventBus.getDefault().post(DebugEvent())
+ false
+ }
+
+ }
+
+ private fun showDebugView() {
+ if (debugViewWatchDogFragment?.get() == null) {
+ debugViewWatchDogFragment = WeakReference(DebugViewWatchDogFragment.newInstance())
+ }
+ val debugViewFragment = debugViewWatchDogFragment?.get()
+ if (ActivityUtils.getTopActivity() is FragmentActivity) {
+ val fragmentActivity = ActivityUtils.getTopActivity() as FragmentActivity
+ DebugViewWatchDogFragment.showDebugView(fragmentActivity.supportFragmentManager,fragmentActivity.supportFragmentManager,debugViewFragment)
+ }
+
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ CallerHmiViewControlListenerManager.removeListener(TAG)
+ CallerSkinModeListenerManager.removeListener(TAG)
+ CallerDevaToolsManager.hideStatusBar()
+ }
+
+}
+
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/statusview/TaxiPBlueToothView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/statusview/TaxiPBlueToothView.kt
new file mode 100644
index 0000000000..b27eeb0c21
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/statusview/TaxiPBlueToothView.kt
@@ -0,0 +1,66 @@
+package com.mogo.och.taxi.passenger.ui.statusview
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.widget.RelativeLayout
+import com.mogo.eagle.core.function.api.devatools.mofang.IMoGoMoFangProvider
+import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
+import com.mogo.och.taxi.passenger.R
+import kotlinx.android.synthetic.main.taxi_p_blue_tooth.view.mofangView
+
+/**
+ * 魔戒蓝牙控件
+ * 放置于StatusBar右侧位置
+ * todo arrow
+ */
+class TaxiPBlueToothView : RelativeLayout, IMoGoMoFangProvider.OnMoFangStatusListener {
+
+ companion object{
+ const val TAG = "TaxiPBlueToothView"
+ }
+
+
+ constructor(context: Context) : this(context, null)
+ constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
+ constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(context, attrs, defStyleAttr, 0)
+ constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
+
+ init {
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_blue_tooth, this, true)
+ }
+
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ CallerDevaToolsManager.mofang()?.registerMoFangStatusListener(TAG, this)
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ CallerDevaToolsManager.mofang()?.unRegisterMoFangStatusListener(this)
+ }
+
+ override fun onMoFangConnected() {
+ mofangView.setImageResource(R.drawable.taxi_p_blue_tooth_close)
+ }
+
+ override fun onMoFangDisconnected() {
+ mofangView.setImageResource(R.drawable.taxi_p_blue_tooth_open)
+ }
+
+ @SuppressLint("SetTextI18n")
+ override fun onMoFangBatteryChanged(battery: Int) {
+
+ }
+
+ override fun onMoFangClicked(keyCode: Int) {}
+
+ override fun onMoFangLongClicked(keyCode: Int) {}
+
+ override fun onMoFangCombineClicked(vararg keyCodes: Int) {}
+
+ override fun onMoFangStatusError(msg: String) {}
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/FullVideoUtils.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/FullVideoUtils.kt
new file mode 100644
index 0000000000..5b3d3f8e87
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/FullVideoUtils.kt
@@ -0,0 +1,95 @@
+package com.mogo.och.taxi.passenger.ui.video
+
+import android.annotation.SuppressLint
+import android.app.Activity
+import android.view.View
+import android.view.WindowManager
+import com.mogo.och.taxi.passenger.widget.ConsultVideoPlayer
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import java.lang.Exception
+
+/**
+ * 视频全屏播放
+ *
+ * @author yangyakun
+ */
+@SuppressLint("StaticFieldLeak")
+object FullVideoUtils {
+ private const val TAG = "FullVideoUtils"
+ private var windowManager: WindowManager? = null
+
+ @Volatile
+ private var isShowing = false
+
+ /**
+ * 记录上一次的View
+ */
+ private var lastOverlayView: View? = null
+
+ /**
+ * 添加覆盖View在Activity上面
+ */
+ @JvmOverloads
+ fun showOverlayView(context: Activity, overlayView: View, ani: Int = -1) {
+ if (windowManager == null) {
+ windowManager = context.windowManager
+ }
+
+ // 设置View显示模式,沉浸式的侵入到状态栏,导航栏
+ overlayView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
+ val params = WindowManager.LayoutParams()
+ params.width = WindowManager.LayoutParams.MATCH_PARENT
+ params.height = WindowManager.LayoutParams.MATCH_PARENT
+ params.alpha = 1.0f
+ // 设置窗口类型为应用子窗口,和PopupWindow同类型
+ params.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
+ // 没有边界限制,允许窗口扩展到屏幕外
+ params.flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+ if (ani != -1) {
+ params.windowAnimations = ani
+ }
+ try {
+ // 后门逻辑,长时间触摸消失
+ lastOverlayView = overlayView
+ windowManager!!.addView(overlayView, params)
+ isShowing = true
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ /**
+ * 移除覆盖View在Activity上面
+ */
+ fun dismissOverlayView(needReleas:Boolean) {
+ if (!isShowing) {
+ return
+ }
+ val consultVideoPlayer =
+ lastOverlayView?.findViewById(GSYVideoManager.FULLSCREEN_ID)
+ consultVideoPlayer?.let {
+ if(needReleas){
+ it.onVideoReset()
+ it.setVideoAllCallBack(null)
+ it.smalllPlayer?.clearFullscreenLayout(it)
+ }
+ consultVideoPlayer.removeAllViews()
+ }
+ try {
+ if (windowManager != null) {
+ windowManager!!.removeViewImmediate(lastOverlayView)
+ windowManager = null
+ }
+ if (lastOverlayView != null) {
+ lastOverlayView = null
+ }
+ isShowing = false
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/InfoVideoView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/InfoVideoView.kt
new file mode 100644
index 0000000000..776188dbc4
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/InfoVideoView.kt
@@ -0,0 +1,232 @@
+package com.mogo.och.taxi.passenger.ui.video
+
+import android.content.Context
+import android.graphics.Color
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.FrameLayout
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.recyclerview.widget.RecyclerView
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerVideoPlay
+import com.mogo.och.taxi.passenger.ui.video.layoutmanage.CarouselLayoutManager
+import com.mogo.och.taxi.passenger.ui.video.layoutmanage.CarouselZoomPostLayoutListener
+import com.mogo.och.taxi.passenger.ui.video.layoutmanage.CenterScrollListener
+import com.mogo.och.taxi.passenger.widget.ConsultVideoPlayer
+import com.mogo.och.taxi.passenger.widget.indicator.IndicatorView
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorOrientation
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorStyle
+import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
+import kotlin.math.floor
+
+/**
+ * @author ChenFufeng
+ * 蘑菇资讯视频
+ */
+internal class InfoVideoView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : FrameLayout(
+ context,
+ attrs,
+ defStyleAttr
+) {
+
+ companion object{
+ private const val TAG = "VideoView"
+ }
+
+ init {
+ LayoutInflater.from(context).inflate(R.layout.taxi_p_mogo_video_layout, this, true)
+ initView()
+ }
+
+ private var rvVideoPlaylist: RecyclerView? = null
+ private lateinit var indicatorView: IndicatorView
+ private lateinit var clContain: ConstraintLayout
+
+ private val arrayListOf by lazy {
+ arrayListOf().apply {
+ add(TaxiPassengerVideoPlay(
+ "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708596763/全车型混剪增加红旗车队.m4v",
+ "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969511280/车队.png",
+ "蘑菇车联覆盖生活的方方面面"
+ ))
+ add(TaxiPassengerVideoPlay(
+ "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708554279/红旗车队.m4v",
+ "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969553174/红旗重新排版.png",
+ "蘑菇车联之红旗车队"
+ ))
+ add(
+ TaxiPassengerVideoPlay(
+ "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708499497/大运会合作解说版.m4v",
+ "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969536177/大运会.png",
+ "蘑菇车联牵手成都大运会"
+ )
+ )
+ add(
+ TaxiPassengerVideoPlay(
+ "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655708409810/20210610重新排版3屏.m4v",
+ "https://img.zhidaohulian.com/fileServer/online_car_hailing/1655969579713/三屏.png",
+ "多视角体验蘑菇车联自动驾驶"
+ )
+ )
+ }
+ }
+
+ fun exitFullScreenMode(resetVideoPlayer: Boolean) {
+ val carouselLayoutManager = rvVideoPlaylist?.layoutManager as CarouselLayoutManager
+ val (_: Int, player) = getPlayer(carouselLayoutManager)
+ player?.let {
+ it.exitFullScreenMode()
+ it.onVideoPause()
+ if(resetVideoPlayer) {
+ it.onVideoReset()
+ }
+ }
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ configPage()
+ }
+
+ override fun onVisibilityChanged(changedView: View, visibility: Int) {
+ super.onVisibilityChanged(changedView, visibility)
+ if(changedView!=this){
+ return
+ }
+ val carouselLayoutManager = rvVideoPlaylist?.layoutManager as CarouselLayoutManager
+ val (_: Int, player) = getPlayer(carouselLayoutManager)
+ when (visibility) {
+ View.VISIBLE -> {
+ player?.let {
+ if (!player.isIfCurrentIsFullscreen) {
+ when (player.currentState) {
+ GSYVideoView.CURRENT_STATE_PAUSE -> {
+ //player.onVideoResume(false)
+ }
+ else -> {}
+ }
+ }
+ }
+ }
+ else -> {
+ player?.let {
+ if (!player.isIfCurrentIsFullscreen) {
+ player.onVideoPause()
+ }
+ }
+ }
+ }
+ }
+
+ private fun initView() {
+ rvVideoPlaylist = findViewById(R.id.infoVideoPlaylist)
+ indicatorView = findViewById(R.id.infoIndicatorView)
+ clContain = findViewById(R.id.infoContainer)
+ }
+
+ private fun configPage() {
+// FullVideoUtils.dismissOverlayView(true)
+ initData()
+ }
+
+ private fun initData() {
+ val carouselLayoutManager = CarouselLayoutManager(CarouselLayoutManager.HORIZONTAL, true)
+ carouselLayoutManager.setPostLayoutListener(CarouselZoomPostLayoutListener())
+ carouselLayoutManager.maxVisibleItems = 1
+ indicatorView.notifyDataChanged(arrayListOf.size)
+ indicatorView.setSlideMode(IndicatorSlideMode.SCALE)
+ indicatorView.setOrientation(IndicatorOrientation.INDICATOR_HORIZONTAL)
+ indicatorView.setIndicatorStyle(IndicatorStyle.ROUND_RECT)
+ indicatorView.setSliderColor(
+ Color.parseColor("#80000000"), Color.parseColor("#3FACFD"),
+ Color.parseColor("#3FACFD")
+ )
+ indicatorView.setSliderWidth(9f, 54f)
+ indicatorView.setSliderHeight(9f)
+ indicatorView.setSliderGap(36f)
+ rvVideoPlaylist?.addOnScrollListener(object : CenterScrollListener() {
+ var prePlayerPosition = 0
+ override fun pageSelect(recyclerView: RecyclerView?, newState: Int) {
+ //播放视频
+ val (centerItemPosition: Int, player) = getPlayer(carouselLayoutManager)
+ indicatorView.onPageSelected(centerItemPosition)
+ if (player is ConsultVideoPlayer) {
+ if (prePlayerPosition != centerItemPosition) {
+ if (player.currentState == GSYVideoView.CURRENT_STATE_PAUSE) {
+ player.onVideoReset()
+ }
+ val playerHolder =
+ carouselLayoutManager.findViewByPosition(prePlayerPosition)
+ val prePlayer =
+ playerHolder?.findViewById(R.id.video_item_player)
+ prePlayer?.onVideoReset()
+ } else {
+ player.onVideoResume(false)
+ }
+ }
+ prePlayerPosition = centerItemPosition
+ }
+
+ override fun pageStop() {
+ val (_: Int, player) = getPlayer(carouselLayoutManager)
+ if (player is ConsultVideoPlayer) {
+ player.onVideoPause()
+ }
+ }
+
+ })
+ carouselLayoutManager.addOnDargAutoDiffListener { adapterPosition, currentPosition ->
+ val fl = adapterPosition - floor(adapterPosition)
+ var currentIndex = currentPosition
+ if (fl > 0.5) {
+ if (currentPosition == 0) {
+ currentIndex = rvVideoPlaylist?.adapter!!.itemCount - 1
+ } else {
+ currentIndex -= 1
+ }
+ }
+ indicatorView.onPageScrolled(currentIndex, fl, 0)
+ }
+ val recyclerVideoAdapter = RecyclerVideoAdapter(context, arrayListOf, rvVideoPlaylist)
+ recyclerVideoAdapter.setOnThumbImageClilckListener {
+ val (_: Int, player) = getPlayer(carouselLayoutManager)
+ if (player is ConsultVideoPlayer) {
+ player.onVideoReset()
+ player.thumbImageViewLayout.visibility = View.VISIBLE
+ }
+ rvVideoPlaylist?.smoothScrollToPosition(it)
+ }
+ rvVideoPlaylist?.layoutManager = carouselLayoutManager
+ rvVideoPlaylist?.setHasFixedSize(true)
+ rvVideoPlaylist?.adapter = recyclerVideoAdapter
+ }
+
+ private fun getPlayer(carouselLayoutManager: CarouselLayoutManager): Pair {
+ val centerItemPosition: Int = carouselLayoutManager.centerItemPosition
+ val playerHolder = carouselLayoutManager.findViewByPosition(centerItemPosition)
+ val player = playerHolder?.findViewById(R.id.video_item_player)
+ return Pair(centerItemPosition, player)
+ }
+
+ override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
+ super.onWindowFocusChanged(hasWindowFocus)
+ val carouselLayoutManager = rvVideoPlaylist?.layoutManager as CarouselLayoutManager
+ val (_: Int, player) = getPlayer(carouselLayoutManager)
+ player?.let {
+ if(it.isInPlayingState&&!it.isIfCurrentIsFullscreen&&!hasWindowFocus){
+ player.onVideoPause()
+ }
+ }
+
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/RecyclerItemVideoHolder.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/RecyclerItemVideoHolder.java
new file mode 100644
index 0000000000..f28610a727
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/RecyclerItemVideoHolder.java
@@ -0,0 +1,29 @@
+package com.mogo.och.taxi.passenger.ui.video;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.mogo.och.taxi.passenger.R;
+import com.mogo.och.taxi.passenger.widget.ConsultVideoPlayer;
+import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder;
+
+public class RecyclerItemVideoHolder extends RecyclerView.ViewHolder {
+
+ public final static String TAG = "RecyclerView2List";
+
+ protected Context context;
+
+ public ConsultVideoPlayer gsyVideoPlayer;
+
+ GSYVideoOptionBuilder gsyVideoOptionBuilder;
+
+ public RecyclerItemVideoHolder(Context context, View v) {
+ super(v);
+ this.context = context;
+ gsyVideoPlayer = v.findViewById(R.id.video_item_player);
+ gsyVideoOptionBuilder = new GSYVideoOptionBuilder();
+ }
+
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/RecyclerVideoAdapter.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/RecyclerVideoAdapter.java
new file mode 100644
index 0000000000..bdf79d44b1
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/RecyclerVideoAdapter.java
@@ -0,0 +1,118 @@
+package com.mogo.och.taxi.passenger.ui.video;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.RequestOptions;
+import com.mogo.eagle.core.utilcode.util.ToastUtils;
+import com.mogo.och.taxi.passenger.R;
+import com.mogo.och.taxi.passenger.bean.TaxiPassengerVideoPlay;
+import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack;
+
+import java.util.List;
+
+import me.jessyan.autosize.AutoSizeCompat;
+
+public class RecyclerVideoAdapter extends RecyclerView.Adapter {
+
+ private final static String TAG = "RecyclerVideoAdapter";
+
+ private List itemDataList ;
+ private final Context context;
+ private OnThumbImageClilckListener onThumbImageClilckListener;
+ private final RecyclerView recyclerView;
+
+
+ public void setOnThumbImageClilckListener(OnThumbImageClilckListener onThumbImageClilckListener) {
+ this.onThumbImageClilckListener = onThumbImageClilckListener;
+ }
+
+ public RecyclerVideoAdapter(Context context, List itemDataList,RecyclerView recyclerView) {
+ this.itemDataList = itemDataList;
+ this.context = context;
+ this.recyclerView = recyclerView;
+ }
+
+ @NonNull
+ @Override
+ public RecyclerItemVideoHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(context).inflate(R.layout.list_video_item_light, parent, false);
+ RecyclerItemVideoHolder recyclerItemVideoHolder = new RecyclerItemVideoHolder(context, v);
+ recyclerItemVideoHolder.setIsRecyclable(false);
+ return recyclerItemVideoHolder;
+ }
+
+
+
+ @Override
+ public void onBindViewHolder(@NonNull final RecyclerItemVideoHolder holder, int position) {
+ final TaxiPassengerVideoPlay taxiPassengerVideoPlay = itemDataList.get(position);
+ AutoSizeCompat.autoConvertDensityOfGlobal(holder.itemView.getResources());
+ holder.gsyVideoOptionBuilder
+ .setEnlargeImageRes(R.drawable.taxi_p_change_full)
+ .setUrl(taxiPassengerVideoPlay.getUrl())
+ .setCacheWithPlay(true)
+ .setPlayTag(taxiPassengerVideoPlay.getImageUrl()+position)
+ .setThumbPlay(false)
+ .build(holder.gsyVideoPlayer);
+ holder.gsyVideoPlayer.getTitleTextView().setText(taxiPassengerVideoPlay.getTitle());
+ Glide.with(context)
+ .load(taxiPassengerVideoPlay.getImageUrl())
+ .apply(new RequestOptions().placeholder(R.drawable.taxi_p_video_holder).centerCrop())
+ .into(holder.gsyVideoPlayer.coverImage);
+ holder.gsyVideoPlayer.getThumbImageViewLayout().setOnClickListener(v -> {
+ if(onThumbImageClilckListener!=null){
+ onThumbImageClilckListener.onDxChanged(holder.getAbsoluteAdapterPosition());
+ }
+ });
+ holder.gsyVideoPlayer.setVideoAllCallBack(new GSYSampleCallBack(){
+ @Override
+ public void onAutoComplete(String url, Object... objects) {
+ holder.gsyVideoPlayer.onVideoReset();
+ if(holder.getAbsoluteAdapterPosition()==getItemCount()-1){
+ recyclerView.smoothScrollToPosition(0);
+ }else {
+ recyclerView.smoothScrollToPosition(holder.getAbsoluteAdapterPosition()+1);
+ }
+ }
+
+ @Override
+ public void onClickBlank(String url, Object... objects) {
+ super.onClickBlank(url, objects);
+ recyclerView.smoothScrollToPosition(holder.getAbsoluteAdapterPosition());
+ }
+
+ @Override
+ public void onPlayError(String url, Object... objects) {
+ ToastUtils.showLong("哎呀,出错了,看看其他视频吧");
+ }
+
+ @Override
+ public void onClickStartError(String url, Object... objects) {
+ ToastUtils.showLong("哎呀,出错了,看看其他视频吧");
+ }
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return itemDataList.size();
+ }
+
+
+ @Override
+ public int getItemViewType(int position) {
+ return 1;
+ }
+
+
+ public interface OnThumbImageClilckListener {
+ void onDxChanged(int targetPosition);
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CarouselLayoutManager.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CarouselLayoutManager.java
new file mode 100644
index 0000000000..326341e950
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CarouselLayoutManager.java
@@ -0,0 +1,970 @@
+package com.mogo.och.taxi.passenger.ui.video.layoutmanage;
+
+import android.graphics.PointF;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.view.ViewCompat;
+import androidx.recyclerview.widget.LinearSmoothScroller;
+import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An implementation of {@link RecyclerView.LayoutManager} that layout items like carousel.
+ * Generally there is one center item and bellow this item there are maximum {@link CarouselLayoutManager#getMaxVisibleItems()} items on each side of the center
+ * item. By default {@link CarouselLayoutManager#getMaxVisibleItems()} is {@link CarouselLayoutManager#MAX_VISIBLE_ITEMS}.
+ *
+ * This LayoutManager supports only fixedSized adapter items.
+ *
+ * This LayoutManager supports {@link CarouselLayoutManager#HORIZONTAL} and {@link CarouselLayoutManager#VERTICAL} orientations.
+ *
+ * This LayoutManager supports circle layout. By default it if disabled. We don't recommend to use circle layout with adapter items count less then 3.
+ *
+ * Please be sure that layout_width of adapter item is a constant value and not {@link ViewGroup.LayoutParams#MATCH_PARENT}
+ * for {@link #HORIZONTAL} orientation.
+ * So like layout_height is not {@link ViewGroup.LayoutParams#MATCH_PARENT} for {@link CarouselLayoutManager#VERTICAL}
+ *
+ */
+public class CarouselLayoutManager extends RecyclerView.LayoutManager implements RecyclerView.SmoothScroller.ScrollVectorProvider {
+
+ public static final int HORIZONTAL = OrientationHelper.HORIZONTAL;
+ public static final int VERTICAL = OrientationHelper.VERTICAL;
+ /**
+ * 固定值一直不变
+ */
+ public static final int INVALID_POSITION = -1;
+ public static final int MAX_VISIBLE_ITEMS = 3;
+
+ private static final boolean CIRCLE_LAYOUT = false;
+
+ private boolean mDecoratedChildSizeInvalid;
+ private Integer mDecoratedChildWidth;
+ private Integer mDecoratedChildHeight;
+
+ private final int mOrientation;
+ private boolean mCircleLayout;
+
+ private int mPendingScrollPosition;
+
+ private final LayoutHelper mLayoutHelper = new LayoutHelper(MAX_VISIBLE_ITEMS);
+
+ private PostLayoutListener mViewPostLayout;
+
+ private final List mOnCenterItemSelectionListeners = new ArrayList<>();
+ private final List onDargAutoDiffListeners = new ArrayList<>();
+ private int mCenterItemPosition = INVALID_POSITION;
+ private int mItemsCount;
+
+ @Nullable
+ private CarouselSavedState mPendingCarouselSavedState;
+
+ /**
+ * @param orientation should be {@link #VERTICAL} or {@link #HORIZONTAL}
+ */
+ @SuppressWarnings("unused")
+ public CarouselLayoutManager(final int orientation) {
+ this(orientation, CIRCLE_LAYOUT);
+ }
+
+ /**
+ * If circleLayout is true then all items will be in cycle. Scroll will be infinite on both sides.
+ *
+ * @param orientation should be {@link #VERTICAL} or {@link #HORIZONTAL}
+ * @param circleLayout true for enabling circleLayout
+ */
+ @SuppressWarnings("unused")
+ public CarouselLayoutManager(final int orientation, final boolean circleLayout) {
+ if (HORIZONTAL != orientation && VERTICAL != orientation) {
+ throw new IllegalArgumentException("orientation should be HORIZONTAL or VERTICAL");
+ }
+ mOrientation = orientation;
+ mCircleLayout = circleLayout;
+ mPendingScrollPosition = INVALID_POSITION;
+ }
+
+ /**
+ * Change circle layout type
+ */
+ @SuppressWarnings("unused")
+ public void setCircleLayout(final boolean circleLayout) {
+ if (mCircleLayout != circleLayout) {
+ mCircleLayout = circleLayout;
+ requestLayout();
+ }
+ }
+
+ /**
+ * Setup {@link PostLayoutListener} for this LayoutManager.
+ * Its methods will be called for each visible view item after general LayoutManager layout finishes.
+ *
+ * Generally this method should be used for scaling and translating view item for better (different) view presentation of layouting.
+ *
+ * @param postLayoutListener listener for item layout changes. Can be null.
+ */
+ @SuppressWarnings("unused")
+ public void setPostLayoutListener(@Nullable final PostLayoutListener postLayoutListener) {
+ mViewPostLayout = postLayoutListener;
+ requestLayout();
+ }
+
+ /**
+ * Setup maximum visible (layout) items on each side of the center item.
+ * Basically during scrolling there can be more visible items (+1 item on each side), but in idle state this is the only reached maximum.
+ *
+ * @param maxVisibleItems should be great then 0, if bot an {@link IllegalAccessException} will be thrown
+ */
+ @CallSuper
+ @SuppressWarnings("unused")
+ public void setMaxVisibleItems(final int maxVisibleItems) {
+ if (0 > maxVisibleItems) {
+ throw new IllegalArgumentException("maxVisibleItems can't be less then 0");
+ }
+ mLayoutHelper.mMaxVisibleItems = maxVisibleItems;
+ requestLayout();
+ }
+
+ /**
+ * @return current setup for maximum visible items.
+ * @see #setMaxVisibleItems(int)
+ */
+ @SuppressWarnings("unused")
+ public int getMaxVisibleItems() {
+ return mLayoutHelper.mMaxVisibleItems;
+ }
+
+ @Override
+ public RecyclerView.LayoutParams generateDefaultLayoutParams() {
+ return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ }
+
+ /**
+ * @return current layout orientation
+ * @see #VERTICAL
+ * @see #HORIZONTAL
+ */
+ public int getOrientation() {
+ return mOrientation;
+ }
+
+ @Override
+ public boolean canScrollHorizontally() {
+ return 0 != getChildCount() && HORIZONTAL == mOrientation;
+ }
+
+ @Override
+ public boolean canScrollVertically() {
+ return 0 != getChildCount() && VERTICAL == mOrientation;
+ }
+
+ /**
+ * @return current layout center item
+ */
+ public int getCenterItemPosition() {
+ return mCenterItemPosition;
+ }
+
+ /**
+ * @param onCenterItemSelectionListener listener that will trigger when ItemSelectionChanges. can't be null
+ */
+ public void addOnItemSelectionListener(@NonNull final OnCenterItemSelectionListener onCenterItemSelectionListener) {
+ mOnCenterItemSelectionListeners.add(onCenterItemSelectionListener);
+ }
+
+ /**
+ * @param onCenterItemSelectionListener listener that was previously added by {@link #addOnItemSelectionListener(OnCenterItemSelectionListener)}
+ */
+ public void removeOnItemSelectionListener(@NonNull final OnCenterItemSelectionListener onCenterItemSelectionListener) {
+ mOnCenterItemSelectionListeners.remove(onCenterItemSelectionListener);
+ }
+
+ public void addOnDargAutoDiffListener(@NonNull final OnDargAutoDiffListener onDargAutoDiffListener) {
+ onDargAutoDiffListeners.add(onDargAutoDiffListener);
+ }
+
+ public void removeOnDargAutoDiffListener(@NonNull final OnDargAutoDiffListener onDargAutoDiffListener) {
+ onDargAutoDiffListeners.remove(onDargAutoDiffListener);
+ }
+
+ @SuppressWarnings("RefusedBequest")
+ @Override
+ public void scrollToPosition(final int position) {
+ if (0 > position) {
+ throw new IllegalArgumentException("position can't be less then 0. position is : " + position);
+ }
+ mPendingScrollPosition = position;
+ requestLayout();
+ }
+
+ @SuppressWarnings("RefusedBequest")
+ @Override
+ public void smoothScrollToPosition(@NonNull final RecyclerView recyclerView, @NonNull final RecyclerView.State state, final int position) {
+ final LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
+ @Override
+ public int calculateDyToMakeVisible(final View view, final int snapPreference) {
+ if (!canScrollVertically()) {
+ return 0;
+ }
+
+ return getOffsetForCurrentView(view);
+ }
+
+ @Override
+ public int calculateDxToMakeVisible(final View view, final int snapPreference) {
+ if (!canScrollHorizontally()) {
+ return 0;
+ }
+ return getOffsetForCurrentView(view);
+ }
+ };
+ linearSmoothScroller.setTargetPosition(position);
+ startSmoothScroll(linearSmoothScroller);
+ }
+
+ @Override
+ @Nullable
+ public PointF computeScrollVectorForPosition(final int targetPosition) {
+ if (0 == getChildCount()) {
+ return null;
+ }
+ final float directionDistance = getScrollDirection(targetPosition);
+ //noinspection NumericCastThatLosesPrecision
+ final int direction = (int) -Math.signum(directionDistance);
+
+ if (HORIZONTAL == mOrientation) {
+ return new PointF(direction, 0);
+ } else {
+ return new PointF(0, direction);
+ }
+ }
+
+ private float getScrollDirection(final int targetPosition) {
+ final float currentScrollPosition = makeScrollPositionInRange0ToCount(getCurrentScrollPosition(), mItemsCount);
+
+ if (mCircleLayout) {
+ final float t1 = currentScrollPosition - targetPosition;
+ final float t2 = Math.abs(t1) - mItemsCount;
+ if (Math.abs(t1) > Math.abs(t2)) {
+ return Math.signum(t1) * t2;
+ } else {
+ return t1;
+ }
+ } else {
+ return currentScrollPosition - targetPosition;
+ }
+ }
+
+ @Override
+ public int scrollVerticallyBy(final int dy, @NonNull final RecyclerView.Recycler recycler, @NonNull final RecyclerView.State state) {
+ if (HORIZONTAL == mOrientation) {
+ return 0;
+ }
+ return scrollBy(dy, recycler, state);
+ }
+
+ @Override
+ public int scrollHorizontallyBy(final int dx, final RecyclerView.Recycler recycler, final RecyclerView.State state) {
+ if (VERTICAL == mOrientation) {
+ return 0;
+ }
+ return scrollBy(dx, recycler, state);
+ }
+
+ /**
+ * This method is called from {@link #scrollHorizontallyBy(int, RecyclerView.Recycler, RecyclerView.State)} and
+ * {@link #scrollVerticallyBy(int, RecyclerView.Recycler, RecyclerView.State)} to calculate needed scroll that is allowed.
+ *
+ * This method may do relayout work.
+ *
+ * @param diff 要滚动的距离
+ * @param recycler 回收期
+ * @param state Transient state of RecyclerView
+ * @return distance that we actually scrolled by
+ */
+ @CallSuper
+ protected int scrollBy(final int diff, @NonNull final RecyclerView.Recycler recycler, @NonNull final RecyclerView.State state) {
+ if (null == mDecoratedChildWidth || null == mDecoratedChildHeight) {
+ return 0;
+ }
+ if (0 == getChildCount() || 0 == diff) {
+ return 0;
+ }
+ final int resultScroll;
+ if (mCircleLayout) {
+ resultScroll = diff;
+
+ mLayoutHelper.mScrollOffset += resultScroll;
+
+ final int maxOffset = getScrollItemSize() * mItemsCount;
+ while (0 > mLayoutHelper.mScrollOffset) {
+ mLayoutHelper.mScrollOffset += maxOffset;
+ }
+ while (mLayoutHelper.mScrollOffset > maxOffset) {
+ mLayoutHelper.mScrollOffset -= maxOffset;
+ }
+
+ mLayoutHelper.mScrollOffset -= resultScroll;
+ } else {
+ final int maxOffset = getMaxScrollOffset();
+
+ if (0 > mLayoutHelper.mScrollOffset + diff) {
+ resultScroll = -mLayoutHelper.mScrollOffset; //to make it 0
+ } else if (mLayoutHelper.mScrollOffset + diff > maxOffset) {
+ resultScroll = maxOffset - mLayoutHelper.mScrollOffset; //to make it maxOffset
+ } else {
+ resultScroll = diff;
+ }
+ }
+ if (0 != resultScroll) {
+ mLayoutHelper.mScrollOffset += resultScroll;
+ fillData(recycler, state);
+ }
+ return resultScroll;
+ }
+
+ @Override
+ public void onMeasure(@NonNull final RecyclerView.Recycler recycler, @NonNull final RecyclerView.State state, final int widthSpec, final int heightSpec) {
+ mDecoratedChildSizeInvalid = true;
+
+ super.onMeasure(recycler, state, widthSpec, heightSpec);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public void onAdapterChanged(final RecyclerView.Adapter oldAdapter, final RecyclerView.Adapter newAdapter) {
+ super.onAdapterChanged(oldAdapter, newAdapter);
+
+ removeAllViews();
+ }
+
+
+ @SuppressWarnings("RefusedBequest")
+ @Override
+ @CallSuper
+ public void onLayoutChildren(@NonNull final RecyclerView.Recycler recycler, @NonNull final RecyclerView.State state) {
+ if (0 == state.getItemCount()) {
+ removeAndRecycleAllViews(recycler);
+ selectItemCenterPosition(INVALID_POSITION);
+ return;
+ }
+
+ detachAndScrapAttachedViews(recycler);
+
+ if (null == mDecoratedChildWidth || mDecoratedChildSizeInvalid) {
+ final List scrapList = recycler.getScrapList();
+
+ final boolean shouldRecycle;
+ final View view;
+ if (scrapList.isEmpty()) {
+ shouldRecycle = true;
+ final int itemsCount = state.getItemCount();
+ view = recycler.getViewForPosition(
+ mPendingScrollPosition == INVALID_POSITION ?
+ 0 :
+ Math.max(0, Math.min(itemsCount - 1, mPendingScrollPosition))
+ );
+ addView(view);
+ } else {
+ shouldRecycle = false;
+ view = scrapList.get(0).itemView;
+ }
+ measureChildWithMargins(view, 0, 0);
+
+ final int decoratedChildWidth = getDecoratedMeasuredWidth(view);
+ final int decoratedChildHeight = getDecoratedMeasuredHeight(view);
+ if (shouldRecycle) {
+ detachAndScrapView(view, recycler);
+ }
+
+ if (null != mDecoratedChildWidth && (mDecoratedChildWidth != decoratedChildWidth || mDecoratedChildHeight != decoratedChildHeight)) {
+ if (INVALID_POSITION == mPendingScrollPosition && null == mPendingCarouselSavedState) {
+ mPendingScrollPosition = mCenterItemPosition;
+ }
+ }
+
+ mDecoratedChildWidth = decoratedChildWidth;
+ mDecoratedChildHeight = decoratedChildHeight;
+ mDecoratedChildSizeInvalid = false;
+ }
+
+ if (INVALID_POSITION != mPendingScrollPosition) {
+ final int itemsCount = state.getItemCount();
+ mPendingScrollPosition = 0 == itemsCount ? INVALID_POSITION : Math.max(0, Math.min(itemsCount - 1, mPendingScrollPosition));
+ }
+ if (INVALID_POSITION != mPendingScrollPosition) {
+ mLayoutHelper.mScrollOffset = calculateScrollForSelectingPosition(mPendingScrollPosition, state);
+ mPendingScrollPosition = INVALID_POSITION;
+ mPendingCarouselSavedState = null;
+ } else if (null != mPendingCarouselSavedState) {
+ mLayoutHelper.mScrollOffset = calculateScrollForSelectingPosition(mPendingCarouselSavedState.mCenterItemPosition, state);
+ mPendingCarouselSavedState = null;
+ } else if (state.didStructureChange() && INVALID_POSITION != mCenterItemPosition) {
+ mLayoutHelper.mScrollOffset = calculateScrollForSelectingPosition(mCenterItemPosition, state);
+ }
+
+ fillData(recycler, state);
+ }
+
+ private int calculateScrollForSelectingPosition(final int itemPosition, final RecyclerView.State state) {
+ if (itemPosition == INVALID_POSITION) {
+ return 0;
+ }
+
+ final int fixedItemPosition = itemPosition < state.getItemCount() ? itemPosition : state.getItemCount() - 1;
+ return fixedItemPosition * (VERTICAL == mOrientation ? mDecoratedChildHeight : mDecoratedChildWidth);
+ }
+
+ private void fillData(@NonNull final RecyclerView.Recycler recycler, @NonNull final RecyclerView.State state) {
+ final float currentScrollPosition = getCurrentScrollPosition();
+
+ generateLayoutOrder(currentScrollPosition, state);
+ detachAndScrapAttachedViews(recycler);
+ recyclerOldViews(recycler);
+
+ final int width = getWidthNoPadding();
+ final int height = getHeightNoPadding();
+ if (VERTICAL == mOrientation) {
+ fillDataVertical(recycler, width, height);
+ } else {
+ fillDataHorizontal(recycler, width, height);
+ }
+
+ recycler.clear();
+
+ detectOnItemSelectionChanged(currentScrollPosition, state);
+ }
+
+ private void detectOnItemSelectionChanged(final float currentScrollPosition, final RecyclerView.State state) {
+ final float absCurrentScrollPosition = makeScrollPositionInRange0ToCount(currentScrollPosition, state.getItemCount());
+ final int centerItem = Math.round(absCurrentScrollPosition);
+ if(currentScrollPosition-centerItem!=0){
+ new Handler(Looper.getMainLooper()).post(() -> dragDxDiff(currentScrollPosition,mCenterItemPosition));
+ }
+ if (mCenterItemPosition != centerItem) {
+ mCenterItemPosition = centerItem;
+ new Handler(Looper.getMainLooper()).post(new Runnable() {
+ @Override
+ public void run() {
+ selectItemCenterPosition(centerItem);
+ }
+ });
+ }
+ }
+
+ private void selectItemCenterPosition(final int centerItem) {
+ for (final OnCenterItemSelectionListener onCenterItemSelectionListener : mOnCenterItemSelectionListeners) {
+ onCenterItemSelectionListener.onCenterItemChanged(centerItem);
+ }
+ }
+ private void dragDxDiff(final float centerItem,final int currentPosition) {
+ for (final OnDargAutoDiffListener onDargAutoDiffListener : onDargAutoDiffListeners) {
+ onDargAutoDiffListener.onDxChanged(centerItem,currentPosition);
+ }
+ }
+
+ private void fillDataVertical(final RecyclerView.Recycler recycler, final int width, final int height) {
+ final int start = (width - mDecoratedChildWidth) / 2;
+ final int end = start + mDecoratedChildWidth;
+
+ final int centerViewTop = (height - mDecoratedChildHeight) / 2;
+
+ for (int i = 0, count = mLayoutHelper.mLayoutOrder.length; i < count; ++i) {
+ final LayoutOrder layoutOrder = mLayoutHelper.mLayoutOrder[i];
+ final int offset = getCardOffsetByPositionDiff(layoutOrder.mItemPositionDiff);
+ final int top = centerViewTop + offset;
+ final int bottom = top + mDecoratedChildHeight;
+ fillChildItem(start, top, end, bottom, layoutOrder, recycler, i);
+ }
+ }
+
+ private void fillDataHorizontal(final RecyclerView.Recycler recycler, final int width, final int height) {
+ final int top = (height - mDecoratedChildHeight) / 2;
+ final int bottom = top + mDecoratedChildHeight;
+
+ final int centerViewStart = (width - mDecoratedChildWidth) / 2;
+
+ for (int i = 0, count = mLayoutHelper.mLayoutOrder.length; i < count; ++i) {
+ final LayoutOrder layoutOrder = mLayoutHelper.mLayoutOrder[i];
+ final int offset = getCardOffsetByPositionDiff(layoutOrder.mItemPositionDiff);
+ final int start = centerViewStart + offset;
+ final int end = start + mDecoratedChildWidth;
+ fillChildItem(start, top, end, bottom, layoutOrder, recycler, i);
+ }
+ }
+
+
+ @SuppressWarnings("MethodWithTooManyParameters")
+ private void fillChildItem(final int start, final int top, final int end, final int bottom, @NonNull final LayoutOrder layoutOrder, @NonNull final RecyclerView.Recycler recycler, final int i) {
+ final View view = bindChild(layoutOrder.mItemAdapterPosition, recycler);
+ ViewCompat.setElevation(view, i);
+ ItemTransformation transformation = null;
+ if (null != mViewPostLayout) {
+ transformation = mViewPostLayout.transformChild(view, layoutOrder.mItemPositionDiff, mOrientation, layoutOrder.mItemAdapterPosition);
+ }
+ if (null == transformation) {
+ view.layout(start, top, end, bottom);
+ } else {
+ view.layout(Math.round(start + transformation.mTranslationX), Math.round(top + transformation.mTranslationY),
+ Math.round(end + transformation.mTranslationX), Math.round(bottom + transformation.mTranslationY));
+ view.setScaleX(transformation.mScaleX);
+ view.setScaleY(transformation.mScaleY);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ view.setTransitionAlpha(transformation.mAlpha);
+ }else {
+ view.setAlpha(transformation.mAlpha);
+ }
+ }
+ }
+
+ /**
+ * 中心项目的当前滚动位置。如果是循环布局,则该值可以在任何范围内。如果不是,那么它在[0,-1]
+ */
+ private float getCurrentScrollPosition() {
+ final int fullScrollSize = getMaxScrollOffset();
+ if (0 == fullScrollSize) {
+ return 0;
+ }
+ return 1.0f * mLayoutHelper.mScrollOffset / getScrollItemSize();
+ }
+
+ /**
+ * 填充布局中所有项目的最大滚动值。通常,这仅适用于非循环布局。
+ */
+ private int getMaxScrollOffset() {
+ return getScrollItemSize() * (mItemsCount - 1);
+ }
+
+ /**
+ * Because we can support old Android versions, we should layout our children in specific order to make our center view in the top of layout
+ * (this item should layout last). So this method will calculate layout order and fill up {@link #mLayoutHelper} object.
+ * This object will be filled by only needed to layout items. Non visible items will not be there.
+ *
+ * @param currentScrollPosition current scroll position this is a value that indicates position of center item
+ * (if this value is int, then center item is really in the center of the layout, else it is near state).
+ * Be aware that this value can be in any range is it is cycle layout
+ * @param state Transient state of RecyclerView
+ * @see #getCurrentScrollPosition()
+ */
+ private void generateLayoutOrder(final float currentScrollPosition, @NonNull final RecyclerView.State state) {
+ mItemsCount = state.getItemCount();
+ final float absCurrentScrollPosition = makeScrollPositionInRange0ToCount(currentScrollPosition, mItemsCount);
+ final int centerItem = Math.round(absCurrentScrollPosition);
+
+ if (mCircleLayout && 1 < mItemsCount) {
+ final int layoutCount = Math.min(mLayoutHelper.mMaxVisibleItems * 2 + 1, mItemsCount);
+
+ mLayoutHelper.initLayoutOrder(layoutCount);
+
+ final int countLayoutHalf = layoutCount / 2;
+ // before center item
+ for (int i = 1; i <= countLayoutHalf; ++i) {
+ final int position = Math.round(absCurrentScrollPosition - i + mItemsCount) % mItemsCount;
+ mLayoutHelper.setLayoutOrder(countLayoutHalf - i, position, centerItem - absCurrentScrollPosition - i);
+ }
+ // after center item
+ for (int i = layoutCount - 1; i >= countLayoutHalf + 1; --i) {
+ final int position = Math.round(absCurrentScrollPosition - i + layoutCount) % mItemsCount;
+ mLayoutHelper.setLayoutOrder(i - 1, position, centerItem - absCurrentScrollPosition + layoutCount - i);
+ }
+ mLayoutHelper.setLayoutOrder(layoutCount - 1, centerItem, centerItem - absCurrentScrollPosition);
+
+ } else {
+ final int firstVisible = Math.max(centerItem - mLayoutHelper.mMaxVisibleItems, 0);
+ final int lastVisible = Math.min(centerItem + mLayoutHelper.mMaxVisibleItems, mItemsCount - 1);
+ final int layoutCount = lastVisible - firstVisible + 1;
+
+ mLayoutHelper.initLayoutOrder(layoutCount);
+
+ for (int i = firstVisible; i <= lastVisible; ++i) {
+ if (i == centerItem) {
+ mLayoutHelper.setLayoutOrder(layoutCount - 1, i, i - absCurrentScrollPosition);
+ } else if (i < centerItem) {
+ mLayoutHelper.setLayoutOrder(i - firstVisible, i, i - absCurrentScrollPosition);
+ } else {
+ mLayoutHelper.setLayoutOrder(layoutCount - (i - centerItem) - 1, i, i - absCurrentScrollPosition);
+ }
+ }
+ }
+ }
+
+ public int getWidthNoPadding() {
+ return getWidth() - getPaddingStart() - getPaddingEnd();
+ }
+
+ public int getHeightNoPadding() {
+ return getHeight() - getPaddingEnd() - getPaddingStart();
+ }
+
+ private View bindChild(final int position, @NonNull final RecyclerView.Recycler recycler) {
+ final View view = recycler.getViewForPosition(position);
+
+ addView(view);
+ measureChildWithMargins(view, 0, 0);
+
+ return view;
+ }
+
+ private void recyclerOldViews(final RecyclerView.Recycler recycler) {
+ for (RecyclerView.ViewHolder viewHolder : new ArrayList<>(recycler.getScrapList())) {
+ int adapterPosition = viewHolder.getAdapterPosition();
+ boolean found = false;
+ for (LayoutOrder layoutOrder : mLayoutHelper.mLayoutOrder) {
+ if (layoutOrder.mItemAdapterPosition == adapterPosition) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ recycler.recycleView(viewHolder.itemView);
+ }
+ }
+ }
+
+ /**
+ * Called during {@link #fillData(RecyclerView.Recycler, RecyclerView.State)} to calculate item offset from layout center line.
+ *
+ * Returns {@link #convertItemPositionDiffToSmoothPositionDiff(float)} * (size off area above center item when it is on the center).
+ * Sign is: plus if this item is bellow center line, minus if not
+ *
+ * ----- - area above it
+ * ||||| - center item
+ * ----- - area bellow it (it has the same size as are above center item)
+ *
+ * @param itemPositionDiff current item difference with layout center line. if this is 0, then this item center is in layout center line.
+ * if this is 1 then this item is bellow the layout center line in the full item size distance.
+ * @return offset in scroll px coordinates.
+ */
+ protected int getCardOffsetByPositionDiff(final float itemPositionDiff) {
+ final double smoothPosition = convertItemPositionDiffToSmoothPositionDiff(itemPositionDiff);
+
+ final int dimenDiff;
+ if (VERTICAL == mOrientation) {
+ dimenDiff = (getHeightNoPadding() - mDecoratedChildHeight) / 2;
+ } else {
+ dimenDiff = (getWidthNoPadding() - mDecoratedChildWidth) / 2;
+ }
+ //noinspection NumericCastThatLosesPrecision
+ return (int) Math.round(Math.signum(itemPositionDiff) * dimenDiff * smoothPosition);
+ }
+
+ /**
+ * Called during {@link #getCardOffsetByPositionDiff(float)} for better item movement.
+ * Current implementation speed up items that are far from layout center line and slow down items that are close to this line.
+ * This code is full of maths. If you want to make items move in a different way, probably you should override this method.
+ * Please see code comments for better explanations.
+ *
+ * @param itemPositionDiff current item difference with layout center line. if this is 0, then this item center is in layout center line.
+ * if this is 1 then this item is bellow the layout center line in the full item size distance.
+ * @return smooth position offset. needed for scroll calculation and better user experience.
+ * @see #getCardOffsetByPositionDiff(float)
+ */
+ @SuppressWarnings({"MagicNumber", "InstanceMethodNamingConvention"})
+ protected double convertItemPositionDiffToSmoothPositionDiff(final float itemPositionDiff) {
+ // generally item moves the same way above center and bellow it. So we don't care about diff sign.
+ final float absIemPositionDiff = Math.abs(itemPositionDiff);
+
+ // we detect if this item is close for center or not. We use (1 / maxVisibleItem) ^ (1/3) as close definer.
+ if (absIemPositionDiff > StrictMath.pow(1.0f / mLayoutHelper.mMaxVisibleItems, 1.0f / 3)) {
+ // this item is far from center line, so we should make it move like square root function
+ return StrictMath.pow(absIemPositionDiff / mLayoutHelper.mMaxVisibleItems, 1 / 2.0f);
+ } else {
+ // this item is close from center line. we should slow it down and don't make it speed up very quick.
+ // so square function in range of [0, (1/maxVisible)^(1/3)] is quite good in it;
+ return StrictMath.pow(absIemPositionDiff, 2.0f);
+ }
+ }
+
+ /**
+ * @return full item size
+ */
+ protected int getScrollItemSize() {
+ if (VERTICAL == mOrientation) {
+ return mDecoratedChildHeight;
+ } else {
+ return mDecoratedChildWidth;
+ }
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ if (null != mPendingCarouselSavedState) {
+ return new CarouselSavedState(mPendingCarouselSavedState);
+ }
+ final CarouselSavedState savedState = new CarouselSavedState(super.onSaveInstanceState());
+ savedState.mCenterItemPosition = mCenterItemPosition;
+ return savedState;
+ }
+
+ @Override
+ public void onRestoreInstanceState(final Parcelable state) {
+ if (state instanceof CarouselSavedState) {
+ mPendingCarouselSavedState = (CarouselSavedState) state;
+
+ super.onRestoreInstanceState(mPendingCarouselSavedState.mSuperState);
+ } else {
+ super.onRestoreInstanceState(state);
+ }
+ }
+
+ /**
+ * @return 从中心到最近项目的滚动偏移量
+ */
+ protected int getOffsetCenterView() {
+ return Math.round(getCurrentScrollPosition()) * getScrollItemSize() - mLayoutHelper.mScrollOffset;
+ }
+
+ protected int getOffsetForCurrentView(@NonNull final View view) {
+ final int targetPosition = getPosition(view);
+ final float directionDistance = getScrollDirection(targetPosition);
+
+ return Math.round(directionDistance * getScrollItemSize());
+ }
+
+ /**
+ * 使滚动范围在[0,count]内的Helper方法。通常,只有循环布局才需要此方法。
+ *
+ * @param currentScrollPosition 滚动位置范围 个位数 view的index 小数滚动的范围
+ * @param count adapter 中的数量
+ * @return 在[0,总数]范围内滚动位置良好
+ */
+ private static float makeScrollPositionInRange0ToCount(final float currentScrollPosition, final int count) {
+ float absCurrentScrollPosition = currentScrollPosition;
+ while (0 > absCurrentScrollPosition) {
+ absCurrentScrollPosition += count;
+ }
+ while (Math.round(absCurrentScrollPosition) >= count) {
+ absCurrentScrollPosition -= count;
+ }
+ return absCurrentScrollPosition;
+ }
+
+ /**
+ * This interface methods will be called for each visible view item after general LayoutManager layout finishes.
+ *
+ * Generally this method should be used for scaling and translating view item for better (different) view presentation of layouting.
+ */
+ @SuppressWarnings("InterfaceNeverImplemented")
+ public abstract static class PostLayoutListener {
+
+ /**
+ * 子布局完成后调用。通常,您可以在这里进行任何平移和缩放工作。
+ *
+ * @param child view that was layout
+ * @param itemPositionToCenterDiff view center line difference to layout center. if > 0 then this item is bellow layout center line, else if not
+ * @param orientation layoutManager orientation {@link #getLayoutDirection()}
+ * @param itemPositionInAdapter item position inside adapter for this layout pass
+ */
+ public ItemTransformation transformChild(
+ @NonNull final View child,
+ final float itemPositionToCenterDiff,
+ final int orientation,
+ final int itemPositionInAdapter
+ ) {
+ return transformChild(child, itemPositionToCenterDiff, orientation);
+ }
+
+ /**
+ * Called after child layout finished. Generally you can do any translation and scaling work here.
+ *
+ * @param child view that was layout
+ * @param itemPositionToCenterDiff view center line difference to layout center. if > 0 then this item is bellow layout center line, else if not
+ * @param orientation layoutManager orientation {@link #getLayoutDirection()}
+ */
+ public ItemTransformation transformChild(
+ @NonNull final View child,
+ final float itemPositionToCenterDiff,
+ final int orientation
+ ) {
+ throw new IllegalStateException("at least one transformChild should be implemented");
+ }
+ }
+
+ public interface OnCenterItemSelectionListener {
+
+ /**
+ * Listener that will be called on every change of center item.
+ * This listener will be triggered on every layout operation if item was changed.
+ * Do not do any expensive operations in this method since this will effect scroll experience.
+ *
+ * @param adapterPosition current layout center item
+ */
+ void onCenterItemChanged(final int adapterPosition);
+ }
+
+ public interface OnDargAutoDiffListener {
+ void onDxChanged(final float adapterPosition,final int currentPosition);
+ }
+
+ /**
+ * Helper class that holds currently visible items.
+ * Generally this class fills this list.
+ *
+ * This class holds all scroll and maxVisible items state.
+ *
+ * @see #getMaxVisibleItems()
+ */
+ private static class LayoutHelper {
+
+ private int mMaxVisibleItems;
+
+ private int mScrollOffset;
+
+ private LayoutOrder[] mLayoutOrder;
+
+ private final List> mReusedItems = new ArrayList<>();
+
+ LayoutHelper(final int maxVisibleItems) {
+ mMaxVisibleItems = maxVisibleItems;
+ }
+
+ /**
+ * Called before any fill calls. Needed to recycle old items and init new array list. Generally this list is an array an it is reused.
+ *
+ * @param layoutCount items count that will be layout
+ */
+ void initLayoutOrder(final int layoutCount) {
+ if (null == mLayoutOrder || mLayoutOrder.length != layoutCount) {
+ if (null != mLayoutOrder) {
+ recycleItems(mLayoutOrder);
+ }
+ mLayoutOrder = new LayoutOrder[layoutCount];
+ fillLayoutOrder();
+ }
+ }
+
+ /**
+ * Called during layout generation process of filling this list. Should be called only after {@link #initLayoutOrder(int)} method call.
+ *
+ * @param arrayPosition position in layout order
+ * @param itemAdapterPosition adapter position of item for future data filling logic
+ * @param itemPositionDiff difference of current item scroll position and center item position.
+ * if this is a center item and it is in real center of layout, then this will be 0.
+ * if current layout is not in the center, then this value will never be int.
+ * if this item center is bellow layout center line then this value is greater then 0,
+ * else less then 0.
+ */
+ void setLayoutOrder(final int arrayPosition, final int itemAdapterPosition, final float itemPositionDiff) {
+ final LayoutOrder item = mLayoutOrder[arrayPosition];
+ item.mItemAdapterPosition = itemAdapterPosition;
+ item.mItemPositionDiff = itemPositionDiff;
+ }
+
+ /**
+ * Checks is this screen Layout has this adapterPosition view in layout
+ *
+ * @param adapterPosition adapter position of item for future data filling logic
+ * @return true is adapterItem is in layout
+ */
+ boolean hasAdapterPosition(final int adapterPosition) {
+ if (null != mLayoutOrder) {
+ for (final LayoutOrder layoutOrder : mLayoutOrder) {
+ if (layoutOrder.mItemAdapterPosition == adapterPosition) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @SuppressWarnings("VariableArgumentMethod")
+ private void recycleItems(@NonNull final LayoutOrder... layoutOrders) {
+ for (final LayoutOrder layoutOrder : layoutOrders) {
+ //noinspection ObjectAllocationInLoop
+ mReusedItems.add(new WeakReference<>(layoutOrder));
+ }
+ }
+
+ private void fillLayoutOrder() {
+ for (int i = 0, length = mLayoutOrder.length; i < length; ++i) {
+ if (null == mLayoutOrder[i]) {
+ mLayoutOrder[i] = createLayoutOrder();
+ }
+ }
+ }
+
+ private LayoutOrder createLayoutOrder() {
+ final Iterator> iterator = mReusedItems.iterator();
+ while (iterator.hasNext()) {
+ final WeakReference layoutOrderWeakReference = iterator.next();
+ final LayoutOrder layoutOrder = layoutOrderWeakReference.get();
+ iterator.remove();
+ if (null != layoutOrder) {
+ return layoutOrder;
+ }
+ }
+ return new LayoutOrder();
+ }
+ }
+
+ /**
+ * Class that holds item data.
+ * This class is filled during {@link #generateLayoutOrder(float, RecyclerView.State)} and used during {@link #fillData(RecyclerView.Recycler, RecyclerView.State)}
+ */
+ private static class LayoutOrder {
+
+ /**
+ * Item adapter position
+ */
+ private int mItemAdapterPosition;
+ /**
+ * Item center difference to layout center. If center of item is bellow layout center, then this value is greater then 0, else it is less.
+ */
+ private float mItemPositionDiff;
+ }
+
+ protected static class CarouselSavedState implements Parcelable {
+
+ private final Parcelable mSuperState;
+ private int mCenterItemPosition;
+
+ protected CarouselSavedState(@Nullable final Parcelable superState) {
+ mSuperState = superState;
+ }
+
+ private CarouselSavedState(@NonNull final Parcel in) {
+ mSuperState = in.readParcelable(RecyclerView.LayoutManager.class.getClassLoader());
+ mCenterItemPosition = in.readInt();
+ }
+
+ protected CarouselSavedState(@NonNull final CarouselSavedState other) {
+ mSuperState = other.mSuperState;
+ mCenterItemPosition = other.mCenterItemPosition;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(final Parcel parcel, final int i) {
+ parcel.writeParcelable(mSuperState, i);
+ parcel.writeInt(mCenterItemPosition);
+ }
+
+ public static final Creator CREATOR
+ = new Creator() {
+ @Override
+ public CarouselSavedState createFromParcel(final Parcel parcel) {
+ return new CarouselSavedState(parcel);
+ }
+
+ @Override
+ public CarouselSavedState[] newArray(final int i) {
+ return new CarouselSavedState[i];
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CarouselZoomPostLayoutListener.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CarouselZoomPostLayoutListener.java
new file mode 100644
index 0000000000..348cd70704
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CarouselZoomPostLayoutListener.java
@@ -0,0 +1,40 @@
+package com.mogo.och.taxi.passenger.ui.video.layoutmanage;
+
+import android.view.View;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Implementation of {@link CarouselLayoutManager.PostLayoutListener} that makes interesting scaling of items.
+ * We are trying to make items scaling quicker for closer items for center and slower for when they are far away.
+ * Tis implementation uses atan function for this purpose.
+ */
+public class CarouselZoomPostLayoutListener extends CarouselLayoutManager.PostLayoutListener {
+
+ private final float mScaleMultiplier;
+
+ public CarouselZoomPostLayoutListener() {
+ this(0.21f);
+ }
+
+ public CarouselZoomPostLayoutListener(final float scaleMultiplier) {
+ mScaleMultiplier = scaleMultiplier;
+ }
+
+ @Override
+ public ItemTransformation transformChild(@NonNull final View child, final float itemPositionToCenterDiff, final int orientation) {
+ float scale = 1.0f - mScaleMultiplier * Math.abs(itemPositionToCenterDiff);
+ final float translateY;
+ final float translateX;
+ if (CarouselLayoutManager.VERTICAL == orientation) {
+ final float translateYGeneral = child.getMeasuredHeight() * (1 - scale) / 2f;
+ translateY = Math.signum(itemPositionToCenterDiff) * translateYGeneral;
+ translateX = 0;
+ } else {
+ final float translateXGeneral = child.getMeasuredWidth() * (1 - scale)/8;
+ translateX = Math.signum(itemPositionToCenterDiff) * translateXGeneral;
+ translateY = 0;
+ }
+ return new ItemTransformation(scale,scale, scale, 0, translateY);
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CenterScrollListener.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CenterScrollListener.java
new file mode 100644
index 0000000000..4b04e7b957
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/CenterScrollListener.java
@@ -0,0 +1,52 @@
+package com.mogo.och.taxi.passenger.ui.video.layoutmanage;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Class for centering items after scroll event.
+ * This class will listen to current scroll state and if item is not centered after scroll it will automatically scroll it to center.
+ */
+public class CenterScrollListener extends RecyclerView.OnScrollListener {
+
+ private boolean mAutoSet = true;
+
+ @Override
+ public void onScrollStateChanged(@NonNull final RecyclerView recyclerView, final int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
+ if (!(layoutManager instanceof CarouselLayoutManager)) {
+ mAutoSet = true;
+ return;
+ }
+
+ final CarouselLayoutManager lm = (CarouselLayoutManager) layoutManager;
+ if (!mAutoSet) {
+ if (RecyclerView.SCROLL_STATE_IDLE == newState) {
+ final int scrollNeeded = lm.getOffsetCenterView();
+ // 滚动到中心位置
+ if (CarouselLayoutManager.HORIZONTAL == lm.getOrientation()) {
+ recyclerView.smoothScrollBy(scrollNeeded, 0);
+ } else {
+ recyclerView.smoothScrollBy(0, scrollNeeded);
+ }
+ pageSelect(recyclerView,newState);
+ mAutoSet = true;
+ }
+ }
+ if (RecyclerView.SCROLL_STATE_DRAGGING == newState || RecyclerView.SCROLL_STATE_SETTLING == newState) {
+ mAutoSet = false;
+ }
+ if(RecyclerView.SCROLL_STATE_DRAGGING == newState){
+ pageStop();
+ }
+ }
+
+ protected void pageStop() {
+
+ }
+
+ protected void pageSelect(RecyclerView recyclerView, final int newState) {
+
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/ItemTransformation.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/ItemTransformation.java
new file mode 100644
index 0000000000..c0851112ab
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/ui/video/layoutmanage/ItemTransformation.java
@@ -0,0 +1,18 @@
+package com.mogo.och.taxi.passenger.ui.video.layoutmanage;
+
+public class ItemTransformation {
+
+ final float mAlpha;
+ final float mScaleX;
+ final float mScaleY;
+ final float mTranslationX;
+ final float mTranslationY;
+
+ public ItemTransformation(final float alpha,final float scaleX, final float scaleY, final float translationX, final float translationY) {
+ mScaleX = scaleX;
+ mScaleY = scaleY;
+ mTranslationX = translationX;
+ mTranslationY = translationY;
+ mAlpha = alpha;
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/utils/TaxiPassengerAnalyticsManager.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/utils/TaxiPassengerAnalyticsManager.kt
new file mode 100644
index 0000000000..5b4f60df6b
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/utils/TaxiPassengerAnalyticsManager.kt
@@ -0,0 +1,116 @@
+package com.mogo.och.taxi.passenger.utils
+
+import android.text.TextUtils
+import com.mogo.cloud.passport.MoGoAiCloudClientConfig
+import com.mogo.commons.debug.DebugConfig
+import com.mogo.commons.utils.MogoAnalyticUtils
+import com.mogo.eagle.core.data.app.AppConfigInfo
+import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
+import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
+import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
+import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_TAXI_P
+import com.mogo.eagle.core.utilcode.util.DateTimeUtils
+import com.mogo.och.common.module.utils.RxUtils
+import com.mogo.och.taxi.passenger.constant.TaxiPassengerConst
+import io.reactivex.disposables.Disposable
+
+/**
+ * OCH Taxi埋点工具
+ *
+ * Created on 2022/3/24
+ */
+object TaxiPassengerAnalyticsManager {
+
+
+ private var mStartAutopilotKey: String? = null
+ private val mStartAutopilotParams = HashMap()
+
+ var startAutopiloTimeOut: Disposable? = null
+
+
+ fun triggerStartAutopilotFailureEventByAdas(failCode: String, failMsg: String) {
+ RxUtils.disposeSubscribe(startAutopiloTimeOut)
+ triggerStartAutopilotFailureEvent(failCode, failMsg)
+ }
+
+ private fun clearStartAutopilotParams() {
+ mStartAutopilotParams.clear()
+ }
+
+ /**
+ * ① 15s超时调用
+ * ② 底盘明确给出错误原因
+ * 启动自驾失败写日志
+ */
+ private fun triggerStartAutopilotFailureEvent(failCode: String, failMsg: String) {
+ if (mStartAutopilotParams.isEmpty()) return
+ e(M_TAXI_P + "triggerStartAutopilotFailureEvent", failMsg)
+ if (CallerAutoPilotStatusListenerManager.getState() != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_START_FAILURE_CODE] = failCode
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_START_FAILURE_MSG] = failMsg
+ }
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_START_RESULT] =
+ CallerAutoPilotStatusListenerManager.getState() == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
+ MogoAnalyticUtils.track(mStartAutopilotKey, mStartAutopilotParams)
+ clearStartAutopilotParams() //清空参数数据,防止误传
+ }
+
+ /**
+ *
+ * ① 自检完成后 启动自驾
+ * ② 自驾由其他状态转换到自驾中回调
+ * 触发'开启自动驾驶'埋点流程
+ * 开启自动驾驶,15s内成功则发送成功埋点,否则发送失败埋点
+ * @param restart false(点击'开始服务'启动)/true(接管后点击'自动驾驶'按钮启动)
+ * @param send 是否直接发送埋点(15s内开启成功则直接发送成功埋点)
+ */
+ fun triggerStartAutopilotEvent(restart: Boolean, send: Boolean, startName: String, endName: String, orderNo: String) {
+ mStartAutopilotKey = if (restart) TaxiPassengerConst.EVENT_KEY_RESTART_AUTOPILOT else TaxiPassengerConst.EVENT_KEY_START_SERVICE
+
+ if (send) {
+ if (mStartAutopilotParams.isEmpty()) return
+ // 开启成功,取消失败定时任务
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_START_FAILURE_CODE] = ""
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_START_FAILURE_MSG] = ""
+ // 取消15s超时
+ RxUtils.disposeSubscribe(startAutopiloTimeOut)
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_START_RESULT] = true
+ MogoAnalyticUtils.track(mStartAutopilotKey, mStartAutopilotParams)
+ clearStartAutopilotParams() //清空参数数据,防止误传
+ } else {
+ val plateNum = AppConfigInfo.plateNumber
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_SN] = MoGoAiCloudClientConfig.getInstance().sn
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_PLATE_NUM] = if (TextUtils.isEmpty(plateNum)) "" else plateNum
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_ENV_ONLINE] = DebugConfig.getNetMode() == DebugConfig.NET_MODE_RELEASE
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_TIME] = DateTimeUtils.getTimeText(DateTimeUtils.yyyy_MM_dd_HH_mm_ss)
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_START_NAME] = startName
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_END_NAME] = endName
+ mStartAutopilotParams[TaxiPassengerConst.EVENT_PARAM_ORDER_NUMBER] = orderNo
+ startAutopiloTimeOut = RxUtils.createSubscribeOnOwnThread(TaxiPassengerConst.LOOP_PERIOD_15S) {
+ // 15s内未开启,上报失败埋点
+ triggerStartAutopilotFailureEvent("", "15s后app等待超时")
+ }
+ }
+ }
+
+ /**
+ * 触发"无法开启自驾已知异常"埋点
+ * @param startName
+ * @param endName
+ * @param orderNo
+ */
+ fun triggerUnableStartAPReasonEvent(startName: String, endName: String, orderNo: String, reason: String) {
+ val plateNum = AppConfigInfo.plateNumber
+ val params = HashMap()
+ params[TaxiPassengerConst.EVENT_PARAM_SN] = MoGoAiCloudClientConfig.getInstance().sn
+ params[TaxiPassengerConst.EVENT_PARAM_PLATE_NUM] = if (TextUtils.isEmpty(plateNum)) "" else plateNum
+ params[TaxiPassengerConst.EVENT_PARAM_ENV_ONLINE] = DebugConfig.getNetMode() == DebugConfig.NET_MODE_RELEASE
+ params[TaxiPassengerConst.EVENT_PARAM_TIME] = DateTimeUtils.getTimeText(DateTimeUtils.yyyy_MM_dd_HH_mm_ss)
+ params[TaxiPassengerConst.EVENT_PARAM_START_NAME] = startName
+ params[TaxiPassengerConst.EVENT_PARAM_END_NAME] = endName
+ params[TaxiPassengerConst.EVENT_PARAM_ORDER_NUMBER] = orderNo
+ params[TaxiPassengerConst.EVENT_PARAM_UNABLE_START_REASON] = reason
+ MogoAnalyticUtils.track(TaxiPassengerConst.EVENT_KEY_AP_UNABLE_START_REASON, params)
+ }
+
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/utils/ZoomDrawable.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/utils/ZoomDrawable.kt
new file mode 100644
index 0000000000..12776a6d7f
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/utils/ZoomDrawable.kt
@@ -0,0 +1,21 @@
+package com.mogo.och.taxi.passenger.utils
+
+import android.content.Context
+import android.graphics.*
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.Drawable
+import androidx.annotation.DrawableRes
+
+object ZoomDrawable {
+ fun zoomDrawableImage(context: Context,@DrawableRes id:Int,scaleX:Float,scaleY:Float):Drawable{
+
+ val bitmap: Bitmap = BitmapFactory.decodeResource(context.resources, id)
+ val bitmapWidth = bitmap.width
+ val bitmapHeight = bitmap.height
+ val matrix = Matrix()
+ matrix.postScale(scaleX, scaleY)
+ // 产生缩放后的Bitmap对象
+ val resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmapWidth, bitmapHeight, matrix, true)
+ return BitmapDrawable(context.resources,resizeBitmap)
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/ConsultVideoPlayer.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/ConsultVideoPlayer.kt
new file mode 100644
index 0000000000..170afc5e88
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/ConsultVideoPlayer.kt
@@ -0,0 +1,529 @@
+package com.mogo.och.taxi.passenger.widget
+
+import android.app.Activity
+import android.content.Context
+import android.graphics.Color
+import android.graphics.drawable.GradientDrawable
+import android.os.Build
+import android.util.AttributeSet
+import android.util.TypedValue
+import android.view.Gravity
+import android.view.Surface
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.appcompat.widget.AppCompatImageView
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.app.ActivityCompat
+import com.mogo.eagle.core.utilcode.util.TimeTransformUtils
+import com.mogo.eagle.core.utilcode.util.ToastUtils
+import com.mogo.eagle.core.widget.media.video.TextureVideoViewOutlineProvider
+import com.mogo.och.taxi.passenger.R
+import com.mogo.och.taxi.passenger.ui.statusview.StatusBarView
+import com.mogo.och.taxi.passenger.ui.video.FullVideoUtils
+import com.mogo.och.taxi.passenger.utils.ZoomDrawable
+import com.shuyu.gsyvideoplayer.listener.VideoAllCallBack
+import com.shuyu.gsyvideoplayer.utils.GSYVideoType
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer
+import com.shuyu.gsyvideoplayer.video.base.GSYVideoPlayer
+import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
+import me.jessyan.autosize.utils.AutoSizeUtils
+import java.lang.reflect.Constructor
+
+/**
+ * @author lixiaopeng
+ * @since 2021/11/3
+ *
+ * 视频播放器,ui定制
+ */
+class ConsultVideoPlayer : StandardGSYVideoPlayer {
+
+ private lateinit var start: ImageView
+ lateinit var coverImage: ImageView
+ private lateinit var currentTimeTextView: TextView
+ private lateinit var totalTimeTextView: TextView
+ private lateinit var aivStartPlay: AppCompatImageView
+ private lateinit var layoutBottom: ConstraintLayout
+ private lateinit var vPpenLeft: View
+
+ private var fullVideoPlayer:ConsultVideoPlayer?=null
+ var smalllPlayer:ConsultVideoPlayer?=null
+ private var statusBarView: StatusBarView? = null
+
+ private var currentTime = 0
+
+ constructor(context: Context?) : super(context)
+ constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
+ constructor(context: Context?, fullFlag: Boolean?) : super(context, fullFlag)
+
+ override fun init(context: Context) {
+ mEnlargeImageRes = R.drawable.taxi_p_change_full
+ super.init(context)
+ start = findViewById(R.id.start)
+ coverImage = findViewById(R.id.thumbImage)
+ currentTimeTextView = findViewById(R.id.current)
+ totalTimeTextView = findViewById(R.id.total)
+ aivStartPlay = findViewById(R.id.aiv_start_play)
+ layoutBottom = findViewById(R.id.layout_bottom)
+ vPpenLeft = findViewById(R.id.v_open_left)
+ fullscreenButton.setOnClickListener(this)
+ aivStartPlay.setOnClickListener(this)
+ if (mThumbImageViewLayout != null
+ && (mCurrentState == -1 || mCurrentState == CURRENT_STATE_NORMAL || mCurrentState == CURRENT_STATE_ERROR)
+ ) {
+ mThumbImageViewLayout.visibility = View.VISIBLE
+ }
+ GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_FULL)
+ aivStartPlay.scaleX = 0.8f
+ aivStartPlay.scaleY = 0.8f
+
+ mProgressBar.thumb = ZoomDrawable.zoomDrawableImage(context,R.drawable.bg_taxi_p_video_index,0.66f,0.66f)
+ }
+
+ private fun addDrageAnchor(){
+ vPpenLeft.visibility = VISIBLE
+ layoutBottom.post {
+ val layoutParams = layoutBottom.layoutParams as ConstraintLayout.LayoutParams
+ layoutParams.setMargins(333,0,333,90)
+ layoutParams.height = 148
+ layoutBottom.layoutParams = layoutParams
+ }
+
+ mTopContainer.post {
+ val layoutParams = mTopContainer.layoutParams as ConstraintLayout.LayoutParams
+ layoutParams.height = 320
+ mTopContainer.layoutParams = layoutParams
+ val background = layoutBottom.background as GradientDrawable
+ val x = floatArrayOf(12f, 12f,12f, 12f,12f, 12f,12f, 12f)
+ background.cornerRadii = x
+
+ layoutBottom.background = background
+
+ titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 50f)
+ val layoutParams1 = titleTextView.layoutParams as ConstraintLayout.LayoutParams
+ layoutParams1.marginStart = 80
+ titleTextView.layoutParams = layoutParams1
+ aivStartPlay.scaleX = 1f
+ aivStartPlay.scaleY = 1f
+ val drawable = ActivityCompat.getDrawable(context, R.drawable.bg_taxi_p_video_index)
+ mProgressBar.thumb = drawable
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ mProgressBar.maxHeight = 6
+ mProgressBar.minHeight = 6
+ }
+
+ val layoutParams2 = fullscreenButton.layoutParams as ConstraintLayout.LayoutParams
+ layoutParams2.topMargin = AutoSizeUtils.dp2px(context,119f)
+ layoutParams2.rightMargin = AutoSizeUtils.dp2px(context,70f)
+ layoutParams2.height = AutoSizeUtils.dp2px(context,108f)
+ layoutParams2.width = AutoSizeUtils.dp2px(context,108f)
+ fullscreenButton.layoutParams = layoutParams2
+ fullscreenButton.visibility = View.VISIBLE
+ }
+
+ }
+
+ override fun getLayoutId(): Int {
+ return R.layout.taxi_p_video_show
+ }
+
+ override fun updateStartImage() {
+ when (mCurrentState) {
+ GSYVideoView.CURRENT_STATE_PLAYING ->{
+ start.setImageResource(R.drawable.notice_video_pause)
+ aivStartPlay.visibility = View.GONE
+ }
+ else -> {
+ start.setImageResource(R.drawable.notice_video_after_pause)
+ aivStartPlay.visibility = View.VISIBLE
+ }
+ }
+ }
+
+ override fun setStateAndUi(state: Int) {
+ super.setStateAndUi(state)
+ if(state==CURRENT_STATE_PLAYING_BUFFERING_START){
+ ToastUtils.showShort("加载中请稍等")
+ }
+ }
+
+ override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
+ super.onWindowFocusChanged(hasWindowFocus)
+ if(isIfCurrentIsFullscreen&&smalllPlayer!=null){
+ if(hasWindowFocus){//获取焦点
+ //onVideoResume()
+ }else{
+ onVideoPause()
+ }
+ }
+ }
+
+ override fun touchDoubleUp() {
+
+ }
+
+ override fun changeUiToNormal() {
+ super.changeUiToNormal()
+ //setViewShowState(fullscreenButton, INVISIBLE)
+ this.statusBarView?.visibility = View.VISIBLE
+ }
+
+ override fun changeUiToPreparingShow() {
+ super.changeUiToPreparingShow()
+ this.statusBarView?.visibility = View.VISIBLE
+ }
+
+ override fun changeUiToPlayingShow() {
+ super.changeUiToPlayingShow()
+ setViewShowState(fullscreenButton, VISIBLE)
+ this.statusBarView?.visibility = View.VISIBLE
+ }
+
+ override fun changeUiToPlayingClear() {
+ super.changeUiToPlayingClear()
+ this.statusBarView?.visibility = View.GONE
+ }
+
+ override fun changeUiToPauseShow() {
+ super.changeUiToPauseShow()
+ this.statusBarView?.visibility = View.VISIBLE
+ }
+
+ override fun changeUiToPlayingBufferingShow() {
+ super.changeUiToPlayingBufferingShow()
+ this.statusBarView?.visibility = View.VISIBLE
+ }
+
+ override fun changeUiToCompleteShow() {
+ super.changeUiToCompleteShow()
+ this.statusBarView?.visibility = View.VISIBLE
+ }
+
+ public override fun hideAllWidget() {
+ super.hideAllWidget()
+ this.statusBarView?.visibility = View.GONE
+ }
+
+ override fun setProgressAndTime(
+ progress: Int,
+ secProgress: Int,
+ currentTime: Int,
+ totalTime: Int,
+ forceChange: Boolean
+ ) {
+ super.setProgressAndTime(progress, secProgress, currentTime, totalTime, forceChange)
+ //时间显示
+ currentTimeTextView.text = TimeTransformUtils.stringForTime(currentTime)
+ totalTimeTextView.text = TimeTransformUtils.stringForTime(totalTime)
+ if(currentTime>=totalTime-3000){//
+ this.currentTime = -1
+ }else{
+ this.currentTime = currentTime
+ }
+ if (progress != 0) {
+ mProgressBar?.progress = progress
+ }
+ }
+
+ override fun showWifiDialog() {
+ //直接播放,不显示WIFI对话框
+ startPlayLogic()
+ }
+
+ override fun onDetachedFromWindow() {
+ mProgressBar?.progress = 0
+ fullVideoPlayer?.let {
+ clearFullscreenLayout(it)
+ }
+ fullVideoPlayer = null
+ if(!isIfCurrentIsFullscreen) {
+ onVideoReset()
+ setVideoAllCallBack(null)
+ }
+ dismissProgressDialog()
+ super.onDetachedFromWindow()
+ }
+
+ override fun onClick(v: View?) {
+ super.onClick(v)
+ when (v?.id) {
+ R.id.fullscreen -> {
+ startWindowFullscreenOwn(context)
+// startWindowFullscreen(context)
+ }
+ R.id.aiv_start_play -> {
+ if(currentState==GSYVideoView.CURRENT_STATE_PAUSE){
+ onVideoResume(false)
+ }else{
+ if (mProgressBar==null) {
+ startPlayLogic()
+ }else {
+ mProgressBar?.let {
+ if(currentTime>0) {
+ seekOnStart = currentTime.toLong()
+ }
+ startPlayLogic()
+ }
+ }
+
+ }
+ }
+ else -> {}
+ }
+ }
+
+ override fun onCompletion() {
+ start.setImageResource(R.drawable.notice_video_after_pause)
+ }
+
+ override fun onSurfaceUpdated(surface: Surface) {
+ super.onSurfaceUpdated(surface)
+ if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
+ mThumbImageViewLayout.visibility = View.INVISIBLE
+ }
+ }
+
+ override fun onPrepared() {
+ super.onPrepared()
+ }
+
+ override fun onBufferingUpdate(percent: Int) {
+ super.onBufferingUpdate(percent)
+
+ }
+
+ override fun onError(what: Int, extra: Int) {
+ super.onError(what, extra)
+ mThumbImageViewLayout?.visibility = View.VISIBLE
+ ToastUtils.showLong("哎呀,出错了,看看其他视频吧")
+ currentTime = -1
+ if(isIfCurrentIsFullscreen){
+ smalllPlayer?.clearFullscreenLayout(this)
+ smalllPlayer?.currentTime = -1
+ FullVideoUtils.dismissOverlayView(false)
+ }
+ }
+
+ override fun setViewShowState(view: View?, visibility: Int) {
+ if (view === mThumbImageViewLayout && visibility != View.VISIBLE) {
+ return
+ }
+ super.setViewShowState(view, visibility)
+ }
+
+ override fun onSurfaceAvailable(surface: Surface) {
+ super.onSurfaceAvailable(surface)
+ if (GSYVideoType.getRenderType() != GSYVideoType.TEXTURE) {
+ if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
+ mThumbImageViewLayout.visibility = View.INVISIBLE
+ }
+ }
+ }
+
+ override fun onAutoCompletion() {
+ super.onAutoCompletion()
+ if(mIfCurrentIsFullscreen){
+ if(smalllPlayer!=null){
+ smalllPlayer?.clearFullscreenLayout(this)
+ }
+ FullVideoUtils.dismissOverlayView(false)
+ }
+ }
+
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
+ super.onSizeChanged(w, h, oldw, oldh)
+ if (!mIfCurrentIsFullscreen) {
+ this.outlineProvider = TextureVideoViewOutlineProvider(12F)
+ this.clipToOutline = true
+ }
+ }
+
+ fun exitFullScreenMode() {
+ fullVideoPlayer?.let {
+ clearFullscreenLayout(it)
+ FullVideoUtils.dismissOverlayView(false)
+ }
+ }
+
+ private fun startWindowFullscreenOwn(context:Context){
+ val gsyBaseVideoPlayer = startWindowFullscreen(context)
+ gsyBaseVideoPlayer?.let {
+ val gsyVideoPlayer = it as StandardGSYVideoPlayer
+ gsyVideoPlayer.setLockClickListener(mLockClickListener)
+ gsyVideoPlayer.isNeedLockFull = isNeedLockFull
+ initFullUI(gsyVideoPlayer)
+ }
+ }
+
+ private fun initFullUI(standardGSYVideoPlayer: StandardGSYVideoPlayer) {
+ if (mBottomProgressDrawable != null) {
+ standardGSYVideoPlayer.setBottomProgressBarDrawable(mBottomProgressDrawable)
+ }
+ if (mBottomShowProgressDrawable != null && mBottomShowProgressThumbDrawable != null) {
+ standardGSYVideoPlayer.setBottomShowProgressBarDrawable(
+ mBottomShowProgressDrawable,
+ mBottomShowProgressThumbDrawable
+ )
+ }
+ if (mVolumeProgressDrawable != null) {
+ standardGSYVideoPlayer.setDialogVolumeProgressBar(mVolumeProgressDrawable)
+ }
+ if (mDialogProgressBarDrawable != null) {
+ standardGSYVideoPlayer.setDialogProgressBar(mDialogProgressBarDrawable)
+ }
+ if (mDialogProgressHighLightColor >= 0 && mDialogProgressNormalColor >= 0) {
+ standardGSYVideoPlayer.setDialogProgressColor(
+ mDialogProgressHighLightColor,
+ mDialogProgressNormalColor
+ )
+ }
+ standardGSYVideoPlayer.titleTextView?.text = titleTextView.text
+ }
+
+ private fun startWindowFullscreen(context:Context):GSYBaseVideoPlayer?{
+ if (mTextureViewContainer.childCount > 0) {
+ mTextureViewContainer.removeAllViews()
+ }
+ var hadNewConstructor = true
+
+ //切换时关闭非全屏定时器
+ cancelProgressTimer()
+ try {
+ this@ConsultVideoPlayer.javaClass.getConstructor(
+ Context::class.java,
+ Boolean::class.java
+ )
+ } catch (e: java.lang.Exception) {
+ hadNewConstructor = false
+ }
+ try {
+ //通过被重载的不同构造器来选择
+ val constructor: Constructor
+ val gsyVideoPlayer: ConsultVideoPlayer
+ if (!hadNewConstructor) {
+ constructor = this@ConsultVideoPlayer.javaClass.getConstructor(Context::class.java)
+ gsyVideoPlayer = constructor.newInstance(mContext)
+ } else {
+ constructor = this@ConsultVideoPlayer.javaClass.getConstructor(
+ Context::class.java,
+ Boolean::class.java
+ )
+ gsyVideoPlayer = constructor.newInstance(mContext, true)
+ }
+ this.fullVideoPlayer = gsyVideoPlayer
+ gsyVideoPlayer.id = fullId
+ gsyVideoPlayer.isIfCurrentIsFullscreen = true
+ gsyVideoPlayer.setVideoAllCallBack(mVideoAllCallBack)
+ gsyVideoPlayer.addDrageAnchor()
+ cloneParams(this, gsyVideoPlayer)
+ val frameLayout = FrameLayout(context)
+ if (gsyVideoPlayer.fullscreenButton != null) {
+ gsyVideoPlayer.fullscreenButton.setImageResource(R.drawable.taxi_p_change_normal)
+ gsyVideoPlayer.fullscreenButton.setOnClickListener { v ->
+ if (mBackFromFullScreenListener == null) {
+ clearFullscreenLayout(gsyVideoPlayer)
+ FullVideoUtils.dismissOverlayView(false)
+ } else {
+ mBackFromFullScreenListener.onClick(v)
+ }
+ }
+ }
+ // 点击视频不展示状态栏
+ gsyVideoPlayer.isHideKey = false
+ gsyVideoPlayer.smalllPlayer = this
+ frameLayout.setBackgroundColor(Color.BLACK)
+ val lp = LayoutParams(width, height)
+ frameLayout.addView(gsyVideoPlayer, lp)
+ gsyVideoPlayer.statusBarView = StatusBarView(context)
+ frameLayout.addView(gsyVideoPlayer.statusBarView)
+ FullVideoUtils.showOverlayView(context as Activity,frameLayout,R.style.och_window_anim_alpha)
+ gsyVideoPlayer.visibility = INVISIBLE
+ frameLayout.visibility = INVISIBLE
+ resolveFullVideoShow(context, gsyVideoPlayer, frameLayout)
+ gsyVideoPlayer.addTextureView()
+ gsyVideoPlayer.startProgressTimer()
+ gsyVideoManager.setLastListener(this)
+ gsyVideoManager.setListener(gsyVideoPlayer)
+ checkoutState()
+ thumbImageViewLayout.visibility = View.VISIBLE
+ return gsyVideoPlayer
+ } catch (e: java.lang.Exception) {
+ e.printStackTrace()
+ }
+
+ return null
+ }
+
+ /**
+ * 全屏
+ */
+ override fun resolveFullVideoShow(context: Context?, gsyVideoPlayer: GSYBaseVideoPlayer,
+ frameLayout: FrameLayout) {
+ val lp = gsyVideoPlayer.layoutParams as LayoutParams
+ lp.setMargins(0, 0, 0, 0)
+ lp.height = ViewGroup.LayoutParams.WRAP_CONTENT
+ lp.width = ViewGroup.LayoutParams.MATCH_PARENT
+ lp.gravity = Gravity.BOTTOM
+ gsyVideoPlayer.layoutParams = lp
+ gsyVideoPlayer.isIfCurrentIsFullscreen = true
+ val isVertical = isVerticalFullByVideoSize
+ val isLockLand = isLockLandByAutoFullSize
+ if (isShowFullAnimation) {
+ mInnerHandler.postDelayed({ //autoFull模式下,非横屏视频视频不横屏,并且不自动旋转
+ if (!isVertical && isLockLand && mOrientationUtils != null && mOrientationUtils.isLand != 1) {
+ mOrientationUtils.resolveByClick()
+ }
+ gsyVideoPlayer.visibility = VISIBLE
+ frameLayout.visibility = VISIBLE
+ }, 300)
+ } else {
+ if (!isVertical && isLockLand && mOrientationUtils != null) {
+ mOrientationUtils.resolveByClick()
+ }
+ gsyVideoPlayer.visibility = VISIBLE
+ frameLayout.visibility = VISIBLE
+ }
+ if (mVideoAllCallBack != null) {
+ mVideoAllCallBack.onEnterFullscreen(mOriginUrl, mTitle, gsyVideoPlayer)
+ }
+ mIfCurrentIsFullscreen = true
+ checkoutState()
+ checkAutoFullWithSizeAndAdaptation(gsyVideoPlayer)
+ }
+
+ fun clearFullscreenLayout(gsyVideoPlayer:ConsultVideoPlayer) {
+ if (mIfCurrentIsFullscreen) {
+ mIfCurrentIsFullscreen = false
+ val delay = 100
+ gsyVideoPlayer.smalllPlayer = null
+ mInnerHandler.postDelayed({ resolveNormalVideoShow(gsyVideoPlayer) }, delay.toLong())
+ }
+ }
+
+ private fun resolveNormalVideoShow(gsyVideoPlayer: GSYVideoPlayer) {
+ mCurrentState = gsyVideoManager.lastState
+ cloneParams(gsyVideoPlayer, this)
+ gsyVideoManager.setListener(gsyVideoManager.lastListener())
+ gsyVideoManager.setLastListener(null)
+ gsyVideoPlayer.setVideoAllCallBack(null)
+ setStateAndUi(mCurrentState)
+ addTextureView()
+ mSaveChangeViewTIme = System.currentTimeMillis()
+ if (mVideoAllCallBack != null) {
+ mVideoAllCallBack.onQuitFullscreen(mOriginUrl, mTitle, this)
+ }
+ mIfCurrentIsFullscreen = false
+ if (fullscreenButton != null) {
+ fullscreenButton.setImageResource(enlargeImageRes)
+ }
+ this.fullVideoPlayer = null
+ }
+
+ fun getVideoAllCallBack(): VideoAllCallBack? {
+ return mVideoAllCallBack
+ }
+}
+
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/WindowRelativeLayout.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/WindowRelativeLayout.kt
new file mode 100644
index 0000000000..31313e52f7
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/WindowRelativeLayout.kt
@@ -0,0 +1,30 @@
+package com.mogo.och.taxi.passenger.widget
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.RelativeLayout
+import androidx.lifecycle.ViewModelStore
+import androidx.lifecycle.ViewModelStoreOwner
+
+open class WindowRelativeLayout: RelativeLayout, ViewModelStoreOwner {
+
+ constructor(context: Context?) : super(context)
+
+ constructor(context: Context?, attributeSet: AttributeSet) : super(context, attributeSet)
+
+ constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
+
+ constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
+
+ //定义ViewModelStore变量
+ private var mViewModelStore: ViewModelStore = ViewModelStore()
+
+ override fun getViewModelStore(): ViewModelStore {
+ return mViewModelStore
+ }
+
+ override fun onDetachedFromWindow() {
+ super.onDetachedFromWindow()
+ mViewModelStore.clear()
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/animutils/AnimationsContainer.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/animutils/AnimationsContainer.kt
new file mode 100644
index 0000000000..eab32ba7d0
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/animutils/AnimationsContainer.kt
@@ -0,0 +1,146 @@
+package com.mogo.och.taxi.passenger.widget.animutils
+
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.graphics.drawable.BitmapDrawable
+import android.os.Handler
+import android.os.Looper
+import android.widget.ImageView
+import com.mogo.commons.AbsMogoApplication
+import java.lang.ref.SoftReference
+
+class AnimationsContainer(resId: Int, fps: Int, imageView: ImageView) {
+ private lateinit var mFrames: IntArray // 帧数组
+ private var mIndex = 0 // 当前帧
+ private var mShouldRun = false // 开始/停止播放用
+ private var mIsRunning = false // 动画是否正在播放,防止重复播放
+ private var mSoftReferenceImageView: SoftReference? = null // 软引用ImageView,以便及时释放掉
+ private var mHandler: Handler? = null
+ private var mDelayMillis = 0
+ private var mOnAnimationStoppedListener: OnAnimationStoppedListener? = null//播放停止监听
+ private var mBitmap: Bitmap? = null
+ private var mBitmapOptions: BitmapFactory.Options? = null //Bitmap管理类,可有效减少Bitmap的OOM问题
+
+ init {
+ createAnimation(imageView, getData(resId), fps)
+ }
+
+ private fun createAnimation(imageView: ImageView, frames: IntArray, fps: Int) {
+ mHandler = Handler(Looper.myLooper()!!)
+ mFrames = frames
+ mIndex = -1
+ mSoftReferenceImageView = SoftReference(imageView)
+ mShouldRun = false
+ mIsRunning = false
+ mDelayMillis = 1000 / fps //帧动画时间间隔,毫秒
+ imageView.setImageResource(mFrames[0])
+
+ // 当图片大小类型相同时进行复用,避免频繁GC
+ val bmp = (imageView.drawable as BitmapDrawable).bitmap
+ val width = bmp.width
+ val height = bmp.height
+ val config = bmp.config
+ mBitmap = Bitmap.createBitmap(width, height, config)
+ mBitmapOptions = BitmapFactory.Options()
+ //设置Bitmap内存复用
+ mBitmapOptions!!.inBitmap = mBitmap //Bitmap复用内存块,类似对象池,避免不必要的内存分配和回收
+ mBitmapOptions!!.inMutable = true //解码时返回可变Bitmap
+ mBitmapOptions!!.inSampleSize = 1 //缩放比例
+ }
+
+ //循环读取下一帧
+ private val next: Int
+ get() {
+ mIndex++
+ if (mIndex >= mFrames.size) mIndex = 0
+ return mFrames[mIndex]
+ }
+
+ /**
+ * 播放动画,同步锁防止多线程读帧时,数据安全问题
+ */
+ @Synchronized
+ fun start() {
+ mShouldRun = true
+ if (mIsRunning) return
+ val runnable: Runnable = object : Runnable {
+ override fun run() {
+ val imageView = mSoftReferenceImageView!!.get()
+ if (!mShouldRun || imageView == null) {
+ mIsRunning = false
+ if (mOnAnimationStoppedListener != null) {
+ mOnAnimationStoppedListener!!.AnimationStopped()
+ }
+ return
+ }
+ mIsRunning = true
+ //新开线程去读下一帧
+ mHandler!!.postDelayed(this, mDelayMillis.toLong())
+ if (imageView.isShown) {
+ val imageRes: Int = next
+ if (mBitmap != null) { // so Build.VERSION.SDK_INT >= 11
+ var bitmap: Bitmap? = null
+ try {
+ bitmap = BitmapFactory.decodeResource(
+ imageView.resources,
+ imageRes,
+ mBitmapOptions
+ )
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ if (bitmap != null) {
+ imageView.setImageBitmap(bitmap)
+ } else {
+ imageView.setImageResource(imageRes)
+ mBitmap!!.recycle()
+ mBitmap = null
+ }
+ } else {
+ imageView.setImageResource(imageRes)
+ }
+ }
+ }
+ }
+ mHandler!!.post(runnable)
+ }
+
+ /**
+ * 停止播放
+ */
+ @Synchronized
+ fun stop() {
+ mShouldRun = false
+ }
+
+ /**
+ * 设置停止播放监听
+ * @param listener 设置监听
+ */
+ fun setOnAnimStopListener(listener: OnAnimationStoppedListener?) {
+ mOnAnimationStoppedListener = listener
+ }
+
+ /**
+ * 从xml中读取帧数组
+ * @param resId
+ * @return
+ */
+ private fun getData(resId: Int): IntArray {
+ val array = AbsMogoApplication.getApp().resources.obtainTypedArray(resId)
+ val len = array.length()
+ val intArray = IntArray(array.length())
+ for (i in 0 until len) {
+ intArray[i] = array.getResourceId(i, 0)
+ }
+ array.recycle()
+ return intArray
+ }
+
+ /**
+ * 停止播放监听
+ */
+ interface OnAnimationStoppedListener {
+ fun AnimationStopped()
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/IndicatorView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/IndicatorView.kt
new file mode 100644
index 0000000000..efaf362a21
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/IndicatorView.kt
@@ -0,0 +1,68 @@
+package com.mogo.och.taxi.passenger.widget.indicator
+
+import android.content.Context
+import android.graphics.Canvas
+import android.util.AttributeSet
+import com.mogo.och.taxi.passenger.widget.indicator.annotation.AIndicatorOrientation
+
+import com.zhpan.indicator.base.BaseIndicatorView
+import com.mogo.och.taxi.passenger.widget.indicator.drawer.DrawerProxy
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorOrientation
+import com.mogo.och.taxi.passenger.widget.indicator.option.AttrsController
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+class IndicatorView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : BaseIndicatorView(context, attrs, defStyleAttr) {
+
+ private var mDrawerProxy: DrawerProxy
+
+ init {
+ AttrsController.initAttrs(context, attrs, mIndicatorOptions)
+ mDrawerProxy = DrawerProxy(mIndicatorOptions)
+ }
+
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+ super.onLayout(changed, left, top, right, bottom)
+ mDrawerProxy.onLayout(changed, left, top, right, bottom)
+ }
+
+ override fun onMeasure(
+ widthMeasureSpec: Int,
+ heightMeasureSpec: Int
+ ) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+ val measureResult = mDrawerProxy.onMeasure(widthMeasureSpec, heightMeasureSpec)
+ setMeasuredDimension(measureResult.measureWidth, measureResult.measureHeight)
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ super.onDraw(canvas)
+ rotateCanvas(canvas)
+ mDrawerProxy.onDraw(canvas)
+ }
+
+ override fun setIndicatorOptions(options: IndicatorOptions) {
+ super.setIndicatorOptions(options)
+ mDrawerProxy.setIndicatorOptions(options)
+ }
+
+ override fun notifyDataChanged(itemCount:Int) {
+ mDrawerProxy = DrawerProxy(mIndicatorOptions)
+ super.notifyDataChanged(itemCount)
+ }
+
+ private fun rotateCanvas(canvas: Canvas) {
+ if (mIndicatorOptions.orientation == IndicatorOrientation.INDICATOR_VERTICAL) {
+ canvas.rotate(90f, width / 2f, width / 2f)
+ } else if (mIndicatorOptions.orientation == IndicatorOrientation.INDICATOR_RTL) {
+ canvas.rotate(180f, width / 2f, height / 2f)
+ }
+ }
+
+ fun setOrientation(@AIndicatorOrientation orientation: Int) {
+ mIndicatorOptions.orientation = orientation
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorOrientation.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorOrientation.kt
new file mode 100644
index 0000000000..4e3ff14f56
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorOrientation.kt
@@ -0,0 +1,17 @@
+package com.mogo.och.taxi.passenger.widget.indicator.annotation
+
+import androidx.annotation.IntDef
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorOrientation
+
+/**
+ *
+ * @author zhangpan
+ * @date 2021/1/21
+ */
+@IntDef(
+ IndicatorOrientation.INDICATOR_HORIZONTAL, IndicatorOrientation.INDICATOR_VERTICAL,
+ IndicatorOrientation.INDICATOR_RTL
+)
+@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
+@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD)
+annotation class AIndicatorOrientation()
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorSlideMode.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorSlideMode.kt
new file mode 100644
index 0000000000..2497e29f01
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorSlideMode.kt
@@ -0,0 +1,19 @@
+package com.mogo.och.taxi.passenger.widget.indicator.annotation
+
+import androidx.annotation.IntDef
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode.Companion.COLOR
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode.Companion.NORMAL
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode.Companion.SCALE
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode.Companion.SMOOTH
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode.Companion.WORM
+
+/**
+ *
+ * Created by zhangpan on 2019-10-18.
+ * Description:
+
*
+ */
+@IntDef(NORMAL, SMOOTH, WORM, COLOR, SCALE)
+@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
+@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD)
+annotation class AIndicatorSlideMode
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorStyle.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorStyle.kt
new file mode 100644
index 0000000000..783524aa97
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/annotation/AIndicatorStyle.kt
@@ -0,0 +1,15 @@
+package com.mogo.och.taxi.passenger.widget.indicator.annotation
+
+import androidx.annotation.IntDef
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorStyle
+
+/**
+ *
+ * Created by zhangpan on 2019-10-18.
+ * Description:
+
*
+ */
+@IntDef(IndicatorStyle.CIRCLE, IndicatorStyle.DASH, IndicatorStyle.ROUND_RECT)
+@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
+@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD)
+annotation class AIndicatorStyle
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/base/BaseIndicatorView.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/base/BaseIndicatorView.kt
new file mode 100644
index 0000000000..a24f8d08a7
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/base/BaseIndicatorView.kt
@@ -0,0 +1,205 @@
+package com.zhpan.indicator.base
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+
+import androidx.annotation.ColorInt
+import androidx.recyclerview.widget.RecyclerView
+
+import com.mogo.och.taxi.passenger.widget.indicator.annotation.AIndicatorSlideMode
+import com.mogo.och.taxi.passenger.widget.indicator.annotation.AIndicatorStyle
+import com.mogo.och.taxi.passenger.widget.indicator.base.IIndicator
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+/**
+ *
+ * Created by zhangpan on 2019-09-04.
+ * Description:IndicatorView基类,处理了页面滑动。
+ *
+ */
+@Suppress("UNUSED")
+open class BaseIndicatorView constructor(
+ context: Context,
+ attrs: AttributeSet?,
+ defStyleAttr: Int
+) : View(context, attrs, defStyleAttr), IIndicator {
+
+ var mIndicatorOptions: IndicatorOptions
+
+ private var recyclerView: RecyclerView? = null
+
+ init {
+ mIndicatorOptions = IndicatorOptions()
+ }
+
+ fun setPageSize(pageSize: Int): BaseIndicatorView {
+ mIndicatorOptions.pageSize = pageSize
+ return this
+ }
+
+ // 页面选定
+ fun onPageSelected(position: Int) {
+ if (getSlideMode() == IndicatorSlideMode.NORMAL) {
+ setCurrentPosition(position)
+ setSlideProgress(0f)
+ invalidate()
+ }
+ }
+
+ // 滚动距离
+ fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
+ if (getSlideMode() != IndicatorSlideMode.NORMAL && getPageSize() > 1) {
+ scrollSlider(position, positionOffset)
+ invalidate()
+ }
+ }
+
+ private fun scrollSlider(position: Int, positionOffset: Float) {
+ if (mIndicatorOptions.slideMode == IndicatorSlideMode.SCALE
+ || mIndicatorOptions.slideMode == IndicatorSlideMode.COLOR) {
+ setCurrentPosition(position)
+ setSlideProgress(positionOffset)
+ } else {
+ if (position % getPageSize() == getPageSize() - 1) { // 最后一个页面与第一个页面
+ if (positionOffset < 0.5) {
+ setCurrentPosition(position)
+ setSlideProgress(0f)
+ } else {
+ setCurrentPosition(0)
+ setSlideProgress(0f)
+ }
+ } else { // 中间页面
+ setCurrentPosition(position)
+ setSlideProgress(positionOffset)
+ }
+ }
+ }
+
+ override fun notifyDataChanged(itemCount: Int) {
+ setPageSize(itemCount)
+ requestLayout()
+ invalidate()
+ }
+
+ private fun setupViewPager() {
+
+ }
+
+ fun getNormalSlideWidth(): Float {
+ return mIndicatorOptions.normalSliderWidth
+ }
+
+ fun setNormalSlideWidth(normalSliderWidth: Float) {
+ mIndicatorOptions.normalSliderWidth = normalSliderWidth
+ }
+
+ fun getCheckedSlideWidth(): Float {
+ return mIndicatorOptions.checkedSliderWidth
+ }
+
+ fun setCheckedSlideWidth(checkedSliderWidth: Float) {
+ mIndicatorOptions.checkedSliderWidth = checkedSliderWidth
+ }
+
+ val checkedSliderWidth: Float
+ get() = mIndicatorOptions.checkedSliderWidth
+
+ fun setCurrentPosition(currentPosition: Int) {
+ mIndicatorOptions.currentPosition = currentPosition
+ }
+
+ fun getCurrentPosition(): Int {
+ return mIndicatorOptions.currentPosition
+ }
+
+ fun getIndicatorGap(indicatorGap: Float) {
+ mIndicatorOptions.sliderGap = indicatorGap
+ }
+
+ fun setIndicatorGap(indicatorGap: Float) {
+ mIndicatorOptions.sliderGap = indicatorGap
+ }
+
+ fun setCheckedColor(@ColorInt normalColor: Int) {
+ mIndicatorOptions.checkedSliderColor = normalColor
+ }
+
+ fun getCheckedColor(): Int {
+ return mIndicatorOptions.checkedSliderColor
+ }
+
+ fun setNormalColor(@ColorInt normalColor: Int) {
+ mIndicatorOptions.normalSliderColor = normalColor
+ }
+
+ fun getSlideProgress(): Float {
+ return mIndicatorOptions.slideProgress
+ }
+
+ fun setSlideProgress(slideProgress: Float) {
+ mIndicatorOptions.slideProgress = slideProgress
+ }
+
+ fun getPageSize(): Int {
+ return mIndicatorOptions.pageSize
+ }
+
+ fun setSliderColor(
+ @ColorInt normalColor: Int,
+ @ColorInt selectedColor: Int,
+ @ColorInt selectedEndColor: Int
+ ): BaseIndicatorView {
+ mIndicatorOptions.setSliderColor(normalColor, selectedColor,selectedEndColor)
+ return this
+ }
+
+ fun setSliderWidth(sliderWidth: Float): BaseIndicatorView {
+ mIndicatorOptions.setSliderWidth(sliderWidth)
+ return this
+ }
+
+ fun setSliderWidth(
+ normalSliderWidth: Float,
+ selectedSliderWidth: Float
+ ): BaseIndicatorView {
+ mIndicatorOptions.setSliderWidth(normalSliderWidth, selectedSliderWidth)
+ return this
+ }
+
+ fun setSliderGap(sliderGap: Float): BaseIndicatorView {
+ mIndicatorOptions.sliderGap = sliderGap
+ return this
+ }
+
+ fun getSlideMode(): Int {
+ return mIndicatorOptions.slideMode
+ }
+
+ fun setSlideMode(@AIndicatorSlideMode slideMode: Int): BaseIndicatorView {
+ mIndicatorOptions.slideMode = slideMode
+ return this
+ }
+
+ fun setIndicatorStyle(@AIndicatorStyle indicatorStyle: Int): BaseIndicatorView {
+ mIndicatorOptions.indicatorStyle = indicatorStyle
+ return this
+ }
+
+ fun setSliderHeight(sliderHeight: Float): BaseIndicatorView {
+ mIndicatorOptions.sliderHeight = sliderHeight
+ return this
+ }
+
+ fun showIndicatorWhenOneItem(showIndicatorWhenOneItem: Boolean) {
+ mIndicatorOptions.showIndicatorOneItem = showIndicatorWhenOneItem
+ }
+
+ fun onPageScrollStateChanged(state: Int) {
+ }
+
+ override fun setIndicatorOptions(options: IndicatorOptions) {
+ mIndicatorOptions = options
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/base/IIndicator.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/base/IIndicator.kt
new file mode 100644
index 0000000000..817e798893
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/base/IIndicator.kt
@@ -0,0 +1,16 @@
+package com.mogo.och.taxi.passenger.widget.indicator.base
+
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+/**
+ *
+ * Created by zhangpan on 2019-09-02.
+ * Description:
+
*
+ */
+interface IIndicator {
+
+ fun notifyDataChanged(itemCount:Int)
+
+ fun setIndicatorOptions(options: IndicatorOptions)
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/BaseDrawer.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/BaseDrawer.kt
new file mode 100644
index 0000000000..ae1e7a520b
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/BaseDrawer.kt
@@ -0,0 +1,94 @@
+package com.mogo.och.taxi.passenger.widget.indicator.drawer
+
+import android.animation.ArgbEvaluator
+import android.graphics.Paint
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorOrientation
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode
+
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+/**
+ *
+ * Created by zhpan on 2019/11/23.
+ * Description:
+
*
+ */
+abstract class BaseDrawer internal constructor(internal var mIndicatorOptions: IndicatorOptions) :
+ IDrawer {
+
+ private val mMeasureResult: MeasureResult
+ internal var maxWidth: Float = 0.toFloat()
+ internal var minWidth: Float = 0.toFloat()
+ internal var mPaint: Paint = Paint()
+ internal var argbEvaluator: ArgbEvaluator? = null
+
+ companion object {
+ const val INDICATOR_PADDING_ADDITION = 6
+ const val INDICATOR_PADDING = 3
+ }
+
+ protected val isWidthEquals: Boolean
+ get() = mIndicatorOptions.normalSliderWidth == mIndicatorOptions.checkedSliderWidth
+
+ init {
+ mPaint.isAntiAlias = true
+ mMeasureResult = MeasureResult()
+ if (mIndicatorOptions.slideMode == IndicatorSlideMode.SCALE
+ || mIndicatorOptions.slideMode == IndicatorSlideMode.COLOR
+ ) {
+ argbEvaluator = ArgbEvaluator()
+ }
+ }
+
+ override fun onMeasure(
+ widthMeasureSpec: Int,
+ heightMeasureSpec: Int
+ ): MeasureResult {
+ maxWidth =
+ mIndicatorOptions.normalSliderWidth.coerceAtLeast(mIndicatorOptions.checkedSliderWidth)
+ minWidth =
+ mIndicatorOptions.normalSliderWidth.coerceAtMost(mIndicatorOptions.checkedSliderWidth)
+ if (mIndicatorOptions.orientation == IndicatorOrientation.INDICATOR_VERTICAL) {
+ mMeasureResult.setMeasureResult(measureHeight(), measureWidth())
+ } else {
+ mMeasureResult.setMeasureResult(measureWidth(), measureHeight())
+ }
+ return mMeasureResult
+ }
+
+ protected open fun measureHeight(): Int {
+ return mIndicatorOptions.sliderHeight.toInt() + INDICATOR_PADDING
+ }
+
+ private fun measureWidth(): Int {
+ val pageSize = mIndicatorOptions.pageSize
+ val indicatorGap = mIndicatorOptions.sliderGap
+ return ((pageSize - 1) * indicatorGap + maxWidth + (pageSize - 1) * minWidth).toInt() + INDICATOR_PADDING_ADDITION
+ }
+
+ override fun onLayout(
+ changed: Boolean,
+ left: Int,
+ top: Int,
+ right: Int,
+ bottom: Int
+ ) {
+ }
+
+ inner class MeasureResult {
+
+ var measureWidth: Int = 0
+ internal set
+
+ var measureHeight: Int = 0
+ internal set
+
+ internal fun setMeasureResult(
+ measureWidth: Int,
+ measureHeight: Int
+ ) {
+ this.measureWidth = measureWidth
+ this.measureHeight = measureHeight
+ }
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/CircleDrawer.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/CircleDrawer.kt
new file mode 100644
index 0000000000..f7bde7a9ff
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/CircleDrawer.kt
@@ -0,0 +1,157 @@
+package com.mogo.och.taxi.passenger.widget.indicator.drawer
+
+import android.graphics.Canvas
+import android.graphics.RectF
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode
+
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+import com.mogo.och.taxi.passenger.widget.indicator.utils.IndicatorUtils
+
+/**
+ *
+ * Created by zhpan on 2019/11/23.
+ * Description: Circle Indicator drawer.
+
*
+ */
+class CircleDrawer internal constructor(indicatorOptions: IndicatorOptions) : BaseDrawer(
+ indicatorOptions
+) {
+
+ private val rectF = RectF()
+
+ override fun measureHeight(): Int {
+ return maxWidth.toInt() + INDICATOR_PADDING_ADDITION
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ val pageSize = mIndicatorOptions.pageSize
+ if (pageSize > 1 || mIndicatorOptions.showIndicatorOneItem && pageSize == 1) {
+ drawNormal(canvas)
+ drawSlider(canvas)
+ }
+ }
+
+ private fun drawNormal(canvas: Canvas) {
+ val normalIndicatorWidth = mIndicatorOptions.normalSliderWidth
+ mPaint.color = mIndicatorOptions.normalSliderColor
+ for (i in 0 until mIndicatorOptions.pageSize) {
+ val coordinateX = IndicatorUtils.getCoordinateX(mIndicatorOptions, maxWidth, i)
+ val coordinateY = IndicatorUtils.getCoordinateY(maxWidth)
+ drawCircle(canvas, coordinateX, coordinateY, normalIndicatorWidth / 2)
+ }
+ }
+
+ private fun drawSlider(canvas: Canvas) {
+ mPaint.color = mIndicatorOptions.checkedSliderColor
+ when (mIndicatorOptions.slideMode) {
+ IndicatorSlideMode.NORMAL, IndicatorSlideMode.SMOOTH -> drawCircleSlider(canvas)
+ IndicatorSlideMode.WORM -> drawWormSlider(canvas)
+ IndicatorSlideMode.SCALE -> drawScaleSlider(canvas)
+ IndicatorSlideMode.COLOR -> drawColor(canvas)
+ }
+ }
+
+ private fun drawColor(canvas: Canvas) {
+ val currentPosition = mIndicatorOptions.currentPosition
+ val slideProgress = mIndicatorOptions.slideProgress
+ val coordinateX = IndicatorUtils.getCoordinateX(mIndicatorOptions, maxWidth, currentPosition)
+ val coordinateY = IndicatorUtils.getCoordinateY(maxWidth)
+ var evaluate = argbEvaluator?.evaluate(
+ slideProgress, mIndicatorOptions.checkedSliderColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = (evaluate as Int)
+ drawCircle(canvas, coordinateX, coordinateY, mIndicatorOptions.normalSliderWidth / 2)
+
+ // 绘制可循环的ViewPager指示器渐变
+ evaluate = argbEvaluator?.evaluate(
+ 1 - slideProgress, mIndicatorOptions.checkedSliderColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = evaluate as Int
+ val nextCoordinateX = if (currentPosition == mIndicatorOptions.pageSize - 1) {
+ IndicatorUtils.getCoordinateX(mIndicatorOptions, maxWidth, 0)
+ } else {
+ coordinateX + mIndicatorOptions.sliderGap + mIndicatorOptions.normalSliderWidth
+ }
+ drawCircle(canvas, nextCoordinateX, coordinateY, mIndicatorOptions.checkedSliderWidth / 2)
+ }
+
+ private fun drawScaleSlider(canvas: Canvas) {
+ val currentPosition = mIndicatorOptions.currentPosition
+ val slideProgress = mIndicatorOptions.slideProgress
+ val coordinateX = IndicatorUtils.getCoordinateX(mIndicatorOptions, maxWidth, currentPosition)
+ val coordinateY = IndicatorUtils.getCoordinateY(maxWidth)
+ if (slideProgress < 1) {
+ val evaluate = argbEvaluator?.evaluate(
+ slideProgress, mIndicatorOptions.checkedSliderColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = (evaluate as Int)
+ val radius =
+ mIndicatorOptions.checkedSliderWidth / 2 - (mIndicatorOptions.checkedSliderWidth / 2 - mIndicatorOptions.normalSliderWidth / 2) * slideProgress
+ drawCircle(canvas, coordinateX, coordinateY, radius)
+ }
+
+ if (currentPosition == mIndicatorOptions.pageSize - 1) {
+ val evaluate = argbEvaluator?.evaluate(
+ slideProgress, mIndicatorOptions.normalSliderColor, mIndicatorOptions.checkedSliderColor
+ )
+ mPaint.color = evaluate as Int
+ val nextCoordinateX = maxWidth / 2
+ val nextRadius = minWidth / 2 + (maxWidth / 2 - minWidth / 2) * (slideProgress)
+ drawCircle(canvas, nextCoordinateX, coordinateY, nextRadius)
+ } else {
+ if (slideProgress > 0) {
+ val evaluate = argbEvaluator?.evaluate(
+ slideProgress, mIndicatorOptions.normalSliderColor, mIndicatorOptions.checkedSliderColor
+ )
+ mPaint.color = evaluate as Int
+ val nextCoordinateX =
+ coordinateX + mIndicatorOptions.sliderGap + mIndicatorOptions.normalSliderWidth
+ val nextRadius =
+ mIndicatorOptions.normalSliderWidth / 2 + (mIndicatorOptions.checkedSliderWidth / 2 - mIndicatorOptions.normalSliderWidth / 2) * slideProgress
+ drawCircle(canvas, nextCoordinateX, coordinateY, nextRadius)
+ }
+ }
+ }
+
+ private fun drawCircleSlider(canvas: Canvas) {
+ val currentPosition = mIndicatorOptions.currentPosition
+ val startCoordinateX =
+ IndicatorUtils.getCoordinateX(mIndicatorOptions, maxWidth, currentPosition)
+ val endCoordinateX = IndicatorUtils.getCoordinateX(
+ mIndicatorOptions, maxWidth, (currentPosition + 1) % mIndicatorOptions.pageSize
+ )
+ val coordinateX =
+ startCoordinateX + (endCoordinateX - startCoordinateX) * mIndicatorOptions.slideProgress
+ val coordinateY = IndicatorUtils.getCoordinateY(maxWidth)
+ val radius = mIndicatorOptions.checkedSliderWidth / 2
+ drawCircle(canvas, coordinateX, coordinateY, radius)
+ }
+
+ private fun drawWormSlider(canvas: Canvas) {
+ val sliderHeight = mIndicatorOptions.normalSliderWidth
+ val slideProgress = mIndicatorOptions.slideProgress
+ val currentPosition = mIndicatorOptions.currentPosition
+ val distance = mIndicatorOptions.sliderGap + mIndicatorOptions.normalSliderWidth
+ val startCoordinateX =
+ IndicatorUtils.getCoordinateX(mIndicatorOptions, maxWidth, currentPosition)
+ val left = startCoordinateX + (distance * (slideProgress - 0.5f) * 2.0f).coerceAtLeast(
+ 0f
+ ) - mIndicatorOptions.normalSliderWidth / 2 + INDICATOR_PADDING
+ val right = startCoordinateX + (distance * slideProgress * 2f).coerceAtMost(
+ distance
+ ) + mIndicatorOptions.normalSliderWidth / 2 + INDICATOR_PADDING
+ rectF.set(left, INDICATOR_PADDING.toFloat(), right, sliderHeight + INDICATOR_PADDING)
+ canvas.drawRoundRect(rectF, sliderHeight, sliderHeight, mPaint)
+ }
+
+ private fun drawCircle(
+ canvas: Canvas,
+ coordinateX: Float,
+ coordinateY: Float,
+ radius: Float
+ ) {
+ canvas.drawCircle(
+ coordinateX + INDICATOR_PADDING, coordinateY + INDICATOR_PADDING, radius, mPaint
+ )
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DashDrawer.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DashDrawer.kt
new file mode 100644
index 0000000000..6b2b7e12d1
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DashDrawer.kt
@@ -0,0 +1,20 @@
+package com.mogo.och.taxi.passenger.widget.indicator.drawer
+
+import android.graphics.Canvas
+
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+/**
+ *
+ * Created by zhpan on 2019/11/23.
+ * Description: Dash Indicator Drawer.
+
*
+ */
+class DashDrawer internal constructor(indicatorOptions: IndicatorOptions) : RectDrawer(
+ indicatorOptions
+) {
+
+ override fun drawDash(canvas: Canvas) {
+ canvas.drawRect(mRectF, mPaint)
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DrawerFactory.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DrawerFactory.kt
new file mode 100644
index 0000000000..2b5073a6b2
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DrawerFactory.kt
@@ -0,0 +1,20 @@
+package com.mogo.och.taxi.passenger.widget.indicator.drawer
+
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorStyle
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+/**
+ *
+ * Created by zhpan on 2019/11/24.
+ * Description: Indicator Drawer Factory.
+
*
+ */
+internal object DrawerFactory {
+ fun createDrawer(indicatorOptions: IndicatorOptions): IDrawer {
+ return when (indicatorOptions.indicatorStyle) {
+ IndicatorStyle.DASH -> DashDrawer(indicatorOptions)
+ IndicatorStyle.ROUND_RECT -> RoundRectDrawer(indicatorOptions)
+ else -> CircleDrawer(indicatorOptions)
+ }
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DrawerProxy.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DrawerProxy.kt
new file mode 100644
index 0000000000..30cb21e2ec
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/DrawerProxy.kt
@@ -0,0 +1,48 @@
+package com.mogo.och.taxi.passenger.widget.indicator.drawer
+
+import android.graphics.Canvas
+
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+/**
+ *
+ * Created by zhpan on 2019/11/23.
+ * Description: Indicator Drawer Proxy.
+
*
+ */
+class DrawerProxy(indicatorOptions: IndicatorOptions) : IDrawer {
+
+ private lateinit var mIDrawer: IDrawer
+
+ init {
+ init(indicatorOptions)
+ }
+
+ private fun init(indicatorOptions: IndicatorOptions) {
+ mIDrawer = DrawerFactory.createDrawer(indicatorOptions)
+ }
+
+ override fun onLayout(
+ changed: Boolean,
+ left: Int,
+ top: Int,
+ right: Int,
+ bottom: Int
+ ) {
+ }
+
+ override fun onMeasure(
+ widthMeasureSpec: Int,
+ heightMeasureSpec: Int
+ ): BaseDrawer.MeasureResult {
+ return mIDrawer.onMeasure(widthMeasureSpec, heightMeasureSpec)
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ mIDrawer.onDraw(canvas)
+ }
+
+ fun setIndicatorOptions(indicatorOptions: IndicatorOptions) {
+ init(indicatorOptions)
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/IDrawer.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/IDrawer.kt
new file mode 100644
index 0000000000..728fa254dd
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/IDrawer.kt
@@ -0,0 +1,27 @@
+package com.mogo.och.taxi.passenger.widget.indicator.drawer
+
+import android.graphics.Canvas
+
+/**
+ *
+ * Created by zhpan on 2019/11/23.
+ * Description:
+
*
+ */
+interface IDrawer {
+
+ fun onLayout(
+ changed: Boolean,
+ left: Int,
+ top: Int,
+ right: Int,
+ bottom: Int
+ )
+
+ fun onMeasure(
+ widthMeasureSpec: Int,
+ heightMeasureSpec: Int
+ ): BaseDrawer.MeasureResult
+
+ fun onDraw(canvas: Canvas)
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/RectDrawer.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/RectDrawer.kt
new file mode 100644
index 0000000000..a0d1367e84
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/RectDrawer.kt
@@ -0,0 +1,220 @@
+package com.mogo.och.taxi.passenger.widget.indicator.drawer
+
+import android.graphics.*
+
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+import com.mogo.och.taxi.passenger.widget.indicator.utils.IndicatorUtils
+
+/**
+ *
+ * Created by zhpan on 2020/1/17.
+ * Description:
+
*
+ */
+open class RectDrawer internal constructor(indicatorOptions: IndicatorOptions) : BaseDrawer(
+ indicatorOptions
+) {
+ internal var mRectF: RectF = RectF()
+
+ override fun onDraw(canvas: Canvas) {
+ val pageSize = mIndicatorOptions.pageSize
+ if (pageSize > 1 || mIndicatorOptions.showIndicatorOneItem && pageSize == 1) {
+ if (isWidthEquals && mIndicatorOptions.slideMode != IndicatorSlideMode.NORMAL) {
+ drawUncheckedSlider(canvas, pageSize)
+ drawCheckedSlider(canvas)
+ } else { // 单独处理normalWidth与checkedWidth不一致的情况
+ if (mIndicatorOptions.slideMode == IndicatorSlideMode.SCALE) {
+ for (i in 0 until pageSize) {
+ drawScaleSlider(canvas, i)
+ }
+ } else {
+ drawInequalitySlider(canvas, pageSize)
+ }
+ }
+ }
+ }
+
+ private fun drawScaleSlider(
+ canvas: Canvas,
+ i: Int
+ ) {
+ val checkedColor = mIndicatorOptions.checkedSliderColor
+ val indicatorGap = mIndicatorOptions.sliderGap
+ val sliderHeight = mIndicatorOptions.sliderHeight
+ val currentPosition = mIndicatorOptions.currentPosition
+ val normalWidth = mIndicatorOptions.normalSliderWidth
+ val checkedWidth = mIndicatorOptions.checkedSliderWidth
+ when {
+ i < currentPosition -> {
+ mPaint.color = mIndicatorOptions.normalSliderColor
+ val left: Float = if (currentPosition == mIndicatorOptions.pageSize - 1) {
+ (i * normalWidth + i * indicatorGap) + (checkedWidth - normalWidth) * mIndicatorOptions.slideProgress
+ } else {
+ (i * normalWidth + i * indicatorGap)
+ }
+ mRectF.set(left, 0f, left + normalWidth, sliderHeight)
+ drawRoundRect(canvas, sliderHeight, sliderHeight,mRectF.width()>checkedWidth/2)
+ }
+ i == currentPosition -> {
+ mPaint.color = checkedColor
+ val slideProgress = mIndicatorOptions.slideProgress
+ if (currentPosition == mIndicatorOptions.pageSize - 1) {
+ val evaluate = argbEvaluator?.evaluate(
+ slideProgress, checkedColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = (evaluate as Int)
+ val right =
+ (mIndicatorOptions.pageSize - 1) * (normalWidth + mIndicatorOptions.sliderGap) + checkedWidth
+ val left = right - checkedWidth + (checkedWidth - normalWidth) * (slideProgress)
+ mRectF.set(left, 0f, right, sliderHeight)
+ drawRoundRect(canvas, sliderHeight, sliderHeight,mRectF.width()>checkedWidth/2)
+ } else {
+ if (slideProgress < 1) {
+ val evaluate = argbEvaluator?.evaluate(
+ slideProgress, checkedColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = (evaluate as Int)
+ val left = i * normalWidth + i * indicatorGap
+ val right = left + normalWidth + (checkedWidth - normalWidth) * (1 - slideProgress)
+ mRectF.set(left, 0f, right, sliderHeight)
+ drawRoundRect(canvas, sliderHeight, sliderHeight,mRectF.width()>checkedWidth/2)
+ }
+ }
+
+ if (currentPosition == mIndicatorOptions.pageSize - 1) {
+ if (slideProgress > 0) {
+ val evaluate = argbEvaluator?.evaluate(
+ 1 - slideProgress, checkedColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = evaluate as Int
+ val left = 0f
+ val right = left + normalWidth + (checkedWidth - normalWidth) * slideProgress
+
+ mRectF.set(left, 0f, right, sliderHeight)
+ drawRoundRect(canvas, sliderHeight, sliderHeight,mRectF.width()>checkedWidth/2)
+ }
+ } else {
+ if (slideProgress > 0) {
+ val evaluate = argbEvaluator?.evaluate(
+ 1 - slideProgress, checkedColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = evaluate as Int
+ val right =
+ i * normalWidth + i * indicatorGap + normalWidth + (indicatorGap + checkedWidth)
+ val left = right - (normalWidth) - (checkedWidth - normalWidth) * (slideProgress)
+ mRectF.set(left, 0f, right, sliderHeight)
+ drawRoundRect(canvas, sliderHeight, sliderHeight,mRectF.width()>checkedWidth/2)
+ }
+ }
+ }
+ else -> {
+ if ((currentPosition + 1 != i || mIndicatorOptions.slideProgress == 0f)) { // 避免多余绘制
+ mPaint.color = mIndicatorOptions.normalSliderColor
+ val left = i * minWidth + i * indicatorGap + (checkedWidth - minWidth)
+ mRectF.set(left, 0f, left + minWidth, sliderHeight)
+ drawRoundRect(canvas, sliderHeight, sliderHeight,false)
+ }
+ }
+ }
+ }
+
+ private fun drawUncheckedSlider(
+ canvas: Canvas,
+ pageSize: Int
+ ) {
+ for (i in 0 until pageSize) {
+ mPaint.color = mIndicatorOptions.normalSliderColor
+ val left = i * maxWidth + i * +mIndicatorOptions.sliderGap + (maxWidth - minWidth)
+ mRectF.set(left, 0f, left + minWidth, mIndicatorOptions.sliderHeight)
+ drawRoundRect(canvas, mIndicatorOptions.sliderHeight, mIndicatorOptions.sliderHeight,false)
+ }
+ }
+
+ private fun drawInequalitySlider(
+ canvas: Canvas,
+ pageSize: Int
+ ) {
+ var left = 0f
+ for (i in 0 until pageSize) {
+ val sliderWidth = (if (i == mIndicatorOptions.currentPosition) maxWidth else minWidth)
+ mPaint.color =
+ if (i == mIndicatorOptions.currentPosition) mIndicatorOptions.checkedSliderColor else mIndicatorOptions.normalSliderColor
+ mRectF.set(left, 0f, left + sliderWidth, mIndicatorOptions.sliderHeight)
+ drawRoundRect(canvas, mIndicatorOptions.sliderHeight, mIndicatorOptions.sliderHeight,false)
+ left += sliderWidth + mIndicatorOptions.sliderGap
+ }
+ }
+
+ private fun drawCheckedSlider(canvas: Canvas) {
+ mPaint.color = mIndicatorOptions.checkedSliderColor
+ when (mIndicatorOptions.slideMode) {
+ IndicatorSlideMode.SMOOTH -> drawSmoothSlider(canvas)
+ IndicatorSlideMode.WORM -> drawWormSlider(canvas)
+ IndicatorSlideMode.COLOR -> drawColorSlider(canvas)
+ }
+ }
+
+ private fun drawColorSlider(canvas: Canvas) {
+ val currentPosition = mIndicatorOptions.currentPosition
+ val slideProgress = mIndicatorOptions.slideProgress
+ val left = currentPosition * minWidth + currentPosition * mIndicatorOptions.sliderGap
+ if (slideProgress < 0.99) {
+ val evaluate = argbEvaluator?.evaluate(
+ slideProgress, mIndicatorOptions.checkedSliderColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = (evaluate as Int)
+ mRectF.set(left, 0f, left + minWidth, mIndicatorOptions.sliderHeight)
+ drawRoundRect(canvas, mIndicatorOptions.sliderHeight, mIndicatorOptions.sliderHeight,false)
+ }
+
+ var nextSliderLeft = left + mIndicatorOptions.sliderGap + mIndicatorOptions.normalSliderWidth
+ if (currentPosition == mIndicatorOptions.pageSize - 1) {
+ nextSliderLeft = 0f
+ }
+ val evaluate = argbEvaluator?.evaluate(
+ 1 - slideProgress, mIndicatorOptions.checkedSliderColor, mIndicatorOptions.normalSliderColor
+ )
+ mPaint.color = evaluate as Int
+ mRectF.set(nextSliderLeft, 0f, nextSliderLeft + minWidth, mIndicatorOptions.sliderHeight)
+ drawRoundRect(canvas, mIndicatorOptions.sliderHeight, mIndicatorOptions.sliderHeight,false)
+ }
+
+ private fun drawWormSlider(canvas: Canvas) {
+ val sliderHeight = mIndicatorOptions.sliderHeight
+ val slideProgress = mIndicatorOptions.slideProgress
+ val currentPosition = mIndicatorOptions.currentPosition
+ val distance = mIndicatorOptions.sliderGap + mIndicatorOptions.normalSliderWidth
+ val startCoordinateX =
+ IndicatorUtils.getCoordinateX(mIndicatorOptions, maxWidth, currentPosition)
+ val left = startCoordinateX + (distance * (slideProgress - 0.5f) * 2.0f).coerceAtLeast(
+ 0f
+ ) - mIndicatorOptions.normalSliderWidth / 2
+ val right = startCoordinateX + (distance * slideProgress * 2f).coerceAtMost(
+ distance
+ ) + mIndicatorOptions.normalSliderWidth / 2
+ mRectF.set(left, 0f, right, sliderHeight)
+ drawRoundRect(canvas, sliderHeight, sliderHeight,false)
+ }
+
+ private fun drawSmoothSlider(canvas: Canvas) {
+ val currentPosition = mIndicatorOptions.currentPosition
+ val indicatorGap = mIndicatorOptions.sliderGap
+ val sliderHeight = mIndicatorOptions.sliderHeight
+ val left =
+ currentPosition * maxWidth + currentPosition * +indicatorGap + (maxWidth + indicatorGap) * mIndicatorOptions.slideProgress
+ mRectF.set(left, 0f, left + maxWidth, sliderHeight)
+ drawRoundRect(canvas, sliderHeight, sliderHeight,false)
+ }
+
+ protected open fun drawRoundRect(
+ canvas: Canvas,
+ rx: Float,
+ ry: Float,
+ isWidth:Boolean
+ ) {
+ drawDash(canvas)
+ }
+
+ protected open fun drawDash(canvas: Canvas) {}
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/RoundRectDrawer.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/RoundRectDrawer.kt
new file mode 100644
index 0000000000..fe781c7656
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/drawer/RoundRectDrawer.kt
@@ -0,0 +1,38 @@
+package com.mogo.och.taxi.passenger.widget.indicator.drawer
+
+import android.graphics.Canvas
+import android.graphics.LinearGradient
+import android.graphics.Shader
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+
+/**
+ *
+ * Created by zhpan on 2019/11/26.
+ * Description:
+
*
+ */
+class RoundRectDrawer internal constructor(val indicatorOptions: IndicatorOptions) : RectDrawer(
+ indicatorOptions
+) {
+
+ override fun drawRoundRect(canvas: Canvas, rx: Float, ry: Float, isWidth: Boolean) {
+ if(isWidth) {
+ val linearGradient =
+ LinearGradient(
+ mRectF.left,
+ (mRectF.bottom - mRectF.top) / 2,
+ mRectF.right,
+ (mRectF.bottom - mRectF.top) / 2,
+ indicatorOptions.checkedSliderColor,
+ indicatorOptions.checkedEndSliderColor,
+ Shader.TileMode.CLAMP
+ )
+ mPaint.shader = linearGradient
+ }else{
+ mPaint.color = indicatorOptions.normalSliderColor
+ mPaint.shader = null
+ }
+ canvas.drawRoundRect(mRectF, rx, ry, mPaint)
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorOrientation.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorOrientation.kt
new file mode 100644
index 0000000000..4f507e4c05
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorOrientation.kt
@@ -0,0 +1,16 @@
+package com.mogo.och.taxi.passenger.widget.indicator.enums
+
+import android.widget.LinearLayout
+
+/**
+ *
+ * @author zhangpan
+ * @date 2021/1/21
+ */
+class IndicatorOrientation {
+ companion object {
+ const val INDICATOR_HORIZONTAL = LinearLayout.HORIZONTAL
+ const val INDICATOR_VERTICAL = LinearLayout.VERTICAL
+ const val INDICATOR_RTL = 3
+ }
+}
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorSlideMode.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorSlideMode.kt
new file mode 100644
index 0000000000..0e9dfda078
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorSlideMode.kt
@@ -0,0 +1,17 @@
+package com.mogo.och.taxi.passenger.widget.indicator.enums
+
+/**
+ *
+ * Created by zhangpan on 2019-10-18.
+ * Description:
+
*
+ */
+interface IndicatorSlideMode {
+ companion object {
+ const val NORMAL = 0
+ const val SMOOTH = 2
+ const val WORM = 3
+ const val SCALE = 4
+ const val COLOR = 5
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorStyle.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorStyle.kt
new file mode 100644
index 0000000000..e66ffb10fc
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/enums/IndicatorStyle.kt
@@ -0,0 +1,15 @@
+package com.mogo.och.taxi.passenger.widget.indicator.enums
+
+/**
+ *
+ * Created by zhangpan on 2019-10-18.
+ * Description:
+
*
+ */
+interface IndicatorStyle {
+ companion object {
+ const val CIRCLE = 0
+ const val DASH = 1 shl 1
+ const val ROUND_RECT = 1 shl 2
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/option/AttrsController.java b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/option/AttrsController.java
new file mode 100644
index 0000000000..3a439ec7ea
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/option/AttrsController.java
@@ -0,0 +1,38 @@
+package com.mogo.och.taxi.passenger.widget.indicator.option;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.mogo.och.taxi.passenger.R;
+import com.mogo.och.taxi.passenger.widget.indicator.utils.IndicatorUtils;
+
+public class AttrsController {
+
+ public static void initAttrs(@NonNull Context context, @Nullable AttributeSet attrs,
+ IndicatorOptions indicatorOptions) {
+ if (attrs != null) {
+ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);
+ int indicatorSlideMode = typedArray.getInt(R.styleable.IndicatorView_vpi_slide_mode, 0);
+ int indicatorStyle = typedArray.getInt(R.styleable.IndicatorView_vpi_style, 0);
+ int checkedColor = typedArray.getColor(R.styleable.IndicatorView_vpi_slider_checked_color,
+ Color.parseColor("#6C6D72"));
+ int normalColor = typedArray.getColor(R.styleable.IndicatorView_vpi_slider_normal_color,
+ Color.parseColor("#8C18171C"));
+ int orientation = typedArray.getInt(R.styleable.IndicatorView_vpi_orientation, 0);
+ float radius = typedArray.getDimension(R.styleable.IndicatorView_vpi_slider_radius,
+ IndicatorUtils.dp2px(8));
+ indicatorOptions.setCheckedColor(checkedColor);
+ indicatorOptions.setNormalSliderColor(normalColor);
+ indicatorOptions.setOrientation(orientation);
+ indicatorOptions.setIndicatorStyle(indicatorStyle);
+ indicatorOptions.setSlideMode(indicatorSlideMode);
+ indicatorOptions.setSliderWidth(radius * 2, radius * 2);
+ typedArray.recycle();
+ }
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/option/IndicatorOptions.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/option/IndicatorOptions.kt
new file mode 100644
index 0000000000..47a993e1d7
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/option/IndicatorOptions.kt
@@ -0,0 +1,114 @@
+package com.mogo.och.taxi.passenger.widget.indicator.option
+
+import android.graphics.Color
+import com.mogo.och.taxi.passenger.widget.indicator.annotation.AIndicatorOrientation
+
+import com.mogo.och.taxi.passenger.widget.indicator.annotation.AIndicatorSlideMode
+import com.mogo.och.taxi.passenger.widget.indicator.annotation.AIndicatorStyle
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorOrientation
+import com.mogo.och.taxi.passenger.widget.indicator.enums.IndicatorSlideMode
+import com.mogo.och.taxi.passenger.widget.indicator.utils.IndicatorUtils
+
+/**
+ *
+ * Created by zhpan on 2019/11/20.
+ * Description:Indicator的配置参数
+
*
+ */
+class IndicatorOptions {
+
+ @AIndicatorOrientation
+ var orientation = IndicatorOrientation.INDICATOR_HORIZONTAL
+
+ @AIndicatorStyle
+ var indicatorStyle: Int = 0
+
+ /**
+ * Indicator滑动模式,目前仅支持两种
+ *
+ * @see IndicatorSlideMode.NORMAL
+ *
+ * @see IndicatorSlideMode.SMOOTH
+ */
+ @AIndicatorSlideMode
+ var slideMode: Int = 0
+
+ /**
+ * 页面size
+ */
+ var pageSize: Int = 0
+
+ /**
+ * 未选中时Indicator颜色
+ */
+ var normalSliderColor: Int = 0
+
+ /**
+ * 选中时Indicator颜色
+ */
+ var checkedSliderColor: Int = 0
+ /**
+ * 选中时IndicatorEnd颜色
+ */
+ var checkedEndSliderColor: Int = 0
+
+ /**
+ * Indicator间距
+ */
+ var sliderGap: Float = 0f
+
+ var sliderHeight: Float = 0f
+ get() = if (field > 0) field else normalSliderWidth / 2
+
+ var normalSliderWidth: Float = 0f
+
+ var checkedSliderWidth: Float = 0f
+
+ /**
+ * 指示器当前位置
+ */
+ var currentPosition: Int = 0
+
+ /**
+ * 从一个点滑动到另一个点的进度
+ */
+ var slideProgress: Float = 0f
+
+ var showIndicatorOneItem: Boolean = false
+
+ init {
+ normalSliderWidth = IndicatorUtils.dp2px(8f)
+ .toFloat()
+ checkedSliderWidth = normalSliderWidth
+ sliderGap = normalSliderWidth
+ normalSliderColor = Color.parseColor("#8C18171C")
+ checkedSliderColor = Color.parseColor("#8C6C6D72")
+ slideMode = IndicatorSlideMode.NORMAL
+ }
+
+ fun setCheckedColor(checkedColor: Int) {
+ this.checkedSliderColor = checkedColor
+ }
+
+ fun setSliderWidth(
+ normalIndicatorWidth: Float,
+ checkedIndicatorWidth: Float
+ ) {
+ this.normalSliderWidth = normalIndicatorWidth
+ this.checkedSliderWidth = checkedIndicatorWidth
+ }
+
+ fun setSliderWidth(sliderWidth: Float) {
+ setSliderWidth(sliderWidth, sliderWidth)
+ }
+
+ fun setSliderColor(
+ normalColor: Int,
+ checkedColor: Int,
+ selectedEndColor: Int
+ ) {
+ this.normalSliderColor = normalColor
+ this.checkedSliderColor = checkedColor
+ this.checkedEndSliderColor = selectedEndColor
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/utils/IndicatorUtils.kt b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/utils/IndicatorUtils.kt
new file mode 100644
index 0000000000..6b0894f3a8
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/java/com/mogo/och/taxi/passenger/widget/indicator/utils/IndicatorUtils.kt
@@ -0,0 +1,32 @@
+package com.mogo.och.taxi.passenger.widget.indicator.utils
+
+import android.content.res.Resources
+
+import com.mogo.och.taxi.passenger.widget.indicator.option.IndicatorOptions
+
+/**
+ *
+ * Created by zhangpan on 2020-01-20.
+ * Description:
+
*
+ */
+object IndicatorUtils {
+
+ @JvmStatic
+ fun dp2px(dpValue: Float): Int {
+ return (0.5f + dpValue * Resources.getSystem().displayMetrics.density).toInt()
+ }
+
+ fun getCoordinateX(
+ indicatorOptions: IndicatorOptions,
+ maxDiameter: Float,
+ index: Int
+ ): Float {
+ val normalIndicatorWidth = indicatorOptions.normalSliderWidth
+ return maxDiameter / 2 + (normalIndicatorWidth + indicatorOptions.sliderGap) * index
+ }
+
+ fun getCoordinateY(maxDiameter: Float): Float {
+ return maxDiameter / 2
+ }
+}
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/alpha_hide_show.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/alpha_hide_show.xml
new file mode 100644
index 0000000000..ddb2eaf470
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/alpha_hide_show.xml
@@ -0,0 +1,3 @@
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/alpha_show_hide.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/alpha_show_hide.xml
new file mode 100644
index 0000000000..ceac4e6062
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/alpha_show_hide.xml
@@ -0,0 +1,3 @@
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/left_to_right.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/left_to_right.xml
new file mode 100644
index 0000000000..dfe499b9b6
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/left_to_right.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/right_to_left.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/right_to_left.xml
new file mode 100644
index 0000000000..39b17e037e
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/anim/right_to_left.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/animator/alpha_hide_hide_f.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/animator/alpha_hide_hide_f.xml
new file mode 100644
index 0000000000..599149e9a7
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/animator/alpha_hide_hide_f.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/animator/alpha_hide_show_f.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/animator/alpha_hide_show_f.xml
new file mode 100644
index 0000000000..8c6acc7439
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/animator/alpha_hide_show_f.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/color/taxi_autopilot_text_color_selector.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/color/taxi_autopilot_text_color_selector.xml
new file mode 100644
index 0000000000..16cef94271
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/color/taxi_autopilot_text_color_selector.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-v29/taxi_video_order_process.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-v29/taxi_video_order_process.xml
new file mode 100644
index 0000000000..67843a4b8c
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-v29/taxi_video_order_process.xml
@@ -0,0 +1,26 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-v29/taxi_video_seekbar_style.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-v29/taxi_video_seekbar_style.xml
new file mode 100644
index 0000000000..4a771923d6
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-v29/taxi_video_seekbar_style.xml
@@ -0,0 +1,26 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/bg_taxi_p_checked_input_background.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/bg_taxi_p_checked_input_background.png
new file mode 100644
index 0000000000..ec58d028f2
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/bg_taxi_p_checked_input_background.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/bg_taxi_p_video_index.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/bg_taxi_p_video_index.png
new file mode 100644
index 0000000000..61f22d3bf0
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/bg_taxi_p_video_index.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_light_increase_set.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_light_increase_set.png
new file mode 100644
index 0000000000..5ec15568b0
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_light_increase_set.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_light_set.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_light_set.png
new file mode 100644
index 0000000000..de1f7f064f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_light_set.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_voice_increase_set.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_voice_increase_set.png
new file mode 100644
index 0000000000..7e62e77a05
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_voice_increase_set.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_voice_set.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_voice_set.png
new file mode 100644
index 0000000000..c0f586f35e
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/iv_voice_set.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/tail_ani_0000.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/tail_ani_0000.webp
new file mode 100644
index 0000000000..1448922144
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/tail_ani_0000.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/tail_ani_0090.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/tail_ani_0090.webp
new file mode 100644
index 0000000000..d10da861a8
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/tail_ani_0090.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_arrived_glide.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_arrived_glide.png
new file mode 100644
index 0000000000..adc24a4587
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_arrived_glide.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_blue_tooth_close.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_blue_tooth_close.png
new file mode 100644
index 0000000000..f114ddbb67
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_blue_tooth_close.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_blue_tooth_open.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_blue_tooth_open.png
new file mode 100644
index 0000000000..55896f8433
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_blue_tooth_open.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_bar_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_bar_bg.png
new file mode 100644
index 0000000000..e57ab24b01
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_bar_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_bar_select_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_bar_select_bg.png
new file mode 100644
index 0000000000..80a15f7f0b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_bar_select_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_overmap_normal.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_overmap_normal.png
new file mode 100644
index 0000000000..039096dd66
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_overmap_normal.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_overmap_press.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_overmap_press.png
new file mode 100644
index 0000000000..5996ff1b61
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_overmap_press.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_precisionmap_normal.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_precisionmap_normal.png
new file mode 100644
index 0000000000..ebc9258cb7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_precisionmap_normal.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_precisionmap_press.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_precisionmap_press.png
new file mode 100644
index 0000000000..1406939d8e
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_precisionmap_press.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_video_normal.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_video_normal.png
new file mode 100644
index 0000000000..92ed61f399
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_video_normal.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_video_press.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_video_press.png
new file mode 100644
index 0000000000..22f03e303b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_bottom_video_press.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_change_full.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_change_full.png
new file mode 100644
index 0000000000..1504bbc816
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_change_full.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_change_normal.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_change_normal.png
new file mode 100644
index 0000000000..3f24949883
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_change_normal.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_front_left_door_bg.9.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_front_left_door_bg.9.png
new file mode 100644
index 0000000000..b34a60c25e
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_front_left_door_bg.9.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_front_right_door_bg.9.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_front_right_door_bg.9.png
new file mode 100644
index 0000000000..0fe4112c52
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_front_right_door_bg.9.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_function_voice_humb.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_function_voice_humb.png
new file mode 100644
index 0000000000..347bb58d46
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_function_voice_humb.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_itinerary_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_itinerary_bg.png
new file mode 100644
index 0000000000..8d08d98530
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_itinerary_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_location_center.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_location_center.png
new file mode 100644
index 0000000000..2aa805a7c2
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_location_center.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_arrow_arrived.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_arrow_arrived.png
new file mode 100644
index 0000000000..36ef2e88d3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_arrow_arrived.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_arrow_un_arrive.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_arrow_un_arrive.png
new file mode 100644
index 0000000000..baa35592cb
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_arrow_un_arrive.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_car.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_car.png
new file mode 100644
index 0000000000..560ba9a367
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_car.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_car_light.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_car_light.png
new file mode 100644
index 0000000000..3d4acc9951
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_car_light.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_view_dir_end.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_view_dir_end.png
new file mode 100644
index 0000000000..a81336d4c2
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_view_dir_end.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_view_dir_start.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_view_dir_start.png
new file mode 100644
index 0000000000..3cee184981
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_map_view_dir_start.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_consult_title_icon.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_consult_title_icon.png
new file mode 100644
index 0000000000..56452fe256
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_consult_title_icon.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_logo.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_logo.png
new file mode 100644
index 0000000000..7497c10064
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_logo.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_video_play.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_video_play.png
new file mode 100644
index 0000000000..ff5fb41cab
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_mogo_video_play.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_arrived_close.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_arrived_close.png
new file mode 100644
index 0000000000..77bac9388b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_arrived_close.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_end_boll.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_end_boll.png
new file mode 100644
index 0000000000..97644d1c3d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_end_boll.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_input_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_input_bg.png
new file mode 100644
index 0000000000..72c0f0fc40
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_input_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_logo.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_logo.png
new file mode 100644
index 0000000000..328da8bc90
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_logo.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_panel_bg.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_panel_bg.webp
new file mode 100644
index 0000000000..8736cf5d06
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_panel_bg.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_start_boll.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_start_boll.png
new file mode 100644
index 0000000000..c6a019187a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_start_boll.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_start_end_line.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_start_end_line.png
new file mode 100644
index 0000000000..14c0e5fa19
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_check_start_end_line.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_start_panel_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_start_panel_bg.png
new file mode 100644
index 0000000000..784a482dcf
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_passenger_start_panel_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_pnc_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_pnc_bg.png
new file mode 100644
index 0000000000..f3892d99b1
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_pnc_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_rear_left_door_bg.9.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_rear_left_door_bg.9.png
new file mode 100644
index 0000000000..bfa9354128
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_rear_left_door_bg.9.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_rear_right_door_bg.9.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_rear_right_door_bg.9.png
new file mode 100644
index 0000000000..9dae84147d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_rear_right_door_bg.9.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_right_rear_cam.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_right_rear_cam.png
new file mode 100755
index 0000000000..cc4cdceca5
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_right_rear_cam.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_roma_checked.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_roma_checked.png
new file mode 100644
index 0000000000..7377fd23a7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_roma_checked.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_roma_normal.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_roma_normal.png
new file mode 100644
index 0000000000..38e78514d9
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_roma_normal.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_checked.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_checked.png
new file mode 100644
index 0000000000..017decf57c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_checked.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_normal.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_normal.png
new file mode 100644
index 0000000000..c317fdc045
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_normal.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_view_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_view_bg.png
new file mode 100644
index 0000000000..3b9fadf64c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_setting_view_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_status_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_status_bg.png
new file mode 100644
index 0000000000..9ef3dedd65
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_status_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_video_holder.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_video_holder.png
new file mode 100644
index 0000000000..99bfcefc6f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_video_holder.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_video_light_bg.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_video_light_bg.png
new file mode 100644
index 0000000000..e9f0ea0090
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/taxi_p_video_light_bg.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/xiaozhi_safety_belt.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/xiaozhi_safety_belt.png
new file mode 100644
index 0000000000..1f44f3d499
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable-xhdpi/xiaozhi_safety_belt.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_check_input_background.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_check_input_background.xml
new file mode 100644
index 0000000000..9e7e8385d0
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_check_input_background.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_keyboard_background.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_keyboard_background.xml
new file mode 100644
index 0000000000..8476da3706
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_keyboard_background.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_bg.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_bg.xml
new file mode 100644
index 0000000000..d86b36b5c1
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_bg.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_bg_top.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_bg_top.xml
new file mode 100644
index 0000000000..843c2658d2
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_bg_top.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_light_bg_shape.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_light_bg_shape.xml
new file mode 100644
index 0000000000..387f89e2eb
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/bg_taxi_p_video_light_bg_shape.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00000.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00000.png
new file mode 100644
index 0000000000..7d887647ed
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00000.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00001.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00001.png
new file mode 100644
index 0000000000..9cf5bda880
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00001.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00002.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00002.png
new file mode 100644
index 0000000000..6077a2c08f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00002.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00003.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00003.png
new file mode 100644
index 0000000000..047b3c3d2c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00003.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00004.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00004.png
new file mode 100644
index 0000000000..4f615372d7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00004.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00005.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00005.png
new file mode 100644
index 0000000000..959dbd6c57
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00005.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00006.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00006.png
new file mode 100644
index 0000000000..59aa3aa5a7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00006.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00007.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00007.png
new file mode 100644
index 0000000000..d623763a76
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00007.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00008.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00008.png
new file mode 100644
index 0000000000..8f548bfbf0
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00008.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00009.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00009.png
new file mode 100644
index 0000000000..6127862fcd
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00009.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00010.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00010.png
new file mode 100644
index 0000000000..d12a204bd3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00010.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00011.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00011.png
new file mode 100644
index 0000000000..ba1ec584d3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00011.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00012.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00012.png
new file mode 100644
index 0000000000..9f8ef18110
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00012.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00013.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00013.png
new file mode 100644
index 0000000000..a6c4c29ca6
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00013.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00014.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00014.png
new file mode 100644
index 0000000000..4d686d6906
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00014.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00015.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00015.png
new file mode 100644
index 0000000000..229d90ea91
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00015.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00016.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00016.png
new file mode 100644
index 0000000000..76566ef4cf
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00016.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00017.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00017.png
new file mode 100644
index 0000000000..0c737824f2
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00017.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00018.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00018.png
new file mode 100644
index 0000000000..ed21f50463
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00018.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00019.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00019.png
new file mode 100644
index 0000000000..6c3d2f36d1
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00019.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00020.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00020.png
new file mode 100644
index 0000000000..79ba9c2d55
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00020.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00021.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00021.png
new file mode 100644
index 0000000000..344298c6fa
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00021.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00022.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00022.png
new file mode 100644
index 0000000000..d4a3aa37ac
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00022.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00023.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00023.png
new file mode 100644
index 0000000000..bf16bc01e3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00023.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00024.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00024.png
new file mode 100644
index 0000000000..4393d89daa
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00024.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00025.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00025.png
new file mode 100644
index 0000000000..0d806f46f3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00025.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00026.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00026.png
new file mode 100644
index 0000000000..1d66ff5f0f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00026.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00027.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00027.png
new file mode 100644
index 0000000000..48cb04e811
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00027.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00028.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00028.png
new file mode 100644
index 0000000000..346985a730
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00028.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00029.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00029.png
new file mode 100644
index 0000000000..fa5570051b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00029.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00030.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00030.png
new file mode 100644
index 0000000000..e3a021bcdd
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00030.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00031.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00031.png
new file mode 100644
index 0000000000..997acf4628
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00031.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00032.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00032.png
new file mode 100644
index 0000000000..c203740591
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00032.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00033.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00033.png
new file mode 100644
index 0000000000..60c9ca07c1
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00033.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00034.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00034.png
new file mode 100644
index 0000000000..c1c8de33df
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/image_00034.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00000.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00000.png
new file mode 100644
index 0000000000..5aae3fd86e
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00000.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00001.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00001.png
new file mode 100644
index 0000000000..ea026b1519
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00001.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00002.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00002.png
new file mode 100644
index 0000000000..0c759d3144
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00002.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00003.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00003.png
new file mode 100644
index 0000000000..3ec26bf793
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00003.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00004.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00004.png
new file mode 100644
index 0000000000..bbeeaab0e9
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00004.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00005.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00005.png
new file mode 100644
index 0000000000..4a33f8d9b1
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00005.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00006.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00006.png
new file mode 100644
index 0000000000..6f4cc5ba4f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00006.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00007.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00007.png
new file mode 100644
index 0000000000..2a8b59e10d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00007.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00008.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00008.png
new file mode 100644
index 0000000000..0d41d05357
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00008.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00009.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00009.png
new file mode 100644
index 0000000000..dbea71933f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00009.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00010.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00010.png
new file mode 100644
index 0000000000..640b30dc9f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00010.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00011.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00011.png
new file mode 100644
index 0000000000..2ab41deea3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00011.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00012.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00012.png
new file mode 100644
index 0000000000..ba65b3bb1a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00012.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00013.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00013.png
new file mode 100644
index 0000000000..4a90fbf8e8
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/light_00013.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/roma_taxi_p_bg_selector.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/roma_taxi_p_bg_selector.xml
new file mode 100644
index 0000000000..f51169b6b9
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/roma_taxi_p_bg_selector.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_map_arrow_arrived.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_map_arrow_arrived.png
new file mode 100644
index 0000000000..36ef2e88d3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_map_arrow_arrived.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_map_arrow_un_arrive.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_map_arrow_un_arrive.png
new file mode 100644
index 0000000000..baa35592cb
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_map_arrow_un_arrive.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_function_voice_right_process_humb.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_function_voice_right_process_humb.xml
new file mode 100644
index 0000000000..1c98f8cad6
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_function_voice_right_process_humb.xml
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_setting_selector.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_setting_selector.xml
new file mode 100644
index 0000000000..8058cbece5
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_setting_selector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_start_autopilot_bottom_bg.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_start_autopilot_bottom_bg.xml
new file mode 100644
index 0000000000..54909012c8
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_start_autopilot_bottom_bg.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_start_autopilot_txt_btn_bg.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_start_autopilot_txt_btn_bg.xml
new file mode 100644
index 0000000000..d00674aaef
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_start_autopilot_txt_btn_bg.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_xiaozhibelt_info.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_xiaozhibelt_info.xml
new file mode 100644
index 0000000000..a5287f9968
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_xiaozhibelt_info.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_xiaozhibelt_info_ball.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_xiaozhibelt_info_ball.xml
new file mode 100644
index 0000000000..f5013dd9f1
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_p_xiaozhibelt_info_ball.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_video_order_process.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_video_order_process.xml
new file mode 100644
index 0000000000..36db1355c2
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_video_order_process.xml
@@ -0,0 +1,26 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_video_seekbar_style.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_video_seekbar_style.xml
new file mode 100644
index 0000000000..30ed19fa3c
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/taxi_video_seekbar_style.xml
@@ -0,0 +1,26 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_000.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_000.png
new file mode 100755
index 0000000000..dc02d142fc
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_000.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_001.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_001.png
new file mode 100755
index 0000000000..bbdea63868
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_001.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_002.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_002.png
new file mode 100755
index 0000000000..2e47294ae0
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_002.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_003.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_003.png
new file mode 100755
index 0000000000..cdf8848baa
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_003.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_004.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_004.png
new file mode 100755
index 0000000000..428b2e6089
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_004.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_005.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_005.png
new file mode 100755
index 0000000000..b5848a97f8
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_005.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_006.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_006.png
new file mode 100755
index 0000000000..68f6057614
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_006.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_007.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_007.png
new file mode 100755
index 0000000000..85f75927b0
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_007.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_008.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_008.png
new file mode 100755
index 0000000000..8ff0c749ee
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_008.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_009.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_009.png
new file mode 100755
index 0000000000..bce367e306
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_009.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_010.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_010.png
new file mode 100755
index 0000000000..89e66f1d6a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_010.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_011.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_011.png
new file mode 100755
index 0000000000..149ab11fba
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_011.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_012.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_012.png
new file mode 100755
index 0000000000..5e58823550
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_012.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_013.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_013.png
new file mode 100755
index 0000000000..d3079ef2da
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_013.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_014.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_014.png
new file mode 100755
index 0000000000..5f2524166a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_014.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_015.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_015.png
new file mode 100755
index 0000000000..216249be50
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_015.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_016.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_016.png
new file mode 100755
index 0000000000..4465305efc
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_016.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_017.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_017.png
new file mode 100755
index 0000000000..533a974f5b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_017.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_018.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_018.png
new file mode 100755
index 0000000000..8dce9ab91f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_018.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_019.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_019.png
new file mode 100755
index 0000000000..5aa9065b4f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_019.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_020.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_020.png
new file mode 100755
index 0000000000..9594926e7c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_020.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_021.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_021.png
new file mode 100755
index 0000000000..dc3ab0f50d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_021.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_022.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_022.png
new file mode 100755
index 0000000000..bb5e8ee278
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_022.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_023.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_023.png
new file mode 100755
index 0000000000..9647352845
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_023.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_024.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_024.png
new file mode 100755
index 0000000000..27aa8b213d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_024.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_025.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_025.png
new file mode 100755
index 0000000000..88e8fee290
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_025.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_026.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_026.png
new file mode 100755
index 0000000000..718de44286
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_026.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_027.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_027.png
new file mode 100755
index 0000000000..baef995016
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_027.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_028.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_028.png
new file mode 100755
index 0000000000..51c492f00f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_028.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_029.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_029.png
new file mode 100755
index 0000000000..42ae9da6b9
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_029.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_030.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_030.png
new file mode 100755
index 0000000000..8422896d73
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_030.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_031.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_031.png
new file mode 100755
index 0000000000..2a92bba341
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_031.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_032.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_032.png
new file mode 100755
index 0000000000..02081c5a36
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_032.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_033.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_033.png
new file mode 100755
index 0000000000..673c1f8301
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_033.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_034.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_034.png
new file mode 100755
index 0000000000..5ffe7bbb2c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_034.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_035.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_035.png
new file mode 100755
index 0000000000..89b156fc30
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_035.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_036.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_036.png
new file mode 100755
index 0000000000..eb99f327c0
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_036.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_037.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_037.png
new file mode 100755
index 0000000000..b002816e80
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_037.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_038.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_038.png
new file mode 100755
index 0000000000..92b56f031b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_038.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_039.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_039.png
new file mode 100755
index 0000000000..ee1fd2d15e
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_039.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_040.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_040.png
new file mode 100755
index 0000000000..efbebc1c84
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_040.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_041.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_041.png
new file mode 100755
index 0000000000..a976070776
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_041.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_042.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_042.png
new file mode 100755
index 0000000000..ca1edadfd7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_042.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_043.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_043.png
new file mode 100755
index 0000000000..7b255286bb
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_043.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_044.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_044.png
new file mode 100755
index 0000000000..710755927c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_044.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_045.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_045.png
new file mode 100755
index 0000000000..7c9123c8bc
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_045.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_046.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_046.png
new file mode 100755
index 0000000000..82fc0d5753
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_046.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_047.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_047.png
new file mode 100755
index 0000000000..c7c91207c3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_047.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_048.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_048.png
new file mode 100755
index 0000000000..28032ff402
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_048.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_049.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_049.png
new file mode 100755
index 0000000000..2c6830833f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_049.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_050.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_050.png
new file mode 100755
index 0000000000..04afd5754c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_050.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_051.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_051.png
new file mode 100755
index 0000000000..ba9e72c76f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_051.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_052.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_052.png
new file mode 100755
index 0000000000..3468c9dbe4
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_052.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_053.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_053.png
new file mode 100755
index 0000000000..46da555c6f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_053.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_054.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_054.png
new file mode 100755
index 0000000000..15cf6b1a89
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_054.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_055.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_055.png
new file mode 100755
index 0000000000..01903dda51
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_055.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_056.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_056.png
new file mode 100755
index 0000000000..372bad7c5d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_056.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_057.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_057.png
new file mode 100755
index 0000000000..2d27f781a0
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_057.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_058.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_058.png
new file mode 100755
index 0000000000..4812010741
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_058.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_059.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_059.png
new file mode 100755
index 0000000000..47e92e74ce
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_belt_059.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_000.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_000.png
new file mode 100755
index 0000000000..8f41f3ef17
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_000.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_001.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_001.png
new file mode 100755
index 0000000000..8974bdb433
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_001.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_002.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_002.png
new file mode 100755
index 0000000000..c27cff4a08
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_002.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_003.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_003.png
new file mode 100755
index 0000000000..480226c096
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_003.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_004.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_004.png
new file mode 100755
index 0000000000..d241bc3600
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_004.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_005.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_005.png
new file mode 100755
index 0000000000..043772caef
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_005.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_006.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_006.png
new file mode 100755
index 0000000000..e6141a5912
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_006.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_007.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_007.png
new file mode 100755
index 0000000000..08157b8d6a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_007.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_008.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_008.png
new file mode 100755
index 0000000000..518a163ee1
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_008.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_009.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_009.png
new file mode 100755
index 0000000000..0c00e4aec3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_009.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_010.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_010.png
new file mode 100755
index 0000000000..e2a82962be
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_010.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_011.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_011.png
new file mode 100755
index 0000000000..e4725814d1
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_011.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_012.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_012.png
new file mode 100755
index 0000000000..dd4c443901
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_012.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_013.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_013.png
new file mode 100755
index 0000000000..7bcd528ef6
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_013.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_014.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_014.png
new file mode 100755
index 0000000000..edf6a2a82f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_014.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_015.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_015.png
new file mode 100755
index 0000000000..6d19a79755
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_015.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_016.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_016.png
new file mode 100755
index 0000000000..13ca6cd6d7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_016.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_017.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_017.png
new file mode 100755
index 0000000000..11ec920c66
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_017.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_018.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_018.png
new file mode 100755
index 0000000000..5e747ba4db
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_018.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_019.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_019.png
new file mode 100755
index 0000000000..b1a7577d77
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_019.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_020.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_020.png
new file mode 100755
index 0000000000..281c7e819c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_020.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_021.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_021.png
new file mode 100755
index 0000000000..6c1da40819
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_021.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_022.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_022.png
new file mode 100755
index 0000000000..af5c969a1c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_022.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_023.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_023.png
new file mode 100755
index 0000000000..f0e0032234
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_023.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_024.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_024.png
new file mode 100755
index 0000000000..6dcdd8b73d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_024.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_025.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_025.png
new file mode 100755
index 0000000000..5a6f07be8c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_025.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_026.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_026.png
new file mode 100755
index 0000000000..f19df657d2
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_026.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_027.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_027.png
new file mode 100755
index 0000000000..bedc1f5560
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_027.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_028.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_028.png
new file mode 100755
index 0000000000..9cdfd7d0c6
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_028.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_029.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_029.png
new file mode 100755
index 0000000000..dd15bcfc8b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_029.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_030.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_030.png
new file mode 100755
index 0000000000..ec47b415ea
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_030.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_031.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_031.png
new file mode 100755
index 0000000000..0b79143e97
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_031.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_032.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_032.png
new file mode 100755
index 0000000000..50f98af14f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_032.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_033.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_033.png
new file mode 100755
index 0000000000..a067948510
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_033.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_034.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_034.png
new file mode 100755
index 0000000000..2a1654747f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_034.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_035.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_035.png
new file mode 100755
index 0000000000..58e547f24d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_035.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_036.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_036.png
new file mode 100755
index 0000000000..2a9683d1a7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_036.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_037.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_037.png
new file mode 100755
index 0000000000..937add65e7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_037.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_038.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_038.png
new file mode 100755
index 0000000000..e266a7f591
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_038.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_039.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_039.png
new file mode 100755
index 0000000000..e5e902e036
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_039.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_040.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_040.png
new file mode 100755
index 0000000000..3cb905752f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_040.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_041.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_041.png
new file mode 100755
index 0000000000..143b9c8d90
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_041.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_042.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_042.png
new file mode 100755
index 0000000000..a389ab571f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_042.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_043.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_043.png
new file mode 100755
index 0000000000..1cb679d5b3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_043.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_044.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_044.png
new file mode 100755
index 0000000000..8831f72e30
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_044.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_045.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_045.png
new file mode 100755
index 0000000000..1dc2743f91
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_045.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_046.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_046.png
new file mode 100755
index 0000000000..89a8a71f68
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_046.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_047.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_047.png
new file mode 100755
index 0000000000..8162689ff4
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_047.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_048.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_048.png
new file mode 100755
index 0000000000..0942909715
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_048.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_049.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_049.png
new file mode 100755
index 0000000000..5dc09ffd53
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_049.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_050.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_050.png
new file mode 100755
index 0000000000..701eb4430a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_050.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_051.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_051.png
new file mode 100755
index 0000000000..85589aa923
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_051.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_052.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_052.png
new file mode 100755
index 0000000000..6fde977d5d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_052.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_053.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_053.png
new file mode 100755
index 0000000000..af7b3c073b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_053.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_054.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_054.png
new file mode 100755
index 0000000000..73420b4b16
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_054.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_055.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_055.png
new file mode 100755
index 0000000000..337d51bd7a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_055.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_056.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_056.png
new file mode 100755
index 0000000000..baa1f32c72
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_056.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_057.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_057.png
new file mode 100755
index 0000000000..bf048e1eff
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_057.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_058.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_058.png
new file mode 100755
index 0000000000..a2fa4696b3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_058.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_059.png b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_059.png
new file mode 100755
index 0000000000..5886f3c427
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_love_059.png differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal002.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal002.webp
new file mode 100644
index 0000000000..f884ab93d7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal002.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal004.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal004.webp
new file mode 100644
index 0000000000..df14aa223b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal004.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal006.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal006.webp
new file mode 100644
index 0000000000..77274eaa4d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal006.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal008.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal008.webp
new file mode 100644
index 0000000000..4f5c85d539
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal008.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal010.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal010.webp
new file mode 100644
index 0000000000..4adbad5fb8
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal010.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal012.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal012.webp
new file mode 100644
index 0000000000..fc528eb53a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal012.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal014.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal014.webp
new file mode 100644
index 0000000000..4fcb94ef98
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal014.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal016.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal016.webp
new file mode 100644
index 0000000000..f5a93b0804
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal016.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal018.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal018.webp
new file mode 100644
index 0000000000..02e0e93241
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal018.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal020.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal020.webp
new file mode 100644
index 0000000000..98e72da076
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal020.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal022.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal022.webp
new file mode 100644
index 0000000000..e2d81a7334
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal022.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal024.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal024.webp
new file mode 100644
index 0000000000..7a1b164bf8
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal024.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal026.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal026.webp
new file mode 100644
index 0000000000..5e6aaed2f8
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal026.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal028.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal028.webp
new file mode 100644
index 0000000000..6eb257211d
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal028.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal030.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal030.webp
new file mode 100644
index 0000000000..a5edb81360
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal030.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal032.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal032.webp
new file mode 100644
index 0000000000..08c77712cb
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal032.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal034.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal034.webp
new file mode 100644
index 0000000000..014091014e
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal034.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal036.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal036.webp
new file mode 100644
index 0000000000..1cc0f71711
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal036.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal038.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal038.webp
new file mode 100644
index 0000000000..049594af92
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal038.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal040.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal040.webp
new file mode 100644
index 0000000000..b0a4fd1620
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal040.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal042.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal042.webp
new file mode 100644
index 0000000000..65dc7c66a7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal042.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal044.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal044.webp
new file mode 100644
index 0000000000..007f0c5bd2
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal044.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal046.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal046.webp
new file mode 100644
index 0000000000..f64218b62e
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal046.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal048.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal048.webp
new file mode 100644
index 0000000000..ce7aa5b09b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal048.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal050.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal050.webp
new file mode 100644
index 0000000000..2483b5cc85
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal050.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal052.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal052.webp
new file mode 100644
index 0000000000..2d6bbb3a28
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal052.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal054.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal054.webp
new file mode 100644
index 0000000000..073c631800
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal054.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal056.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal056.webp
new file mode 100644
index 0000000000..85ece9e86c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal056.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal058.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal058.webp
new file mode 100644
index 0000000000..8ea05e04c9
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal058.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal060.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal060.webp
new file mode 100644
index 0000000000..7128d98d60
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal060.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal062.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal062.webp
new file mode 100644
index 0000000000..05d022bc56
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal062.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal064.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal064.webp
new file mode 100644
index 0000000000..090a4dc753
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal064.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal066.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal066.webp
new file mode 100644
index 0000000000..ff190083fd
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal066.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal068.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal068.webp
new file mode 100644
index 0000000000..0071c33280
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal068.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal070.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal070.webp
new file mode 100644
index 0000000000..b3fa5a1881
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal070.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal072.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal072.webp
new file mode 100644
index 0000000000..d5896737f6
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal072.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal074.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal074.webp
new file mode 100644
index 0000000000..7ff64b5711
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal074.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal076.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal076.webp
new file mode 100644
index 0000000000..ec56210221
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal076.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal078.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal078.webp
new file mode 100644
index 0000000000..e6ec711416
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal078.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal080.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal080.webp
new file mode 100644
index 0000000000..e8fa9e5d36
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal080.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal082.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal082.webp
new file mode 100644
index 0000000000..d8ef9b37a7
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal082.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal084.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal084.webp
new file mode 100644
index 0000000000..da08363a67
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal084.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal086.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal086.webp
new file mode 100644
index 0000000000..c496ae20cc
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal086.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal088.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal088.webp
new file mode 100644
index 0000000000..27a41260df
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal088.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal090.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal090.webp
new file mode 100644
index 0000000000..65f9302aed
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal090.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal092.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal092.webp
new file mode 100644
index 0000000000..f7651dbf15
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal092.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal094.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal094.webp
new file mode 100644
index 0000000000..dd5570c9a9
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal094.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal096.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal096.webp
new file mode 100644
index 0000000000..4680be2c1c
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal096.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal098.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal098.webp
new file mode 100644
index 0000000000..76723aa3f3
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal098.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal100.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal100.webp
new file mode 100644
index 0000000000..49969ff350
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal100.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal102.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal102.webp
new file mode 100644
index 0000000000..533855c47f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal102.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal104.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal104.webp
new file mode 100644
index 0000000000..ee31412bd6
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal104.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal106.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal106.webp
new file mode 100644
index 0000000000..8efe589ede
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal106.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal108.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal108.webp
new file mode 100644
index 0000000000..1f6ff9aee6
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal108.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal110.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal110.webp
new file mode 100644
index 0000000000..3566c675d9
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal110.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal112.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal112.webp
new file mode 100644
index 0000000000..c9e23f1f69
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal112.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal114.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal114.webp
new file mode 100644
index 0000000000..be60094f54
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal114.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal116.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal116.webp
new file mode 100644
index 0000000000..e5dff07f9a
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal116.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal118.webp b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal118.webp
new file mode 100644
index 0000000000..aba89b659b
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/drawable/xiaozhi_normal118.webp differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/font/din.ttf b/OCH/taxi/taxi-unmanned-passenger/src/main/res/font/din.ttf
new file mode 100644
index 0000000000..60e06cb75f
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/font/din.ttf differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/list_video_item_light.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/list_video_item_light.xml
new file mode 100644
index 0000000000..eaca7d4b4a
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/list_video_item_light.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/m1_bottom_check.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/m1_bottom_check.xml
new file mode 100644
index 0000000000..d2841dbbd4
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/m1_bottom_check.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_arrived_end_panel.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_arrived_end_panel.xml
new file mode 100644
index 0000000000..54b4bd2d17
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_arrived_end_panel.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_base_fragment.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_base_fragment.xml
new file mode 100644
index 0000000000..21f27aa6b7
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_base_fragment.xml
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_blue_tooth.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_blue_tooth.xml
new file mode 100644
index 0000000000..ae7dafde3a
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_blue_tooth.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_bottom_bar.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_bottom_bar.xml
new file mode 100644
index 0000000000..db389e16c1
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_bottom_bar.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_debug.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_debug.xml
new file mode 100644
index 0000000000..3ac12defbe
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_debug.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_itinerary.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_itinerary.xml
new file mode 100644
index 0000000000..a5666659f3
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_itinerary.xml
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_mogo_video_layout.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_mogo_video_layout.xml
new file mode 100644
index 0000000000..fd94d513d7
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_mogo_video_layout.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_navi_view.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_navi_view.xml
new file mode 100644
index 0000000000..f3dc5139bd
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_navi_view.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_overmap_fragment.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_overmap_fragment.xml
new file mode 100644
index 0000000000..725167d00c
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_overmap_fragment.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_passenger_check_panel.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_passenger_check_panel.xml
new file mode 100644
index 0000000000..fac0def352
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_passenger_check_panel.xml
@@ -0,0 +1,320 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_right_rear_cam.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_right_rear_cam.xml
new file mode 100644
index 0000000000..d5c147cb67
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_right_rear_cam.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_setting_view.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_setting_view.xml
new file mode 100644
index 0000000000..94c9432ca1
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_setting_view.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_start_autopilot_view.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_start_autopilot_view.xml
new file mode 100644
index 0000000000..8390992694
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_start_autopilot_view.xml
@@ -0,0 +1,220 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_statusview.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_statusview.xml
new file mode 100644
index 0000000000..ecd2990ddc
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_statusview.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_video_show.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_video_show.xml
new file mode 100644
index 0000000000..f3e2d98126
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/layout/taxi_p_video_show.xml
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/raw/end_video.mp4 b/OCH/taxi/taxi-unmanned-passenger/src/main/res/raw/end_video.mp4
new file mode 100755
index 0000000000..d736845f93
Binary files /dev/null and b/OCH/taxi/taxi-unmanned-passenger/src/main/res/raw/end_video.mp4 differ
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/arrays.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/arrays.xml
new file mode 100644
index 0000000000..1776029165
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/arrays.xml
@@ -0,0 +1,260 @@
+
+
+
+ - @drawable/xiaozhi_normal002
+ - @drawable/xiaozhi_normal004
+ - @drawable/xiaozhi_normal006
+ - @drawable/xiaozhi_normal008
+ - @drawable/xiaozhi_normal010
+ - @drawable/xiaozhi_normal012
+ - @drawable/xiaozhi_normal014
+ - @drawable/xiaozhi_normal016
+ - @drawable/xiaozhi_normal018
+ - @drawable/xiaozhi_normal020
+ - @drawable/xiaozhi_normal022
+ - @drawable/xiaozhi_normal024
+ - @drawable/xiaozhi_normal026
+ - @drawable/xiaozhi_normal028
+ - @drawable/xiaozhi_normal030
+ - @drawable/xiaozhi_normal032
+ - @drawable/xiaozhi_normal034
+ - @drawable/xiaozhi_normal036
+ - @drawable/xiaozhi_normal038
+ - @drawable/xiaozhi_normal040
+ - @drawable/xiaozhi_normal042
+ - @drawable/xiaozhi_normal044
+ - @drawable/xiaozhi_normal046
+ - @drawable/xiaozhi_normal048
+ - @drawable/xiaozhi_normal050
+ - @drawable/xiaozhi_normal052
+ - @drawable/xiaozhi_normal054
+ - @drawable/xiaozhi_normal056
+ - @drawable/xiaozhi_normal058
+ - @drawable/xiaozhi_normal060
+ - @drawable/xiaozhi_normal062
+ - @drawable/xiaozhi_normal064
+ - @drawable/xiaozhi_normal066
+ - @drawable/xiaozhi_normal068
+ - @drawable/xiaozhi_normal070
+ - @drawable/xiaozhi_normal072
+ - @drawable/xiaozhi_normal074
+ - @drawable/xiaozhi_normal076
+ - @drawable/xiaozhi_normal078
+ - @drawable/xiaozhi_normal080
+ - @drawable/xiaozhi_normal082
+ - @drawable/xiaozhi_normal084
+ - @drawable/xiaozhi_normal086
+ - @drawable/xiaozhi_normal088
+ - @drawable/xiaozhi_normal090
+ - @drawable/xiaozhi_normal092
+ - @drawable/xiaozhi_normal094
+ - @drawable/xiaozhi_normal096
+ - @drawable/xiaozhi_normal098
+ - @drawable/xiaozhi_normal100
+ - @drawable/xiaozhi_normal102
+ - @drawable/xiaozhi_normal104
+ - @drawable/xiaozhi_normal106
+ - @drawable/xiaozhi_normal108
+ - @drawable/xiaozhi_normal110
+ - @drawable/xiaozhi_normal112
+ - @drawable/xiaozhi_normal114
+ - @drawable/xiaozhi_normal116
+ - @drawable/xiaozhi_normal118
+
+
+
+ - @drawable/image_00000
+ - @drawable/image_00001
+ - @drawable/image_00002
+ - @drawable/image_00003
+ - @drawable/image_00004
+ - @drawable/image_00005
+ - @drawable/image_00006
+ - @drawable/image_00007
+ - @drawable/image_00008
+ - @drawable/image_00009
+ - @drawable/image_00010
+ - @drawable/image_00011
+ - @drawable/image_00012
+ - @drawable/image_00013
+ - @drawable/image_00014
+ - @drawable/image_00015
+ - @drawable/image_00016
+ - @drawable/image_00017
+ - @drawable/image_00018
+ - @drawable/image_00019
+ - @drawable/image_00020
+ - @drawable/image_00021
+ - @drawable/image_00022
+ - @drawable/image_00023
+ - @drawable/image_00024
+ - @drawable/image_00025
+ - @drawable/image_00026
+ - @drawable/image_00027
+ - @drawable/image_00028
+ - @drawable/image_00029
+ - @drawable/image_00030
+ - @drawable/image_00031
+ - @drawable/image_00032
+ - @drawable/image_00033
+ - @drawable/image_00034
+
+
+
+ - @drawable/light_00000
+ - @drawable/light_00001
+ - @drawable/light_00002
+ - @drawable/light_00003
+ - @drawable/light_00004
+ - @drawable/light_00005
+ - @drawable/light_00006
+ - @drawable/light_00007
+ - @drawable/light_00008
+ - @drawable/light_00009
+ - @drawable/light_00010
+ - @drawable/light_00011
+ - @drawable/light_00012
+ - @drawable/light_00013
+
+
+
+ - @drawable/xiaozhi_love_000
+ - @drawable/xiaozhi_love_001
+ - @drawable/xiaozhi_love_002
+ - @drawable/xiaozhi_love_003
+ - @drawable/xiaozhi_love_004
+ - @drawable/xiaozhi_love_005
+ - @drawable/xiaozhi_love_006
+ - @drawable/xiaozhi_love_007
+ - @drawable/xiaozhi_love_008
+ - @drawable/xiaozhi_love_009
+
+ - @drawable/xiaozhi_love_010
+ - @drawable/xiaozhi_love_011
+ - @drawable/xiaozhi_love_012
+ - @drawable/xiaozhi_love_013
+ - @drawable/xiaozhi_love_014
+ - @drawable/xiaozhi_love_015
+ - @drawable/xiaozhi_love_016
+ - @drawable/xiaozhi_love_017
+ - @drawable/xiaozhi_love_018
+ - @drawable/xiaozhi_love_019
+
+ - @drawable/xiaozhi_love_020
+ - @drawable/xiaozhi_love_021
+ - @drawable/xiaozhi_love_022
+ - @drawable/xiaozhi_love_023
+ - @drawable/xiaozhi_love_024
+ - @drawable/xiaozhi_love_025
+ - @drawable/xiaozhi_love_026
+ - @drawable/xiaozhi_love_027
+ - @drawable/xiaozhi_love_028
+ - @drawable/xiaozhi_love_029
+
+
+ - @drawable/xiaozhi_love_030
+ - @drawable/xiaozhi_love_031
+ - @drawable/xiaozhi_love_032
+ - @drawable/xiaozhi_love_033
+ - @drawable/xiaozhi_love_034
+ - @drawable/xiaozhi_love_035
+ - @drawable/xiaozhi_love_036
+ - @drawable/xiaozhi_love_037
+ - @drawable/xiaozhi_love_038
+ - @drawable/xiaozhi_love_039
+
+ - @drawable/xiaozhi_love_040
+ - @drawable/xiaozhi_love_041
+ - @drawable/xiaozhi_love_042
+ - @drawable/xiaozhi_love_043
+ - @drawable/xiaozhi_love_044
+ - @drawable/xiaozhi_love_045
+ - @drawable/xiaozhi_love_046
+ - @drawable/xiaozhi_love_047
+ - @drawable/xiaozhi_love_048
+ - @drawable/xiaozhi_love_049
+
+
+ - @drawable/xiaozhi_love_050
+ - @drawable/xiaozhi_love_051
+ - @drawable/xiaozhi_love_052
+ - @drawable/xiaozhi_love_053
+ - @drawable/xiaozhi_love_054
+ - @drawable/xiaozhi_love_055
+ - @drawable/xiaozhi_love_056
+ - @drawable/xiaozhi_love_057
+ - @drawable/xiaozhi_love_058
+ - @drawable/xiaozhi_love_059
+
+
+
+
+ - @drawable/xiaozhi_belt_000
+ - @drawable/xiaozhi_belt_001
+ - @drawable/xiaozhi_belt_002
+ - @drawable/xiaozhi_belt_003
+ - @drawable/xiaozhi_belt_004
+ - @drawable/xiaozhi_belt_005
+ - @drawable/xiaozhi_belt_006
+ - @drawable/xiaozhi_belt_007
+ - @drawable/xiaozhi_belt_008
+ - @drawable/xiaozhi_belt_009
+
+ - @drawable/xiaozhi_belt_010
+ - @drawable/xiaozhi_belt_011
+ - @drawable/xiaozhi_belt_012
+ - @drawable/xiaozhi_belt_013
+ - @drawable/xiaozhi_belt_014
+ - @drawable/xiaozhi_belt_015
+ - @drawable/xiaozhi_belt_016
+ - @drawable/xiaozhi_belt_017
+ - @drawable/xiaozhi_belt_018
+ - @drawable/xiaozhi_belt_019
+
+ - @drawable/xiaozhi_belt_020
+ - @drawable/xiaozhi_belt_021
+ - @drawable/xiaozhi_belt_022
+ - @drawable/xiaozhi_belt_023
+ - @drawable/xiaozhi_belt_024
+ - @drawable/xiaozhi_belt_025
+ - @drawable/xiaozhi_belt_026
+ - @drawable/xiaozhi_belt_027
+ - @drawable/xiaozhi_belt_028
+ - @drawable/xiaozhi_belt_029
+
+
+ - @drawable/xiaozhi_belt_030
+ - @drawable/xiaozhi_belt_031
+ - @drawable/xiaozhi_belt_032
+ - @drawable/xiaozhi_belt_033
+ - @drawable/xiaozhi_belt_034
+ - @drawable/xiaozhi_belt_035
+ - @drawable/xiaozhi_belt_036
+ - @drawable/xiaozhi_belt_037
+ - @drawable/xiaozhi_belt_038
+ - @drawable/xiaozhi_belt_039
+
+ - @drawable/xiaozhi_belt_040
+ - @drawable/xiaozhi_belt_041
+ - @drawable/xiaozhi_belt_042
+ - @drawable/xiaozhi_belt_043
+ - @drawable/xiaozhi_belt_044
+ - @drawable/xiaozhi_belt_045
+ - @drawable/xiaozhi_belt_046
+ - @drawable/xiaozhi_belt_047
+ - @drawable/xiaozhi_belt_048
+ - @drawable/xiaozhi_belt_049
+
+
+ - @drawable/xiaozhi_belt_050
+ - @drawable/xiaozhi_belt_051
+ - @drawable/xiaozhi_belt_052
+ - @drawable/xiaozhi_belt_053
+ - @drawable/xiaozhi_belt_054
+ - @drawable/xiaozhi_belt_055
+ - @drawable/xiaozhi_belt_056
+ - @drawable/xiaozhi_belt_057
+ - @drawable/xiaozhi_belt_058
+ - @drawable/xiaozhi_belt_059
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/attrs.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/attrs.xml
new file mode 100644
index 0000000000..b7946fe4f7
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/attrs.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/colors.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..5212ef2c22
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/colors.xml
@@ -0,0 +1,57 @@
+
+
+ #FF3B4577
+
+ #FFFFFF
+
+ #FFFFA28B
+
+
+ #FFFFC836
+ #FF282F62
+ #FFFFFF
+ #FFFFFF
+
+ #8039388E
+ #151937
+
+ #4DFFFFFF
+ #FFFFFF
+
+ #111D2F
+ #004DC4
+ #293449
+ #203555
+ #B35C71AB
+ #081831
+ #112B57
+ #66476FBE
+
+ #6edbdc
+ #56efa0
+ #A7BDF3
+ #41444D
+ #0F5FFF
+ #44C8FF
+ #8AE4ED
+ #C8F3F4
+ #282F62
+ #121842
+ #242C65
+ #374968
+ #303C52
+ #2CBFFC
+ #1060ff
+ #96a5c2
+ #76D7FF
+ #255BAA
+ #80F8FF
+ #2B364B
+ #005D6A8C
+ #5D6A8C
+ #995D6A8C
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/dimens.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000..9619be8593
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/dimens.xml
@@ -0,0 +1,123 @@
+
+
+ 40dp
+ 46dp
+ 24dp
+
+ 15dp
+ 15dp
+ 40dp
+ 50dp
+ 50dp
+ 70dp
+ 40dp
+
+ 24dp
+ 300dp
+ 100dp
+
+ 100dp
+ 100dp
+
+ 35dp
+
+ 15dp
+ 300dp
+ 270dp
+
+ 30dp
+ 13dp
+ 12dp
+ 288dp
+
+ 460dp
+ 30dp
+ 5dp
+ 20dp
+ 20dp
+ 20dp
+ 1dp
+ 20dp
+ 20dp
+ 20dp
+ 140dp
+ 20dp
+ 20dp
+ 17dp
+ 20dp
+ 26dp
+ 20dp
+ 20dp
+ 64dp
+ 3dp
+ 20dp
+ 20dp
+ 24dp
+ 17dp
+ 22.5dp
+
+ 496dp
+ 560dp
+ 910dp
+ 800dp
+ 222dp
+ 1120dp
+ 162dp
+ 446dp
+ 400dp
+ 160dp
+ 432dp
+ 64dp
+ 616dp
+ 132dp
+ 300dp
+ 240dp
+ 400dp
+ 160dp
+ 280dp
+ 120dp
+
+ 220dp
+ 420dp
+ 220dp
+
+ 624dp
+ 984dp
+
+ 225dp
+ 154dp
+ 60dp
+ 40dp
+ 23dp
+ 210dp
+ 120dp
+ 15dp
+ 17dp
+ 154dp
+ 130dp
+ 60dp
+
+ 31dp
+ 110dp
+ 10dp
+ 70dp
+ 120dp
+ 39dp
+ 20dp
+ 30dp
+
+ 82dp
+ 42dp
+
+ 144dp
+ 32dp
+ 32dp
+ 36dp
+ 50dp
+ 34dp
+ 28dp
+
+ 52dp
+ 520dp
+ 150dp
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/strings.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..715cf4fee6
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/strings.xml
@@ -0,0 +1,49 @@
+
+
+ 确认上车,行程开始
+ 到达站点,乘客已下车
+ 已到达上车站点,等待乘客上车
+ 预计里程
+ 3.2 km
+ 请携带好随身物品,注意侧后\n方来车,感谢体验蘑菇智行自\n动驾驶车!
+ 即将到达目的地,请您携带好随身物品,安全下车。
+ 送乘客至目的地
+ 等待乘客上车
+ 前往乘客上车地点
+ 已到达乘客下车点
+ 订单已完成
+ 订单已取消
+ 请选择取消订单的理由
+ 出现异常情况时,可选择原因无责取消订单:
+ 确认
+ 开始服务
+ 服务完成
+ 准备出发
+ 正在前往目的地
+ 即将到达目的地,请您收好好随声物品,准备下车
+ 已达到目的地,请从右侧下车,感谢乘坐\'蘑菇车联\'自动驾驶车
+ 已到达
+ 感谢您使用蘑菇车联自动驾驶出行服务,期待下次与您相遇
+
+
+ 欢迎体验MOGO自动驾驶出租车
+ Hello,您好
+ 请输入手机号后4位:
+ 小蘑菇
+ 删除
+
+ 点击开启
+ 启动中...
+ 自动驾驶启动失败,请与司机确认车辆状态
+ 车辆尚未完成准备,不能启动自动驾驶
+
+ 距离(KM)
+ 距离(M)
+ 剩余(分)
+
+
+ 亮度
+ 音量
+
+
+
\ No newline at end of file
diff --git a/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/styles.xml b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/styles.xml
new file mode 100644
index 0000000000..7c3458d9bc
--- /dev/null
+++ b/OCH/taxi/taxi-unmanned-passenger/src/main/res/values/styles.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/script/functions/och.gradle b/app/script/functions/och.gradle
index a46cbee658..a5732d4de4 100644
--- a/app/script/functions/och.gradle
+++ b/app/script/functions/och.gradle
@@ -36,6 +36,8 @@ project.dependencies {
implementation project.project(':OCH:sweeper:sweeper')
} else if (isCurrentDriver("taxiunmanned")) {
implementation project.project(':OCH:taxi:mogo-och-taxi-unmanned')
+ } else if (isCurrentPassenger("taxiunmanned")) {
+ implementation project.project(':OCH:taxi:taxi-unmanned-passenger')
} else if (isCurrentDriver("taxi")) {
implementation project.project(':OCH:taxi:mogo-och-taxi')
}else if (isCurrentPassenger("taxi")) {
diff --git a/settings.gradle b/settings.gradle
index 865c818f1e..3d83bef07e 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -58,16 +58,25 @@ include ':test:crashreport-apmbyte'
//OCH 业务模块
include ':OCH:mogo-och-bus'
include ':OCH:mogo-och-bus-passenger'
+
include ':OCH:taxi:mogo-och-taxi'
-include ':OCH:taxi:mogo-och-taxi-unmanned'
include ':OCH:taxi:mogo-och-taxi-passenger'
+
+include ':OCH:taxi:mogo-och-taxi-unmanned'
+include ':OCH:taxi:taxi-unmanned-passenger'
+
include ':OCH:mogo-och-noop'
+
include(':OCH:mogo-och-common-module')
+include ':OCH:mogo-och-data'
+
include ':OCH:sweeper:sweeper'
include ':OCH:sweeper:sweeper-cloud'
+
include ':OCH:mogo-och-charter'
include ':OCH:mogo-och-charter-passenger'
+
include ':OCH:mogo-och-shuttle'
include ':OCH:mogo-och-shuttle-passenger'
-include ':OCH:mogo-och-data'
+
include ':core:function-impl:mogo-core-function-patch'