前言
Android外部存储空间由 vold init 服务和 StorageManagerService 系统服务共同管理。外部实体存储卷的装载由 vold 处理:通过执行分阶段操作准备好媒体,然后再将其提供给应用。 从 Android 8.0 开始,MountService 类已更名为 StorageManagerService。 并且StorageManagerService与Vold的通信方式由socket方式变为binder方式,精简了部分代码。
涉及代码路径:
基于android11走读存储系统部分代码 frameworks/base/services/core/java/com/android/server/StorageManagerService.java frameworks/base/services/java/com/android/server/SystemServer.java
StorageManagerService
startService
StorageManagerService同其他系统服务一样,也是从SystemServer启动
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
t.traceBegin("StartStorageManagerService");
try {
/* * NotificationManagerService is dependant on StorageManagerService, * (for media / usb notifications) so we must start StorageManagerService first. */
mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
storageManager = IStorageManager.Stub.asInterface(
ServiceManager.getService("mount"));
} catch (Throwable e) {
reportWtf("starting StorageManagerService", e);
}
t.traceEnd();
t.traceBegin("StartStorageStatsService");
try {
mSystemServiceManager.startService(STORAGE_STATS_SERVICE_CLASS);
} catch (Throwable e) {
reportWtf("starting StorageStatsService", e);
}
t.traceEnd();
}
}
...
}
NotificationManagerService依赖于StorageManagerService,所以必需先启动StroageManagerService。 private static final String STORAGE_MANAGER_SERVICE_CLASS = "com.android.server.StorageManagerService$Lifecycle";
SystemManagerService通过反射构建LifeCycle并调用onStart()方法
@Override
public void onStart() {
mStorageManagerService = new StorageManagerService(getContext());
publishBinderService("mount", mStorageManagerService);
mStorageManagerService.start();
}
StorageManagerService
public StorageManagerService(Context context) {
sSelf = this;
// 前面先是读取一些属性状态,其中关于FUSE下面会稍微介绍一下
// Snapshot feature flag used for this boot
SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT, Boolean.toString(
SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, true)));
// If there is no value in the property yet (first boot after data wipe), this value may be
// incorrect until #updateFusePropFromSettings where we set the correct value and reboot if
// different
mIsFuseEnabled = SystemProperties.getBoolean(PROP_FUSE, DEFAULT_FUSE_ENABLED);
mVoldAppDataIsolationEnabled = mIsFuseEnabled && SystemProperties.getBoolean(
ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false);
mContext = context;
mResolver = mContext.getContentResolver();
mCallbacks = new Callbacks(FgThread.get().getLooper());
mLockPatternUtils = new LockPatternUtils(mContext);
// 创建名为“StorageManagerService”的线程,并创建对应的Handler
HandlerThread hthread = new HandlerThread(TAG);
hthread.start();
mHandler = new StorageManagerServiceHandler(hthread.getLooper());
// mObbActionHandler对应“android.io”线程
// Add OBB Action Handler to StorageManagerService thread.
mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());
mStorageSessionController = new StorageSessionController(mContext, mIsFuseEnabled);
// 启动installd服务
mInstaller = new Installer(mContext);
mInstaller.onStart();
// Initialize the last-fstrim tracking if necessary
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
mLastMaintenanceFile = new File(systemDir, LAST_FSTRIM_FILE);
//判断/data/system/last-fstrim文件,不存在则创建,存在则更新最后修改时间
if (!mLastMaintenanceFile.exists()) {
// Not setting mLastMaintenance here means that we will force an
// fstrim during reboot following the OTA that installs this code.
try {
(new FileOutputStream(mLastMaintenanceFile)).close();
} catch (IOException e) {
Slog.e(TAG, "Unable to create fstrim record " + mLastMaintenanceFile.getPath());
}
} else {
mLastMaintenance = mLastMaintenanceFile.lastModified();
}
// 读取data/system/storage.xml配置
mSettingsFile = new AtomicFile(
new File(Environment.getDataSystemDirectory(), "storage.xml"), "storage-settings");
synchronized (mLock) {
readSettingsLocked();
}
LocalServices.addService(StorageManagerInternal.class, mStorageManagerInternal);
// 监听ACTION_USER_ADDED、ACTION_USER_REMOVED广播
final IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_ADDED);
userFilter.addAction(Intent.ACTION_USER_REMOVED);
mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
// 内部私有volume的路径为/data,该volume通过dumpsys mount是不会显示的
synchronized (mLock) {
addInternalVolumeLocked();
}
// Add ourself to the Watchdog monitors if enabled.
if (WATCHDOG_ENABLE) {
Watchdog.getInstance().addMonitor(this);
}
// 汽车应用支持
mIsAutomotive = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_AUTOMOTIVE);
}
FUSE
为了实现更灵活的权限管理能力,Android引入了fuse文件系统。
Filesystem in Userspace顾名思义,即在用户空间的文件系统。 为什么要强调用户空间呢?接触过Linux内核的同学大概会知道,文件系统一般是实现在内核里面的,比如,Ext4、Fat32、NTFS(Kernel原生版)等常见的文件系统,其代码都在内核中,而FUSE特殊之处就是,其文件系统的核心逻辑是在用户空间实现的。
FUSE实现原理
图中体现了FUSE的2个关键部分(绿色方框),分别是Kernel中的那个FUSE(这里简称kernel FUSE)和user space中的那个fuse_user程序。其中kernel FUSE是负责把从用户层过来的文件系统操作请求传递给fuse_user程序的,而这个fuse_user程序实现了前面所说的文件系统的核心逻辑。
onStart
private void start() {
connectStoraged();
connectVold();
}
private void connectStoraged() {
IBinder binder = ServiceManager.getService("storaged");
if (binder != null) {
try {
// 设置死亡代理以重新建立连接
binder.linkToDeath(new DeathRecipient() {
@Override
public void binderDied() {
Slog.w(TAG, "storaged died; reconnecting");
mStoraged = null;
connectStoraged();
}
}, 0);
} catch (RemoteException e) {
binder = null;
}
}
if (binder != null) {
// 获取storaged的bp端用于通信
mStoraged = IStoraged.Stub.asInterface(binder);
} else {
Slog.w(TAG, "storaged not found; trying again");
}
if (mStoraged == null) {
BackgroundThread.getHandler().postDelayed(() -> {
connectStoraged();
}, DateUtils.SECOND_IN_MILLIS);
} else {
onDaemonConnected();
}
}
private void connectVold() {
IBinder binder = ServiceManager.getService("vold");
if (binder != null) {
try {
// 设置死亡代理以重新建立连接
binder.linkToDeath(new DeathRecipient() {
@Override
public void binderDied() {
Slog.w(TAG, "vold died; reconnecting");
mVold = null;
connectVold();
}
}, 0);
} catch (RemoteException e) {
binder = null;
}
}
if (binder != null) {
// 获取Vold的bp端用于通信
mVold = IVold.Stub.asInterface(binder);
try {
// 关键代码:设置Vold的Listener
mVold.setListener(mListener);
} catch (RemoteException e) {
mVold = null;
Slog.w(TAG, "vold listener rejected; trying again", e);
}
} else {
Slog.w(TAG, "vold not found; trying again");
}
if (mVold == null) {
BackgroundThread.getHandler().postDelayed(() -> {
connectVold();
}, DateUtils.SECOND_IN_MILLIS);
} else {
onDaemonConnected();
}
}
connectStoraged和connectVold分别是获取Vold和Storaged服务的bp端,设置死亡代理, 为Vold设置Listener监听,然后调用onDaemonConnected
public void onDaemonConnected() {
mDaemonConnected = true;
mHandler.obtainMessage(H_DAEMON_CONNECTED).sendToTarget();
}
private void handleDaemonConnected() {
initIfBootedAndConnected();
resetIfBootedAndConnected();
// On an encrypted device we can't see system properties yet, so pull
// the system locale out of the mount service.
if ("".equals(VoldProperties.encrypt_progress().orElse(""))) {
copyLocaleFromMountService();
}
}
private void initIfBootedAndConnected() {
Slog.d(TAG, "Thinking about init, mBootCompleted=" + mBootCompleted
+ ", mDaemonConnected=" + mDaemonConnected);
if (mBootCompleted && mDaemonConnected
&& !StorageManager.isFileEncryptedNativeOnly()) {
// 根据persist.sys.emulate_fbe确定用户目录的加锁/解锁状态
final boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly();
Slog.d(TAG, "Setting up emulation state, initlocked=" + initLocked);
final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
for (UserInfo user : users) {
try {
if (initLocked) {
mVold.lockUserKey(user.id);
} else {
mVold.unlockUserKey(user.id, user.serialNumber, encodeBytes(null),
encodeBytes(null));
}
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
}
}
private void resetIfBootedAndConnected() {
Slog.d(TAG, "Thinking about reset, mBootCompleted=" + mBootCompleted
+ ", mDaemonConnected=" + mDaemonConnected);
// systemserver启动进入bootcomplete阶段
if (mBootCompleted && mDaemonConnected) {
final UserManager userManager = mContext.getSystemService(UserManager.class);
final List<UserInfo> users = userManager.getUsers();
if (mIsFuseEnabled) {
mStorageSessionController.onReset(mVold, () -> {
mHandler.removeCallbacksAndMessages(null);
});
} else {
killMediaProvider(users);
}
final int[] systemUnlockedUsers;
synchronized (mLock) {
// make copy as sorting can change order
systemUnlockedUsers = Arrays.copyOf(mSystemUnlockedUsers,
mSystemUnlockedUsers.length);
// 清空mDisk和mVolumes两个ArrayMap
mDisks.clear();
mVolumes.clear();
// 将/data为路径的private volume添加到mVolumes
addInternalVolumeLocked();
}
try {
// 通过Vold的bp端调用reset()方法
// TODO(b/135341433): Remove paranoid logging when FUSE is stable
Slog.i(TAG, "Resetting vold...");
mVold.reset();
Slog.i(TAG, "Reset vold");
// 通知Vold所有的用户和已解锁用户
for (UserInfo user : users) {
mVold.onUserAdded(user.id, user.serialNumber);
}
for (int userId : systemUnlockedUsers) {
mVold.onUserStarted(userId);
mStoraged.onUserStarted(userId);
}
if (mIsAutomotive) {
restoreAllUnlockedUsers(userManager, users, systemUnlockedUsers);
}
mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
mStorageManagerInternal.onReset(mVold);
} catch (Exception e) {
Slog.wtf(TAG, e);
}
}
}
onBootPhase
@Override();
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mStorageManagerService.servicesReady();
} else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mStorageManagerService.systemReady();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mStorageManagerService.bootCompleted();
}
}
SystemServiceManager的startBootPhase()贯穿system_server进程的整个启动过程
1. servicesReady
private void servicesReady() {
mPmInternal = LocalServices.getService(PackageManagerInternal.class);
mIPackageManager = IPackageManager.Stub.asInterface(
ServiceManager.getService("package"));
mIAppOpsService = IAppOpsService.Stub.asInterface(
ServiceManager.getService(Context.APP_OPS_SERVICE));
// MediaProvider
ProviderInfo provider = getProviderInfo(MediaStore.AUTHORITY);
if (provider != null) {
mMediaStoreAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
sMediaStoreAuthorityProcessName = provider.applicationInfo.processName;
}
// DownloadsProvider
provider = getProviderInfo(Downloads.Impl.AUTHORITY);
if (provider != null) {
mDownloadsAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
}
// DocumentsUiProvider
provider = getProviderInfo(DocumentsContract.EXTERNAL_STORAGE_PROVIDER_AUTHORITY);
if (provider != null) {
mExternalStorageAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
}
if (!mIsFuseEnabled) {
try {
mIAppOpsService.startWatchingMode(OP_REQUEST_INSTALL_PACKAGES, null,
mAppOpsCallback);
mIAppOpsService.startWatchingMode(OP_LEGACY_STORAGE, null, mAppOpsCallback);
} catch (RemoteException e) {
}
}
}
2. systemReady
private void systemReady() {();
LocalServices.getService(ActivityTaskManagerInternal.class)
.registerScreenObserver(this);
mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
}
private void handleSystemReady() {
//计划执行日常的fstrim操作?
// Start scheduling nominally-daily fstrim operations
MountServiceIdler.scheduleIdlePass(mContext);
// 响应设置而切换zram-enable系统属性
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ZRAM_ENABLED),
false /*notifyForDescendants*/,
new ContentObserver(null /* current thread */) {
@Override
public void onChange(boolean selfChange) {
refreshZramSettings();
}
});
refreshZramSettings();
// 计划zram写回,除非由persist.sys.zram_enabled禁用了zram
String zramPropValue = SystemProperties.get(ZRAM_ENABLED_PROPERTY);
if (!zramPropValue.equals("0")
&& mContext.getResources().getBoolean(
com.android.internal.R.bool.config_zramWriteback)) {
ZramWriteback.scheduleZramWriteback(mContext);
}
// 响应设置切换isolated-enable 的系统属性
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ISOLATED_STORAGE_REMOTE),
false /*notifyForDescendants*/,
new ContentObserver(null /* current thread */) {
@Override
public void onChange(boolean selfChange) {
refreshIsolatedStorageSettings();
}
});
// 在属性更改时克隆属性
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
mContext.getMainExecutor(), (properties) -> {
refreshIsolatedStorageSettings();
refreshFuseSettings();
});
refreshIsolatedStorageSettings();
}
3. bootCompleted
private void bootCompleted() {
mBootCompleted = true;
mHandler.obtainMessage(H_BOOT_COMPLETED).sendToTarget();
updateFusePropFromSettings();
}
private void handleBootCompleted() {
// 与onStart部分调用一致
initIfBootedAndConnected();
resetIfBootedAndConnected();
}
小结
StorageManagerService与storaged和Vold服务建立链接,并持有了storaged和Vold的BP对象以进行通信。 StorageManagerService还设置Vold设置了Listener接收Vold回调过来的各类事件。 下文我将分析Vold部分代码。
今天的文章Android存储系统源码走读(一):StorageManagerService分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/13937.html