Android存储系统源码走读(一):StorageManagerService

Watchdog.getInstance().addMonitor(this);
}

// 汽车应用支持
mIsAutomotive = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_AUTOMOTIVE);
}

FUSE

FUSE(Filesystem in Userspace)

为了实现更灵活的权限管理能力,Android引入了fuse文件系统。

Filesystem in Userspace顾名思义,即在用户空间的文件系统。 为什么要强调用户空间呢?接触过Linux内核的同学大概会知道,文件系统一般是实现在内核里面的,比如,Ext4、Fat32、NTFS(Kernel原生版)等常见的文件系统,其代码都在内核中,而FUSE特殊之处就是,其文件系统的核心逻辑是在用户空间实现的。

FUSE实现原理

image.png

图中体现了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 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 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进程的整个启动过程

image.png

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 */) {

最后

给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了

image

image

image

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

714398979317)]

[外链图片转存中…(img-lXLgPlUg-1714398979318)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 29
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值