Android 系统显示过大
系统文件计算方式是通过mStorageInfo.totalBytes - mStorageInfo.freeBytes计算得出,差异点是由于mUsedBytes导致,是由于data剩余的空间少导致系统显示大,请排查data分区差异
分析如下:
packages/apps/Settings/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
final long systemSize = Math.max(TrafficStats.GB_IN_BYTES, mUsedBytes - attributedSize);
mSystemPreference.setStorageSize(systemSize, mTotalSize);
设置的系统大小是systemSize,是使用 mUsedBytes - attributedSize计算得出,由于mUsedBytes较大导致显示大
packages/apps/Settings/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
...
mPreferenceController.setUsedSize(privateUsedBytes);
mUsedBytes来自mPreferenceController.setUsedSize(privateUsedBytes); 取得,privateUsedBytes 是通过总内存减去空余内存得出,由于空余内存小,导致计算之后privateUsedBytes 超大
frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
public PrivateStorageInfo(long freeBytes, long totalBytes) {
Log.d("xxx", "freeBytes:"+freeBytes);
this.freeBytes = freeBytes;
this.totalBytes = totalBytes;
}
剩余空间从PrivateStorageInfo获取
packages/apps/Settings/src/com/android/settings/deviceinfo/storage/VolumeSizesLoader.java
static PrivateStorageInfo getVolumeSize(
StorageVolumeProvider storageVolumeProvider, StorageStatsManager stats, VolumeInfo info)
throws IOException {
long privateTotalBytes = storageVolumeProvider.getTotalBytes(stats, info);
long privateFreeBytes = storageVolumeProvider.getFreeBytes(stats, info);
此处传入空余空间数值,数值从storageVolumeProvider.getFreeBytes获取
return new PrivateStorageInfo(privateFreeBytes, privateTotalBytes);
}
frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java
long getFreeBytes(StorageStatsManager stats, VolumeInfo volume) throws IOException;
storageVolumeProvider接口方法实现是StorageManagerVolumeProvider
frameworks/base/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java
@Override
public long getFreeBytes(StorageStatsManager stats, VolumeInfo volume) throws IOException {
return stats.getFreeBytes(volume.getFsUuid());
}
实现接口方法后从StorageStatsManager 的方法getFreeBytes获取空余空间
frameworks/base/core/java/android/app/usage/StorageStatsManager.java
@WorkerThread
public @BytesLong long getFreeBytes(@NonNull UUID storageUuid) throws IOException {
try {
return mService.getFreeBytes(convert(storageUuid), mContext.getOpPackageName());
} catch (ParcelableException e) {
e.maybeRethrow(IOException.class);
throw new RuntimeException(e);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
StorageStatsManager通过该IStorageStatsManager接口获取,IStorageStatsManager实现类是StorageStatsService
frameworks/base/services/usage/java/com/android/server/usage/StorageStatsService.java
@Override
public long getFreeBytes(String volumeUuid, String callingPackage) {
// NOTE: No permissions required
final long token = Binder.clearCallingIdentity();
Log.d("xxx", "StorageStatsService token:"+(token));// token:4294967298582
try {
final File path;
try {
path = mStorage.findPathForUuid(volumeUuid);
Log.d("xxx", "StorageStatsService path:"+path);// path:/data
} catch (FileNotFoundException e) {
throw new ParcelableException(e);
}
// Free space is usable bytes plus any cached data that we're
// willing to automatically clear. To avoid user confusion, this
// logic should be kept in sync with getAllocatableBytes().
if (isQuotaSupported(volumeUuid, PLATFORM_PACKAGE_NAME)) {
final long cacheTotal = getCacheBytes(volumeUuid, PLATFORM_PACKAGE_NAME);
final long cacheReserved = mStorage.getStorageCacheBytes(path, 0);
final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
Log.d("xxx", "StorageStatsService cacheTotal:"+(cacheTotal));// cacheTotal:1417216
Log.d("xxx", "StorageStatsService cacheReserved:"+(cacheReserved));// cacheReserved:3760313958
Log.d("xxx", "StorageStatsService cacheClearable:"+(cacheClearable));// cacheClearable:0
Log.d("xxx", "StorageStatsService path.getUsableSpace():"+(path.getUsableSpace()));// path.getUsableSpace():36319633408
Log.d("xxx", "StorageStatsService getUsableSpace() + cacheClearable:"+(path.getUsableSpace() + cacheClearable));// getUsableSpace() + cacheClearable:36319633408
return path.getUsableSpace() + cacheClearable;
} else {
Log.d("xxx", "StorageStatsService path.getUsableSpace():"+(path.getUsableSpace()));
return path.getUsableSpace();
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
对比其他项目,Q7257项目data分区:/dev/block/dm-4 35G 1.1G 34G 4% /data
malta项目data分区:/dev/block/mmcblk0p60 49G 4.1G 44G 9% /data
由于data差异较大,剩余空间较少导致系统显示较大
解决方案:
Buganizer: https://issuetracker.google.com/issues/77499348 https://issuetracker.google.com/issues/110084019 |
/frameworks/native / cmds/installd/InstalldNativeService.cpp
if (!uuid) {
ATRACE_BEGIN("dalvik");
int32_t sharedGid = multiuser_get_shared_gid(0, appId);
if (sharedGid != -1 && sharedGid != 0) {
calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
sharedGid, -1);
}
ATRACE_END();
}
}
std::vector ret;
ret.push_back(stats.codeSize);
ret.push_back(stats.dataSize);
ret.push_back(stats.cacheSize);
ret.push_back(extStats.codeSize);
ret.push_back(extStats.dataSize);
ret.push_back(extStats.cacheSize);
#if MEASURE_DEBUG
LOG(DEBUG)
#endif
*_aidl_return = ret;
return ok();
}