[MT8766][Android12] 使用谷歌LPA实现ESIM功能的流程

文章目录

    • 开发平台基本信息
    • 问题描述
    • 实现流程
  • 其他问题

开发平台基本信息

芯片: MT8766
版本: Android 12
kernel: msm-4.19

问题描述

客户需要我们设备支持ESIM功能,5月份的时候在高通6125上面预研过ESIM功能,当时ESIM供应商是Links field,集成流程只是内置了ESIM厂商的apk,并且开启了feature以及默认给了一些权限,具体ESIM功能的实现都是在厂商的apk中,所以就没去深入研究ESIM功能。但是,由于Links field报价过高,所以这次又找了两家ESIM厂商,分别是鹏越与紫光;鹏越只把他们的ESIM芯片寄给了我们,然后让我们去找GMS实验室要LPA的相关资料,按照谷歌的标准流程操作,即可实现ESIM功能;而紫光则提供了一个他们的apk,并且要求给权限与feature,与之前的Links field类似。GMS实验室提供了一份资料,里面包含了3份文档以及一个apk。
三份文档的内容大致为:

  • 1、如何集成LPA
  • 2、如何实现overlay app
  • 3、如何在开机向导和系统设置增加ESIM选项

ESIM功能可以简单理解为,ESIM厂家提供芯片,芯片分为贴片式跟拔插式,贴片式是贴到主板上,类似于各种单片机;而拔插式则是一张实体ESIM卡,长得跟普通的SIM卡一样,需要插入到卡槽中才能使用;然后,就到ESIM运营商购买ESIM卡号,安卓系统就可以通过谷歌LPA服务将购买的ESIM卡号下载到ESIM芯片中,下载完成启用ESIM卡就能正常使用了,一张ESIM芯片可以下载多个ESIM卡,但是,设备最多只能启用一张ESIM。

实现流程

在验证ESIM功能之前,可以先到设置-关于手机-sim卡详细信息中查看是否有EID,EID是ESIM芯片的唯一标识,代表着ESIM的正常使用,如果设备无法读取到EID,得排查硬件通路以及modem。

ESIM功能都实现流程可以分为以下几个步骤:

  • 启用euicc的feature
  • 内置谷歌LPA服务到system/priv-app/
  • 给LPA服务增加priv-app权限或者关闭权限校验
  • 增加overlay app
  • 在系统设置中,调起LPA服务下载ESIM卡号,并启用ESIM

framework中已经有euicc的feature,只需要拷贝到设备即可

--- a/device/mediateksample/custom_go/full_custom_go.mk
+++ b/device/mediateksample/custom_go/full_custom_go.mk
@@ -7,3 +7,11 @@ MTK_TARGET_PROJECT_FOLDER := $(LOCAL_PATH)-include $(MTK_TARGET_PROJECT_FOLDER)/vnd_$(MTK_TARGET_PROJECT).mkPRODUCT_NAME := full_custom_go+PRODUCT_COPY_FILES += \
+	frameworks/native/data/etc/android.hardware.telephony.euicc.xml:system/etc/permissions/android.hardware.telephony.euicc.xml \
+

内置谷歌LPA服务到system/priv-app/

--- a/device/mediateksample/p8_go/full_custom_go.mk
+++ b/device/mediateksample/p8_go/full_custom_go.mk
@@ -7,3 +7,11 @@ MTK_TARGET_PROJECT_FOLDER := $(LOCAL_PATH)-include $(MTK_TARGET_PROJECT_FOLDER)/vnd_$(MTK_TARGET_PROJECT).mkPRODUCT_NAME := full_custom_go
+
+PRODUCT_PACKAGES += \
+	EuiccGoogle \
+LOCAL_PATH := $(call my-dir)###############################################################################
include $(CLEAR_VARS)
LOCAL_MODULE 				:= EuiccGoogle
LOCAL_SRC_FILES 			:= EuiccGoogle.apk
LOCAL_MODULE_CLASS 			:= APPS
LOCAL_CERTIFICATE 			:= PRESIGNED
LOCAL_PRIVILEGED_MODULE 	:= true
LOCAL_MODULE_TAGS 			:= optional
include $(BUILD_PREBUILT)

给LPA服务增加priv-app权限或者关闭权限校验,这里选择的是关闭权限校验

--- a/frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -3469,6 +3469,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {@NonNull PackageSetting packageSetting, @NonNull Permission permission) {if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) {return true;
+        }else if (!RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) {
+            return true;}final String packageName = pkg.getPackageName();if (Objects.equals(packageName, PLATFORM_PACKAGE_NAME)) {

增加overlay app,这个app是自己写的,需要实现几个功能

  • 在AndroidManifest.xml中注册广播
        <receiverandroid:name=".PartnerReceiver"android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"android:directBootAware="true"android:exported="true"><intent-filter><action android:name="com.google.android.euicc.action.PARTNER_CUSTOMIZATION" /></intent-filter></receiver>
  • 在java文件中实现广播,并且广播方法中必须为空
package com.tp.euicc.overlay;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;public class PartnerReceiver extends BroadcastReceiver {public PartnerReceiver() {}@Overridepublic void onReceive(Context context, Intent intent) {}
}
  • res/values/strings.xml中增加两个字段
    <string name="sim_slot_mappings_json" translatable="false">{"sim-slot-mappings":[{"devices":["custom_go"],"esim-slot-ids":[0],"psim-slot-ids":[1]}]}</string><integer name="download_type">3</integer>

谷歌LPA就是通过广播找到overlay app,然后从app的资源文件中获取sim_slot_mappings_json的值,拿到配置数据,其中devices的值要修改为Build.DEVICE,如果是其他项目移植要记得修改。后面的esim是虚拟sim卡,psim是物理sim卡,ids的值分别是对应的卡槽,比如P8KR在SIM 1卡槽接了ESIM,这里就配成0,不过实际测试,不过怎么配置ids,都能使用ESIM。

在系统设置中,调起LPA服务下载ESIM卡号,并启用ESIM
按照上面的方式集成之后,在系统设置-网络-移动网络选项,如果没有下载过ESIM,点击就会调起谷歌LPA服务,或者可以通过adb广播调起LPA配置界面,然后根据提示,扫描二维码,下载ESIM卡号即可。

adb shell am start -n
"com.google.android.euicc/com.android.euicc.ui.settings.CurrentProfileListActivity"

其他问题

之前在2290上面调试,出现下载完ESIM卡号之后,无法启用ESIM功能,需要在ESIM界面开、关一次飞行模式,ESIM启用按钮才可以点击。解决方案如下:

--- a/QSSI.12/packages/apps/Settings/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/QSSI.12/packages/apps/Settings/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -58,6 +58,7 @@ import com.android.settingslib.search.SearchIndexable;import com.android.settingslib.utils.ThreadUtils;import org.codeaurora.internal.IExtTelephony;import java.util.Arrays;import java.util.List;
@@ -106,7 +107,8 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {private void setScreenState() {int simState = mTelephonyManager.getSimState();
-        boolean screenState = simState != TelephonyManager.SIM_STATE_ABSENT;
+        // boolean screenState = simState != TelephonyManager.SIM_STATE_ABSENT;
+        boolean screenState = true;if (screenState) {

在MTK8766中同样出现不可点击的问题,而且还把白卡显示出来,造成了混淆,解决方案如下:

--- a/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/network/MobileNetworkListController.java
+++ b/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/network/MobileNetworkListController.java
@@ -26,7 +26,9 @@ import android.content.Intent;import android.provider.Settings;import android.telephony.SubscriptionInfo;import android.telephony.SubscriptionManager;
+import android.telephony.euicc.EuiccManager;import android.util.ArrayMap;
+import android.util.Log;import androidx.lifecycle.Lifecycle;import androidx.lifecycle.LifecycleObserver;
@@ -122,7 +124,7 @@ public class MobileNetworkListController extends AbstractPreferenceController im} else {pref.setSummary(R.string.mobile_network_inactive_esim);/// M: Add for updating enabled state.
-                    pref.setEnabled(false);
+                    //pref.setEnabled(false);}} else {if (mSubscriptionManager.isActiveSubscriptionId(subId)) {
@@ -130,7 +132,7 @@ public class MobileNetworkListController extends AbstractPreferenceController im} else if (SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)) {pref.setSummary(mContext.getString(R.string.mobile_network_inactive_sim));/// M: Add for updating enabled state.
-                    pref.setEnabled(false);
+                    //pref.setEnabled(false);} else {pref.setSummary(mContext.getString(R.string.mobile_network_tap_to_activate,displayName));
@@ -138,7 +140,14 @@ public class MobileNetworkListController extends AbstractPreferenceController im}pref.setOnPreferenceClickListener(clickedPref -> {
-                if (!info.isEmbedded() && !mSubscriptionManager.isActiveSubscriptionId(subId)
+                Log.d(TAG, "clickedPref isEmbedded: " + (info.isEmbedded()));
+                               Log.d(TAG, "clickedPref isActiveSubscriptionId: " + (mSubscriptionManager.isActiveSubscriptionId(subId)));
+                Log.d(TAG, "clickedPref showToggleForPhysicalSim: " + (SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)));
+                               /// M: Add for updating enabled state.
+                               if(info.isEmbedded()){
+                                       Intent intent = new Intent(EuiccManager.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS);
+                                       mContext.startActivity(intent);
+                }else if (!info.isEmbedded() && !mSubscriptionManager.isActiveSubscriptionId(subId)&& !SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager)) {SubscriptionUtil.startToggleSubscriptionDialogActivity(mContext, subId, true);} else {
--- a/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/network/MobileNetworkSummaryController.java
+++ b/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/network/MobileNetworkSummaryController.java
@@ -258,8 +258,17 @@ public class MobileNetworkSummaryController extends AbstractPreferenceControllermPreference.setEnabled(false);}/// @}
-        } else {
-            mPreference.setFragment(MobileNetworkListFragment.class.getCanonicalName());
+        } else {                       
+                       /// M: Add for updating enabled state.
+                       mPreference.setOnPreferenceClickListener((Preference pref) -> {
+                logPreferenceClick(pref);
+
+                Intent intent = new Intent(EuiccManager.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS);
+                               mContext.startActivity(intent);
+                return true;
+            });
+                       
+            //mPreference.setFragment(MobileNetworkListFragment.class.getCanonicalName());}}
--- a/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -27,6 +27,7 @@ import android.provider.Settings;import android.provider.SearchIndexableResource;import android.telephony.SubscriptionManager;import android.telephony.TelephonyManager;
+import android.telephony.euicc.EuiccManager;import android.text.TextUtils;import android.util.Log;import android.view.Menu;
@@ -100,8 +101,12 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {return true;}final String key = preference.getKey();
+               
+               Intent intent = new Intent(EuiccManager.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS);
+               startActivity(intent);
+               return true;-        if (TextUtils.equals(key, BUTTON_CDMA_SYSTEM_SELECT_KEY)
+        /*if (TextUtils.equals(key, BUTTON_CDMA_SYSTEM_SELECT_KEY)|| TextUtils.equals(key, BUTTON_CDMA_SUBSCRIPTION_KEY)) {if (mTelephonyManager.getEmergencyCallbackMode()) {startActivityForResult(
@@ -112,7 +117,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {return true;}-        return false;
+        return false;*/}@Override
diff --git a/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/security/SimLockPreferenceController.java b/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/security/SimLockPreferenceController.java
index 3b85888..98cbc9b 100644
--- a/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/security/SimLockPreferenceController.java
+++ b/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/security/SimLockPreferenceController.java
@@ -94,10 +94,10 @@ public class SimLockPreferenceController extends BasePreferenceController {for (SubscriptionInfo subInfo : subInfoList) {final int simState = mTelephonyManager.getSimState(subInfo.getSimSlotIndex());
-            if ((simState != TelephonyManager.SIM_STATE_ABSENT)
-                    && (simState != TelephonyManager.SIM_STATE_UNKNOWN)) {
+            // if ((simState != TelephonyManager.SIM_STATE_ABSENT)
+            //         && (simState != TelephonyManager.SIM_STATE_UNKNOWN)) {return true;
-            }
+            // }}return false;}

MTK8766下载完ESIM卡号之后,有信号,能ping通百度,但是浏览器无法上网,最终定位是他们默认APN配置的问题

--- a/device/mediatek/config/apns-conf.xml
+++ b/device/mediatek/config/apns-conf.xml
@@ -25782,12 +25782,12 @@mcc="454"mnc="00"apn="mobile"
-       proxy="192.168.59.51"
-       port="8080"
-       mmsc="http://192.168.58.171:8002"
-       mmsproxy="192.168.59.51"
-       mmsport="8080"
-       type="default,supl,mms"
+       proxy=""
+       port=""
+       mmsc=""
+       mmsproxy=""
+       mmsport=""
+       type="default,ia,supl"protocol="IPV4V6"roaming_protocol="IPV4V6"/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/101381.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV4(C++)—— 视频和摄像头的加载、显示与保存

文章目录 一、加载与显示二、保存 一、加载与显示 视频或摄像头的加载是使用 cv::VideoCapture 类。&#xff08;这个类和 ifstream 类比较相似&#xff0c;视频或摄像头的加载和文本文件操作是大致相同。主要步骤&#xff1a;&#xff08;1&#xff09;加载&#xff08;打开&a…

Springboot接收http参数总结(最简单易懂)

1. 前端能携带请求参数的地方 http请求一半前端请求参数放在三个地方&#xff1a;请求头&#xff0c;请求查询参数&#xff08;Query String&#xff09;&#xff0c;请求体。 请求体需要获取HttpServletRequest对象才能获取。 2. 请求体常见格式 而请求体中可以存放多种格式…

深度学习-房价预测案例

1. 实现几个函数方便下载数据 import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)): #save"""下载…

架构师选择题--信息安全技术(系统安全)

架构师选择题--信息安全技术 真题 很少超纲 真题 b c d d b a d a d a Kergberos和数字证书是类似的协议 向TGS申请票据 C PGP&#xff1a;安全电子邮件传输协议 b c b 使用发送方是私钥加密摘要–发送方不可抵赖 加密&#xff1a;保密性 信息摘要&#xff1a;完整性 数…

闭包(C#)

通常来讲&#xff0c;大家一听到闭包&#xff0c;应该首先会想到JavaScript中的闭包&#xff0c;而不会想到C#中的闭包&#xff0c;但是C#中也是有闭包的&#xff0c;下面就让我来为大家仔细讲解讲解。 在C#中&#xff0c;我们通常知道变量作用域有三种&#xff1a;1、是属于类…

docker compose和consul(服务注册与发现)

一、Docker-compose 简介 Docker-Compose项目是基于Python开发的Docker官方开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是 工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&a…

登录页面怎么做渗透

1.用万能密码登录&#xff0c;看是否能登录成功 ‘ or 11# 2.注入漏洞 用burp抓包放在sqlmap里面跑&#xff0c;看是否有注入 3.查看是否有说明文档找文件下载漏洞 一般的链接形式 download.php?path download.php?filename down.php?file data.php?file 包含的参数 &…

Mabatis-puls强于Mybatis的地方

Mabatis-puls与Mybatis都是优秀的Java持久化框架&#xff0c;但是Mabatis-puls相较于Mybatis有以下几个方面的优势&#xff1a; 性能更优&#xff1a;Mabatis-puls采用了Javassist技术&#xff0c;使得它在运行时比Mybatis更快速&#xff0c;尤其是在执行大量SQL的情况下&#…

TensorFlow入门(二十一、softmax算法与损失函数)

在实际使用softmax计算loss时,有一些关键地方与具体用法需要注意: 交叉熵是十分常用的,且在TensorFlow中被封装成了多个版本。多版本中,有的公式里直接带了交叉熵,有的需要自己单独手写公式求出。如果区分不清楚,在构建模型时,一旦出现问题将很难分析是模型的问题还是交叉熵的使…

代码随想录算法训练营第23期day19| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

目录 一、&#xff08;leetcode 654&#xff09;最大二叉树 二、&#xff08;leetcode 617&#xff09;合并二叉树 三、&#xff08;leetcode 700&#xff09;二叉搜索树中的搜索 四、&#xff08;leetcode 98&#xff09;验证二叉搜索树 一、&#xff08;leetcode 654&…

Vega Prime入门教程14.01:调用VAPS XT DLL

本文首发于&#xff1a;Vega Prime入门教程14.01&#xff1a;调用VAPS XT DLL 在VAPS XT系列教程中提到过Vega Prime可以直接调用Drawing Integration生成的dll&#xff0c;本文来测试这个功能效果。 本系列使用的是VP18.0&#xff0c;使用的是VC14.0&#xff08;VS2015&…

Android Studio修改模拟器AVD Manger目录

Android Studio修改虚拟机AVD Manger目录 1、在AS的设备管理器Device Manager中删除原来创建的所有虚拟机&#xff08;Android Virtual Device&#xff09;&#xff1b; 2、新建一个自定义的AVD目录&#xff0c;例如&#xff1a;D:\Android\AndroidAVD 3、在高级系统设置中增加…

hive建表指定列分隔符为多字符分隔符实战(默认只支持单字符)

1、背景&#xff1a; 后端日志采集完成&#xff0c;清洗入hive表的过程中&#xff0c;发现字段之间的单一字符的分割符号已经不能满足列分割需求&#xff0c;因为字段值本身可能包含分隔符。所以列分隔符使用多个字符列分隔符迫在眉睫。 hive在建表时&#xff0c;通常使用ROW …

【Zookeeper专题】Zookeeper选举Leader源码解析

目录 前言阅读建议课程内容一、ZK Leader选举流程回顾二、源码流程图三、Leader选举模型图 学习总结 前言 为什么要看源码&#xff1f;说实在博主之前看Spring源码之前没想过这个问题。因为我在看之前就曾听闻大佬们说过【JavaCoder三板斧&#xff1a;Java&#xff0c;Mysql&a…

Arduino驱动LIS2DH三轴加速度传感器(惯性测量传感器篇)

目录 1、传感器特性 2、硬件原理图 3、控制器和传感器连线图 4、驱动程序 LIS2DH加速度计相对传统的ADXL345在稳定性以及功耗上都有一定的优化,低功耗模式下仅为2μA(普通模式11μA),并且最高支持5.3KHz输出频率,拥有2g/4g/8g/16g四档可选量程&

Kafka和RabbitMQ的对比

Rabbitmq比kafka可靠&#xff0c;kafka更适合IO高吞吐的处理&#xff0c;比如ELK日志收集 Kafka和RabbitMq一样是通用意图消息代理&#xff0c;他们都是以分布式部署为目的。但是他们对消息语义模型的定义的假设是非常不同的。 a) 以下场景比较适合使用Kafka。如果有大量的事…

程序员不写注释的原因及解决方案

目录 一、原因说明 二、问题分析 三、解决方案 在软件开发领域&#xff0c;注释的重要性不言而喻。它们不仅可以提高代码的可读性&#xff0c;还能帮助其他开发者更好地理解代码逻辑。然而&#xff0c;我们常常发现许多程序员在编写代码时并不喜欢添加注释。那么&#xff0c…

MAC 版PowerPoint 插入latex数学公式

参考链接&#xff1a; [IguanaTex Mac] PPT 中快捷导入LaTeX公式 - 知乎

Linux shell编程学习笔记9:字符串运算 和 if语句

Linux Shell 脚本编程和其他编程语言一样&#xff0c;支持算数、关系、布尔、字符串、文件测试等多种运算&#xff0c;同样也需要进行根据条件进行流程控制&#xff0c;提供了if、for、while、until等语句。 上期学习笔记中我们研究了字符串数据的使用&#xff0c;今天我们研…

cf 1886A

题目是输入一个数字&#xff0c;分解成三个数字的和&#xff0c;这三个数字都不相同&#xff0c;并且都不可以被三整除&#xff0c;如果存在输出YES并且输出任意一组可能的三个数字&#xff0c;否则输出NO 代码 #include<bits/stdc.h> using namespace std;int main() …