BCP_IS中的权限问题

权限表及相关内容大体可以用六个表来描述,如下:
1 角色(即用户组)表:包括三个字段,ID,角色名,对该角色的描述;
2 用户表:包括三个或以上字段,ID,用户名,对该用户的描述,其它(如地址、电话等信息);
3 角色-用户对应表:该表记录用户与角色之间的对应关系,一个用户可以隶属于多个角色,一个角色组也可拥有多个用户。包括三个字段,ID,角色ID,用户ID;
4 限制内容列表:该表记录所有需要加以权限区分限制的数据表、功能和字段等内容及其描述,包括三个字段,ID,名称,描述;
5 权限列表:该表记录所有要加以控制的权限,如录入、修改、删除、执行等,也包括三个字段,ID,名称,描述;
6 权限-角色-用户对应表:一般情况下,我们对角色/用户所拥有的权限做如下规定,角色拥有明令允许的权限,其它一律禁止,用户继承所属角色的全部权限,在此范围内的权限除明令禁止外全部允许,范围外权限除明令允许外全部禁止。 
最容易理解的方法,设计五个字段:ID,限制内容ID,权限ID,角色/用户类型(布尔型字段,用来描述一条记录记录的是角色权限还是用户权限),角色/用户ID,权限类型(布尔型字段,用来描述一条记录表示允许还是禁止)
或者说,这么设计已经足够了,我们完全实现了所需要的功能:可以对角色和用户分别进行权限定制,也具有相当的可扩展性,比如说增加了新功能,我们只需要添加一条或者几条记录就可以,同时应用程序接口也无须改动,具有相当的可行性。但是,在程序实现的过程中,我们发现,使用这种方法并不是十分科学,例如浏览某个用户所拥有的权限时,需要对数据库进行多次(甚至是递归)查询,极不方便。于是我们需要想其它的办法。使用过Unix系统的人们都知道,Unix文件系统将对文件的操作权限分为三种:读、写和执行,分别用1、2、4三个代码标识,对用户同时具有读写权限的文件被记录为3,即1+2。我们也可以用类似的办法来解决这个问题。初步的想法是修改权限列表,加入一个字段:标识码,例如,我们可以将录入权限标识为1,浏览权限标识为2,修改权限标识为4,删除权限标识为8,执行权限标识为16,这样,我们通过权限累加的办法就可以轻易的将原本要分为几条记录描述的权限放在一起了,例如,假定某用户ID为1,库存表对应的限制内容ID为2,同时规定角色类型为0、用户类型为1,我们就可以将该用户具有录入、浏览、修改、删除库存表的权限描述为:2,15,1,1。
从表面上看,上述方法足以达到实现功能、简化数据库设计及实现的复杂度这个目的,但这样做有个弊端,我们所涉及的权限列表不是相互独立而是互相依赖的,比如说修改权限,其实是包含浏览权限的,例如,我们可能只是简单的设置用户对库存表存取的权限值为录入+修改+删除(1+4+8=13),但事实上,该用户具有(1+2+4+8=15)的权限,也就是说,在这种方案中,13=15。于是当我们调用API询问某用户是否具有浏览权限时,就必须判断该用户是否具有对该数据表的修改权限,因此,如果不能在程序中固化权限之间的包含关系,就不能利用应用程序接口简单的做出判断。但这与我们的目的“充分的可扩展性”矛盾。

这个问题如何解决?我想到了另外一种设置标识码的方法,那就是利用素数。我们不妨将录入、浏览、修改、删除、执行的基本标志码定为2,3,5,7,11,当遇到权限互相包含的时候,我们将它的标识码设定为两个(或多个)基本标志码的乘积,例如,可以将“修改”功能的标志码定为3*5=15,然后将所有的权限相乘,就得到了我们需要的最终权限标识值。这样,我们在询问用户是否具有某项权限的时候,只需要将最终的值分解成质因子,例如,我们可以定义一个用户具有录入+修改+删除库存表的权限为 2*15*7=2*3*5*7,即表示,该用户具有了对库存表录入+浏览+修改+删除权限。

当然,对权限列表我们使用上述方法的前提是权限列表记录条数不会太多并且关系不是十分复杂,否则,光是解析权限代码就要机器忽悠半宿:)

我希望以上的分析是正确且有效的(事实上,我也用这些的方法在不止一套系统中实现),但无论如何,我觉得如此实现权限管理,只是考虑了数据库设计和应用程序接口两部分内容,对于实现,还是显得很费劲。因此,我恳请有过类似设计、实现经验的同志们提出建设性的意见和修改建议。

bool OatFileAssistant::ValidateBootClassPathChecksums(OatFileAssistantContext* ofa_context, 799 InstructionSet isa, 800 std::string_view oat_checksums, 801 std::string_view oat_boot_class_path, 802 /*out*/ std::string* error_msg) { 803 const std::vector<std::string>& bcp_locations = 804 ofa_context->GetRuntimeOptions().boot_class_path_locations; 805 806 if (oat_checksums.empty() || oat_boot_class_path.empty()) { 807 *error_msg = oat_checksums.empty() ? "Empty checksums" : "Empty boot class path"; 808 return false; 809 } 810 811 size_t oat_bcp_size = gc::space::ImageSpace::CheckAndCountBCPComponents( 812 oat_boot_class_path, ArrayRef<const std::string>(bcp_locations), error_msg); 813 if (oat_bcp_size == static_cast<size_t>(-1)) { 814 DCHECK(!error_msg->empty()); 815 return false; 816 } 817 DCHECK_LE(oat_bcp_size, bcp_locations.size()); 818 819 size_t bcp_index = 0; 820 size_t boot_image_index = 0; 821 bool found_d = false; 822 823 while (bcp_index < oat_bcp_size) { 824 static_assert(gc::space::ImageSpace::kImageChecksumPrefix == 'i', "Format prefix check"); 825 static_assert(gc::space::ImageSpace::kDexFileChecksumPrefix == 'd', "Format prefix check"); 826 if (oat_checksums.starts_with("i") && !found_d) { 827 const std::vector<OatFileAssistantContext::BootImageInfo>& boot_image_info_list = 828 ofa_context->GetBootImageInfoList(isa); 829 if (boot_image_index >= boot_image_info_list.size()) { 830 *error_msg = StringPrintf("Missing boot image for %s, remaining checksums: %s", 831 bcp_locations[bcp_index].c_str(), 832 std::string(oat_checksums).c_str()); 833 return false; 834 } 835 836 const OatFileAssistantContext::BootImageInfo& boot_image_info = 837 boot_image_info_list[boot_image_index]; 838 if (!ConsumePrefix(&oat_checksums, boot_image_info.checksum)) { 839 *error_msg = StringPrintf("Image checksum mismatch, expected %s to start with %s", 840 std::string(oat_checksums).c_str(), 841 boot_image_info.checksum.c_str()); 842 return false; 843 } 844 845 bcp_index += boot_image_info.component_count; 846 boot_image_index++; 847 } else if (oat_checksums.starts_with("d")) { 848 found_d = true; 849 const std::vector<std::string>* bcp_checksums = 850 ofa_context->GetBcpChecksums(bcp_index, error_msg); 851 if (bcp_checksums == nullptr) { 852 return false; 853 } 854 oat_checksums.remove_prefix(1u); 855 for (const std::string& checksum : *bcp_checksums) { 856 if (!ConsumePrefix(&oat_checksums, checksum)) { 857 *error_msg = StringPrintf( 858 "Dex checksum mismatch for bootclasspath file %s, expected %s to start with %s", 859 bcp_locations[bcp_index].c_str(), 860 std::string(oat_checksums).c_str(), 861 checksum.c_str()); 862 return false; 863 } 864 } 865 866 bcp_index++; 867 } else { 868 *error_msg = StringPrintf("Unexpected checksums, expected %s to start with %s", 869 std::string(oat_checksums).c_str(), 870 found_d ? "'d'" : "'i' or 'd'"); 871 return false; 872 } 报这个artd : GetBestInfo: odex next to the dex file (/system_ext/priv-app/OplusLauncher/oat/arm64/OplusLauncher.odex) is kOatBootImageOutOfDate with filter 'speed-profile' executable 'false': Missing boot image for /apex/com.android.adservices/javalib/framework-adservices.jar, remaining checksums: i;29/08499db2为什么
11-15
<think> 我们正在处理一个关于Android运行时(ART)的错误日志。错误信息如下: 'artd : GetBestInfo: odex next to the dex file (/system_ext/priv-app/OplusLauncher/oat/arm64/OplusLauncher.odex) is kOatBootImageOutOfDate with filter 'speed-profile' executable 'false': Missing boot image for /apex/com.android.adservices/javalib/framework-adservices.jar, remaining checksums: i;29/08499db2' 这个错误是由ART守护进程(artd)在尝试获取一个odex文件的最佳信息时发生的。错误状态为`kOatBootImageOutOfDate`,原因是缺少一个boot image文件:`/apex/com.android.adservices/javalib/framework-adservices.jar`。 ### 错误原因分析 1. **Boot Image的作用**:在ART中,boot image包含了系统启动时预加载的类和方法的编译代码。它通常包括核心库(如`framework.jar`)和关键APEX模块中的类。当应用运行时,如果它们的dex/odex文件依赖于boot image,就需要匹配的boot image存在,否则会导致验证失败。 2. **错误原因**:错误信息明确指出缺少`/apex/com.android.adservices/javalib/framework-adservices.jar`的boot image。这意味着在生成`OplusLauncher.odex`文件时,它引用了`framework-adservices.jar`中的类,并且这些类被期望在boot image中。但是,当前的boot image中没有包含这个jar文件。 3. **为什么会出现这个错误?**:可能的原因包括: - **系统更新问题**:在系统更新后,boot image可能没有重新生成,或者更新过程中部分模块的boot image生成失败。 - **模块依赖问题**:`OplusLauncher`应用(可能是Oppo的启动器)依赖于`com.android.adservices`模块(提供广告服务),但广告服务模块可能没有正确安装或更新,导致其boot image缺失。 - **编译配置问题**:在构建系统镜像时,可能没有将`framework-adservices.jar`包含在boot classpath中,因此它没有被编译进boot image。 4. **具体错误信息解读**: - `odex next to the dex file`: 指的是与dex文件同目录下的odex文件(即`/system_ext/priv-app/OplusLauncher/oat/arm64/OplusLauncher.odex`)。 - `kOatBootImageOutOfDate`: 表示这个odex文件所依赖的boot image已经过时(或者更具体地说,缺少所需的boot image)。 - `Missing boot image for ...`: 明确指出了缺失的boot image对应的jar文件路径。 - `remaining checksums: i;29/08499db2`:这是对缺失的boot image的校验和,用于验证。 ### 解决方法 1. **重新生成boot image**:可以尝试重新生成boot image,确保包含所有必需的模块。在Android设备上,这通常需要重新启动设备并触发boot image的重新编译。可以尝试清除`dalvik-cache`并重启: ```bash adb shell cmd package compile -f -m speed-profile com.android.adservices adb reboot ``` 注意:这需要设备有root权限或者是在调试版本上。 2. **更新或重新安装相关模块**:检查`com.android.adservices`模块是否正常。可以尝试更新或重新安装该APEX模块。 3. **检查系统完整性**:如果是系统更新后出现的问题,可能是更新不完整。尝试重新刷入完整的系统镜像。 4. **等待系统自动修复**:ART在下次设备空闲时可能会尝试重新编译。可以等待一段时间,或者重启设备多次,看问题是否消失。 5. **联系设备厂商**:如果上述方法无效,可能是设备厂商的系统构建问题,建议联系设备厂商获取支持。 ### 相关引用 在Android ART中,boot image的生成和验证是确保应用运行性能和安全的重要机制[^1]。当依赖的boot image缺失时,系统会拒绝使用预先编译的odex文件,转而解释执行或尝试重新编译,这可能导致应用启动变慢[^2]。 [^1]: [Android ART Boot Image](https://source.android.com/devices/tech/dalvik/configure#boot_image) [^2]: [Understanding the Android Runtime (ART)](https://source.android.com/devices/tech/dalvik) §§相关问题§§ 1. 如何手动生成Android设备的boot image? 2. 什么是APEX模块?它们如何影响Android系统? 3. ART中的dex2oat工具的作用是什么? 4. 如何解决Android应用启动时的性能问题? </think> 这个错误信息表明 Android 运行时环境(ART)在处理 OplusLauncher 应用的优化代码时遇到了问题,具体原因是缺少关键的系统组件。以下是详细分析: ### 错误原因分析 1. **Boot Image 缺失(核心问题)**: - 错误信息 `Missing boot image for /apex/com.android.adservices/javalib/framework-adservices.jar` 表明 ART 运行时缺少必要的启动镜像文件 - `framework-adservices.jar` 是 Android 广告服务(AdServices)模块的核心库,属于 Android APEX 动态模块 - 当 ART 尝试优化应用时,需要这些核心库的预编译版本来验证代码兼容性[^1] 2. **OAT 文件状态异常**: - `kOatBootImageOutOfDate` 表示 `/system_ext/priv-app/OplusLauncher/oat/arm64/OplusLauncher.odex` 这个优化文件依赖的启动镜像已过期 - `speed-profile` 表明系统尝试使用性能分析数据进行优化,但因依赖缺失而失败 3. **根本原因可能性**: - **系统更新不完整**:AdServices APEX 模块未正确更新或损坏 - **厂商定制问题**:OplusLauncher(Oppo 系设备专有)与 Android 原生组件存在兼容性问题 - **分区损坏**:`/apex` 或 `/system_ext` 分区数据损坏 - **跨版本兼容**:系统升级后残留旧版优化文件 ### 解决方案 1. **清除 ART 缓存**: ```bash adb shell pm art cleanup adb reboot ``` 这会强制 ART 在下次启动时重新生成优化文件[^2] 2. **更新/修复 AdServices 模块**: ```bash adb shell cmd package update-adservices adb reboot ``` 3. **检查分区完整性**: ```bash adb shell df /apex adb shell ls -l /apex/com.android.adservices ``` 确认 APEX 模块完整存在(应有 20-50MB 左右) 4. **完整系统更新**: - 重新刷入完整的官方系统镜像,特别是 `adservices.apex` 和系统扩展分区 5. **临时规避方案**: ```bash adb shell settings put global speed_profile_enabled 0 adb reboot ``` 禁用性能分析优化模式(可能影响应用启动速度) > **注意**:此错误通常出现在 Android 12+ 的设备上,尤其是厂商定制系统(如 ColorOS)与 Android 原生模块集成时出现兼容性问题。如果问题持续,可能需要等待厂商推送系统更新修复[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值