【转】 android cts failed items

本文针对常见的CTS测试问题提供了解决方案,包括设置问题、权限问题、网络问题等,并介绍了如何处理摄像头测试、系统文件权限等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Fail的一些修改

 

1、直接设置问题

estUnknownSourcesOffByDefault

fail

junit.framework.AssertionFailedError: Deviceshould not ship with 'Unknown Sources' enabled by default.expected:<0> butwas:<1> atandroid.provider.cts.Settings_SecureTest.testUnknownSourcesOffByDefault(Settings_SecureTest.java:183)

这种fail最好解决,直接按照字面理解就OK,设置---安全---默认关闭:未知来源

 

 

2、permission

-- testSensorFeatures

fail

junit.framework.AssertionFailedError:PackageManager#hasSystemFeature(android.hardware.sensor.accelerometer)returns true but SensorManager#getSensorList(1) shows sensors []expected:<true> butwas:<false> atandroid.app.cts.SystemFeaturesTest.assertFeatureForSensor(SystemFeaturesTest.java:300)

一般情况修改 - > frameworks/base/data/etc/*.xml 文件,例如
android.hardware.camera.xml,platform.xml等文件,这边的文件定义了设备具有的一些权限。

--------------------------------------------------------------------------------------------------------------------

 android.app.cts.SystemFeaturesTest#testSensorFeatures FAIL
junit.framework.AssertionFailedError: PackageManager#hasSystemFeature(android.hardware.sensor.light) returns true but SensorManager#getSensorList(5) shows sensors [] expected:<true> but was:<false>

原因:手机无光感
解决方法:去除..\mediatek\config\{PROJECT}\android.hardware.sensor.light.xml及
                   android.hardware.sensor.proximity.xml文件中相应选项

 

3、由测试而引起的非测试项出错

-- testRecordingHint

fail

java.lang.RuntimeException: start failed. atandroid.media.MediaRecorder.start(Native Method)

这种情况要根据Logcat去查看RuntimeException的具体错误。通常可以先不改,因为很难查错。

 

 

4、网络问题

-- test_isReachable

fail

java.net.UnknownHostException: Unable to resolvehost "www.google.com": No address associated with hostname atjava.net.InetAddress.lookupHostByName(InetAddress.java:426)

这类问题是由于国内的网络无法访问国外网站导致的,最好的办法就在公司搭建一个VPN,链接出去。

 

 

 

 

5、系统文件权限

-- testAllFilesInSysAreNotWritable

fail

junit.framework.AssertionFailedError: Foundwritable:

[/sys/devices/platform/malata_ts.0/tsclass/tsclass0/ts_power,/sys/devices/platform/malata_ts.0/tsclass/tsclass0/ts_en_file,/sys/devices/platform/malata_ts.0/tsclass/tsclass0/ts_Calibrate] atandroid.permission.cts.FileSystemPermissionTest.

testAllFilesInSysAreNotWritable(FileSystemPermissionTest.java:364)

-- testNoSetuidTcpdump

fail

junit.framework.AssertionFailedError at

android.security.cts.BannedFilesTest.

assertNotSetugid(BannedFilesTest.java:59)

这些问题是系统文件权限的问题,解决方法比较土,就是全局搜索该文件,查看那些对该文件操作的脚本,然后修改即可。

上面两个fail的解决方法是:

a.   修改kernel/drivers/input/touchscreen/malata_ts.c

__ATTR(ts_power, 0777, NULL,ts_set_point),

__ATTR(ts_en_file, 0777, NULL,ts_set_point),

__ATTR(ts_ Calibrate, 0777,NULL, ts_set_point),

b.   修改system/core/include/private/android-filesystem-config.h

{ 06755, ADD_ROOT, ADD_ROOT,“system/xbin/tcpdump”}

-------------------------------------------------------------------------------------------------

android.app.cts.SystemFeaturesTest
-- testLocationFeatures
fail
junit.framework.AssertionFailedError: PackageManager#hasSystemFeature should NOT return true for android.hardware.location.networkat android.app.cts.SystemFeaturesTest.assertNotAvailable(SystemFeaturesTest.java:375)

原因:未配置相对应功能(开启Location access中所有开关(gps和wifi))
解决方法:将..\frameworks\base\data\etc\android.hardware.location.gps.xml拷贝

                     ..\mediatek\config\{PROJECT}\android.hardware.location.gps.xml目录下并做修改
                  <permissions>
                         <feature name="android.hardware.location" />  ----打开
                         <feature name="android.hardware.location.network" />   ----打开
                         <feature name="android.hardware.location.gps" />   ---无GPS则关此项
                </permissions>

 

 

6、这种情况最多的。

-- testFocusDistances

fail

junit.framework.ComparisonFailure:expected:<infinity> butwas:<auto> at

android.hardware.cts.CameraTest.testFocusDistancesByCamera

(CameraTest.java:1386)

对于这个fail的原因是CTS对摄像头测试时,对摄像头进行参数设置,然后在读取参数后,参数出错。

这种情况要找到CameraTest源码,通常在source/cts/...下面,我们编译时没有编译到这里,仅查看代码,例如找到CameraTest.java,打开后找到1386行,行数一般情况下不会有出入,除非source下面的cts版本和下载的cts版本不一致才会找不到,找到testFocusDistancesByCamera,然后根据代码查看具体的测试,然后在找camera的源代码,使用Log跟踪,当然这个测试一定要结合做该模块的人一起改才行,不然很容易引起其他问题。

 

其中camera CTS测试代码在:

source/cts/tests/tests/hardware/src/android/hardware/cts/CameraTest.java

摄像头设置的相关代码在:Source/device/Samsung/exynos4/libcamera/下面,有SecCameraHWInterface_zoom.cpp、SecCameraHWInterface_zoom.h、SecCamera_zoom.cpp、SecCamera_zoom.h

找到之后通过修改后测试再修改后再测试直到CTS PASS。

(对于摄像头,应注意是几个摄像头,不然测试可能会对两个一起测试,这样就算一个摄像头调好了,能PASS了,另外一个过不了也是FAIL的。)

---------------------------------------------------------------------------

android.app.cts.SystemFeaturesTest#testCameraFeatures FAIL
junit.framework.AssertionFailedError: PackageManager#hasSystemFeature should NOT return true for android.hardware.camera.autofocus
原因:手机无自动对焦功能  
解决方法:去除..\mediatek\config\{PROJECT}\android.hardware.camera.xml文件中
                  <feature name="android.hardware.camera.autofocus" />



7.Android.app.cts.SystemFeaturesTest#testLocationFeatures
該項是測試設備利用無線網絡信號進行粗略定位的功能
Root Cause: 缺少 google 网络定位的服务包 NetworkLocation.apk ,但是机器用 getSystemFeature 依然有这项功能。
Solution :要么移植服务包 , 要么 disable systemFeature 。我暂时选择后者。将 /framework/base/data/etc/ 目录下 xml 文件里面的所有 .” android.hardware.location.network 注释掉即通
 
8.Android.holo.cts.HoloTest
該項是測試設備显示的 widget view 是否跟他提供的图片相一致,精确到像素点。
Root Cause: 分辨率设置问题
Solution :将修改 build.prop

ro.sf.lcd_density=160可以通过测试,但是Blaze Launcher菜单显示不能全屏,考虑修改api

 

9.Android.mediastress
該項是測試設備能否正常播放 google 提供的视频文件
Root Cause: 确定是否将 cts -media copy sdcard 目录、确定是否正常播放视频文件。 不能正常扫描播放,可能是视频驱动 问题
Solution :将 cts -media 文件放到 sdcard , 检文件能正常扫描播放,测试通过。
 
10.Android.permissin.cts.DebugableTest#testNoDebuggable
该項是測試相应的 app 是否有 debugable 的标志
Root Cause:AndroidManifest 文件里面 android:debuggable =“true”
Solution :将 android:debuggable =“true” 改为 false
 
11.Android.security.cts.PackageSignatureTest#testPackageSignatures
該項是測試应用包是否使用 google 默认的签名文件
Root Cause: 使用默认的签名编译 code
Solution build/target/product/security/ 下面的签名换成自己做的。做法在该目录下 README 有详细说明

 

12.Libcore cts部分

Libcore cts 部分主要测试的是设备里面 java api 是否正常工作。当某部分异常的时候, cts 对该项测试就会失败。
根据实际的工作成果,得出一般 libcore 测试失败大部分都跟你 cts 配置是否正确有关,而不是 java api 存在问题,比如测试之前是否 factory reset 就会影响其部分测试结果。所以在尝试各种方法无果后,进行一下 reset 可能它就能过。以下是我做过的一些 cts debug 项。
1>.Libcore.java.text.dataFormateSymbolsTest
# test_getInstance_invalid_locale
Root Cause:
Solution :执行 factory reset 后, pass
 
2>.Libcore.java.text.SimpleDateFormateTest#testNonDstZoneNameWithDstTimestamp
Root Cause: 该测试失败原因是因为 java SimpleDateFormate 类无法解析 Daylight time 夏令时区造成的
Solution :追 api 无果下, factory reset Daylight 时区正常解析, pass
 
3>.Libcore.java.util.OldTimeZoneTest
Root Cause:java 无法解析 daylight 夏令时区造成
Solution factory reset
 
4>.Org.apache.harmony.luny.tests.java.net.URLConnectionTest#test_getAllowUserInteraction
Root Cause:java 无法连接 onearth.jpl.nasa.gov 网站造成, nexus 机器同样无法通过该测试
Solution :无解。 Google 在新版本的 cts 测试中已经去掉连接该网站的逻辑部分。

13、DisplayRefreshRateTest
android.view.cts.DisplayRefreshRateTest
-- testRefreshRate
fail
junit.framework.AssertionFailedError at android.view.cts.DisplayRefreshRateTest.testRefreshRate(DisplayRefreshRateTest.java:168)
A3.关于这个刷帧率的问题,采用临时修改的方法
./frameworks/base/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp下在硬件初始化阶段
  1. mRefreshRate = fbDev->fps-5;  
  1. mRefreshRate = fbDev->fps-5;  
调整为:
  1. mRefreshRate = fbDev->fps-4;  
  1. mRefreshRate = fbDev->fps-4; 
14、
Compatibility Test Package: android.permission
TestResultDetails
android.permission.cts.FileSystemPermissionTest
-- testAllFilesInSysAreNotWritablefailjunit.framework.AssertionFailedError: Found writable: [/sys/devices/virtual/input/input3/enable_ps, /sys/devices/pci0000:00/0000:00:03.4/i2c-5/5-0068/delay, /sys/devices/virtual/input/input3/delay_ps, /sys/devices/virtual/input/input3/enable_als, /sys/devices/virtual/input/input3/delay_als, /sys/devices/pci0000:00/0000:00:03.4/i2c-5/5-0068/enable, /sys/devices/virtual/input/input3/enable_gs] at android.permission.cts.FileSystemPermissionTest.testAllFilesInSysAreNotWritable(FileSystemPermissionTest.java:577)

将相应的delay_ps这些文件进行设置权限,rw-r-r


15、

Compatibility Test Package: android.view
TestResultDetails
android.view.cts.DisplayRefreshRateTest
-- testRefreshRatefailjunit.framework.AssertionFailedError at android.view.cts.DisplayRefreshRateTest.testRefreshRate(DisplayRefreshRateTest.java:198)
可以从Log中看到需要设置的刷新率的大小。需要让驱动修改该值


16、

android.media.cts.StreamingMediaPlayerTest
-- testHLSfailjunit.framework.AssertionFailedError: Stream did not play successfully after all attempts at android.media.cts.MediaPlayerTestBase.playVideoWithRetries(MediaPlayerTestBase.java:196)
-- testHTTP_H264Base_AAC_Video1failTest failed to run to completion. Reason: 'Instrumentation run failed due to 'junit.framework.AssertionFailedError''. Check device logcat for details
-- testHTTP_H264Base_AAC_Video2failTest failed to run to completion. Reason: 'Instrumentation run failed due to 'junit.framework.AssertionFailedError''. Check device logcat for details
HLS测试是这样:带宽分为200000,360000,500000, 800000, 1200000,客户端会根据当前获取的带宽值选择是否播放高清还是普通视频,
公司的带宽比较大,但实际真正的带宽可能会小好多,导致去播放高清视频是会很卡,然后失败
解决方法:
参考8x25平台做法,在 system.prop 里面对带宽做限制:
media.httplive.max-bw = 360000   
最大带宽限制在360000,这样,测试HLS的时候,就只会去播放200000的普通视频,基本可以通过。
/*This file has been modified by Unisoc (Shanghai) Technologies Co., Ltd in 2024. * * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "recovery_utils/roots.h" #include <fcntl.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <iostream> #include <string> #include <vector> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android-base/unique_fd.h> #include <ext4_utils/ext4_utils.h> #include <ext4_utils/wipe.h> #include <fs_mgr.h> #include <fs_mgr/roots.h> #include "otautil/sysutil.h" //hook #include <include/hook/librecovery_utils_stubs.h> using android::fs_mgr::Fstab; using android::fs_mgr::FstabEntry; using android::fs_mgr::ReadDefaultFstab; using android::base::ReadFileToString; static Fstab fstab; constexpr const char* CACHE_ROOT = "/cache"; void load_volume_table() { if (!ReadDefaultFstab(&fstab)) { LOG(ERROR) << "Failed to read default fstab"; return; } fstab.emplace_back(FstabEntry{ .blk_device = "ramdisk", .mount_point = "/tmp", .fs_type = "ramdisk", .length = 0, }); std::cout << "recovery filesystem table" << std::endl << "=========================" << std::endl; for (size_t i = 0; i < fstab.size(); ++i) { auto& entry = fstab[i]; if (strcmp(entry.mount_point.c_str(), "/storage/sdcard0") == 0) load_volume_table_impl(entry); std::cout << " " << i << " " << entry.mount_point << " " << " " << entry.fs_type << " " << entry.blk_device << " " << entry.length << std::endl; } std::cout << std::endl; } Volume* volume_for_mount_point(const std::string& mount_point) { return android::fs_mgr::GetEntryForMountPoint(&fstab, mount_point); } // Mount the volume specified by path at the given mount_point. int ensure_path_mounted_at(const std::string& path, const std::string& mount_point) { return android::fs_mgr::EnsurePathMounted(&fstab, path, mount_point) ? 0 : -1; } int ensure_path_mounted(const std::string& path) { // Mount at the default mount point. return android::fs_mgr::EnsurePathMounted(&fstab, path) ? 0 : -1; } int ensure_path_unmounted(const std::string& path) { return android::fs_mgr::EnsurePathUnmounted(&fstab, path) ? 0 : -1; } static int exec_cmd(const std::vector<std::string>& args) { CHECK(!args.empty()); auto argv = StringVectorToNullTerminatedArray(args); pid_t child; if ((child = fork()) == 0) { execv(argv[0], argv.data()); _exit(EXIT_FAILURE); } int status; waitpid(child, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { LOG(ERROR) << args[0] << " failed with status " << WEXITSTATUS(status); } return WEXITSTATUS(status); } static int64_t get_file_size(int fd, uint64_t reserve_len) { struct stat buf; int ret = fstat(fd, &buf); if (ret) return 0; int64_t computed_size; if (S_ISREG(buf.st_mode)) { computed_size = buf.st_size - reserve_len; } else if (S_ISBLK(buf.st_mode)) { uint64_t block_device_size = get_block_device_size(fd); if (block_device_size < reserve_len || block_device_size > std::numeric_limits<int64_t>::max()) { computed_size = 0; } else { computed_size = block_device_size - reserve_len; } } else { computed_size = 0; } return computed_size; } //#wangfengqiu@HQ, 2024/03/28, Add for: nuovo shield recovery clear data plan start bool forbiddenRecoveryByReserveProperty() { std::string content; std::vector<std::string> reserve2_property_path = { "/nuovo/productinfo/nuovo_forbidden_recovery.prop", // 原Nuovo路径 "/nuovo/productinfo/MACROPAY_forbidden_recovery.prop", // 新增MACROPAY路径 }; //Fstab defFstab; /*if (!ReadDefaultFstab(&defFstab)) { printf("Failed to read default fstab productinfo\n"); return false; }*/ //for (size_t i = 0; i < defFstab.size(); ++i) { //const auto& entry = defFstab[i]; //std::string::size_type pos = entry.blk_device.find("productinfo"); //if ((pos != std::string::npos) && (ensure_path_mounted(entry.mount_point.c_str()) == 0)) { //printf("mount productinfo success,mount point is %s \n", entry.mount_point.c_str()); for (const auto& path : reserve2_property_path) { if (android::base::ReadFileToString(path, &content) && (content.find("opporeserve.sys.custom.recovery.forbidden=1") != std::string::npos)) { printf("found forbidden recovery prop in %s! \n", path.c_str()); return true; } /* if (android::base::ReadFileToString(reserve2_property_path, &content) && (content.find("opporeserve.sys.custom.recovery.forbidden=1") != std::string::npos)) { printf("reserve found forbidden recovery prop! \n"); return true; }*/ //break; //} //} } printf("no forbidden prop found in reserve!\n"); return false; } //end of Start specific code //#endif /* VENDOR_EDIT */ int format_volume(const std::string& volume, const std::string& directory, std::string_view new_fstype) { const FstabEntry* v = android::fs_mgr::GetEntryForPath(&fstab, volume); if (v == nullptr) { LOG(ERROR) << "unknown volume \"" << volume << "\""; return -1; } if (v->fs_type == "ramdisk") { LOG(ERROR) << "can't format_volume \"" << volume << "\""; return -1; } if (v->mount_point != volume) { LOG(ERROR) << "can't give path \"" << volume << "\" to format_volume"; return -1; } if (ensure_path_unmounted(volume) != 0) { LOG(ERROR) << "format_volume: Failed to unmount \"" << v->mount_point << "\""; return -1; } if (v->fs_type != "ext4" && v->fs_type != "f2fs") { LOG(ERROR) << "format_volume: fs_type \"" << v->fs_type << "\" unsupported"; return -1; } bool needs_casefold = false; if (volume == "/data") { needs_casefold = android::base::GetBoolProperty("external_storage.casefold.enabled", false); } int64_t length = 0; if (v->length > 0) { length = v->length; } else if (v->length < 0) { android::base::unique_fd fd(open(v->blk_device.c_str(), O_RDONLY)); if (fd == -1) { PLOG(ERROR) << "format_volume: failed to open " << v->blk_device; return -1; } length = get_file_size(fd.get(), -v->length); if (length <= 0) { LOG(ERROR) << "get_file_size: invalid size " << length << " for " << v->blk_device; return -1; } } // If the raw disk will be used as a metadata encrypted device mapper target, // next boot will do encrypt_in_place the raw disk. While fs_mgr mounts /data // as RO to avoid write file operations before encrypt_inplace, this code path // is not well tested so we would like to avoid it if possible. For safety, // let vold do the formatting on boot for metadata encrypted devices, except // when user specified a new fstype. Because init formats /data according // to fstab, it's difficult to override the fstab in init. if (!v->metadata_key_dir.empty() && length == 0 && new_fstype.empty()) { android::base::unique_fd fd(open(v->blk_device.c_str(), O_RDWR)); if (fd == -1) { PLOG(ERROR) << "format_volume: failed to open " << v->blk_device; return -1; } int64_t device_size = get_file_size(fd.get(), 0); if (device_size > 0 && !wipe_block_device(fd.get(), device_size)) { LOG(INFO) << "format_volume: wipe metadata encrypted " << v->blk_device << " with size " << device_size; return 0; } } if ((v->fs_type == "ext4" && new_fstype.empty()) || new_fstype == "ext4") { LOG(INFO) << "Formatting " << v->blk_device << " as ext4"; static constexpr int kBlockSize = 4096; std::vector<std::string> mke2fs_args = { "/system/bin/mke2fs", "-F", "-t", "ext4", "-b", std::to_string(kBlockSize), }; // Following is added for Project ID's quota as they require wider inodes. // The Quotas themselves are enabled by tune2fs on boot. mke2fs_args.push_back("-I"); mke2fs_args.push_back("512"); if (v->fs_mgr_flags.ext_meta_csum) { mke2fs_args.push_back("-O"); mke2fs_args.push_back("metadata_csum"); mke2fs_args.push_back("-O"); mke2fs_args.push_back("64bit"); mke2fs_args.push_back("-O"); mke2fs_args.push_back("extent"); } int raid_stride = v->logical_blk_size / kBlockSize; int raid_stripe_width = v->erase_blk_size / kBlockSize; // stride should be the max of 8KB and logical block size if (v->logical_blk_size != 0 && v->logical_blk_size < 8192) { raid_stride = 8192 / kBlockSize; } if (v->erase_blk_size != 0 && v->logical_blk_size != 0) { mke2fs_args.push_back("-E"); mke2fs_args.push_back( android::base::StringPrintf("stride=%d,stripe-width=%d", raid_stride, raid_stripe_width)); } mke2fs_args.push_back(v->blk_device); if (length != 0) { mke2fs_args.push_back(std::to_string(length / kBlockSize)); } int result = exec_cmd(mke2fs_args); if (result == 0 && !directory.empty()) { std::vector<std::string> e2fsdroid_args = { "/system/bin/e2fsdroid", "-e", "-f", directory, "-a", volume, v->blk_device, }; result = exec_cmd(e2fsdroid_args); } if (result != 0) { PLOG(ERROR) << "format_volume: Failed to make ext4 on " << v->blk_device; return -1; } return 0; } // Has to be f2fs because we checked earlier. LOG(INFO) << "Formatting " << v->blk_device << " as f2fs"; static constexpr int kSectorSize = 4096; std::vector<std::string> make_f2fs_cmd = { "/system/bin/make_f2fs", "-g", "android", }; make_f2fs_cmd.push_back("-O"); make_f2fs_cmd.push_back("project_quota,extra_attr"); if (needs_casefold) { make_f2fs_cmd.push_back("-O"); make_f2fs_cmd.push_back("casefold"); make_f2fs_cmd.push_back("-C"); make_f2fs_cmd.push_back("utf8"); } if (v->fs_mgr_flags.fs_compress) { make_f2fs_cmd.push_back("-O"); make_f2fs_cmd.push_back("compression"); make_f2fs_cmd.push_back("-O"); make_f2fs_cmd.push_back("extra_attr"); } make_f2fs_cmd.push_back(v->blk_device); if (length >= kSectorSize) { make_f2fs_cmd.push_back(std::to_string(length / kSectorSize)); } if (exec_cmd(make_f2fs_cmd) != 0) { PLOG(ERROR) << "format_volume: Failed to make_f2fs on " << v->blk_device; return -1; } if (!directory.empty()) { std::vector<std::string> sload_f2fs_cmd = { "/system/bin/sload_f2fs", "-f", directory, "-t", volume, v->blk_device, }; if (exec_cmd(sload_f2fs_cmd) != 0) { PLOG(ERROR) << "format_volume: Failed to sload_f2fs on " << v->blk_device; return -1; } } return 0; } int format_volume(const std::string& volume) { return format_volume(volume, "", ""); } int setup_install_mounts() { if (fstab.empty()) { LOG(ERROR) << "can't set up install mounts: no fstab loaded"; return -1; } for (const FstabEntry& entry : fstab) { // We don't want to do anything with "/". if (entry.mount_point == "/") { continue; } if (entry.mount_point == "/tmp" || entry.mount_point == "/cache") { if (ensure_path_mounted(entry.mount_point) != 0) { LOG(ERROR) << "Failed to mount " << entry.mount_point; return -1; } } else { if (ensure_path_unmounted(entry.mount_point) != 0) { LOG(ERROR) << "Failed to unmount " << entry.mount_point; return -1; } } } return 0; } bool HasCache() { CHECK(!fstab.empty()); static bool has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr; return has_cache; } 总览页的备注列从差异top改成增大大于1M的top5,并且只显示深层路径文件,例如 修改前: "1. my_product: +730.66MB 2. my_product/app: +322.14MB 3. my_product/priv-app: +277.58MB 4. my_product/del-app-pre: +193.83MB 5. my_product/priv-app/GoogleVelvet_CTS: +187.39MB" 修改后: 1. my_product/priv-app/GoogleVelvet_CTS: +187.39MB"
最新发布
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值