Android 8.1客制化OTG Uディスクのマウントパス名
46997 ワード
Android 8.1客制化OTG Uディスクのマウントパス名
プロジェクトには特殊なUディスクマウントパスや固定されたUディスクマウントパスが必要な場合がありますが、以下の方法で修正できます.
まず、Uディスクのマウントプロセスを見てみましょう.Android 8.1デフォルトのUディスクはstorageディレクトリの下にマウントされていません.また、ファイル管理にもUディスクが表示されません.ファイル管理にUディスクが表示される必要がある場合は、別のブログを参照してください.Android 8.1 OGUディスクはシステムファイル管理の変更を表示できません.
1.Uディスクを挿入すると、まずnewのDiskクラスがあり、そのコンストラクション関数は「eventPath」というパラメータを入力し、ソースファイル:system/vold/Disk.cpp
クラスのプライベート変数「mEventPath」は、「/devices/platform/mt_usb/musb-hdrc.0.auto/usb 1/1-1/1-1.4/...」など、各Uディスクのデバイスパスを保存します.このパスは、USB HUBとUディスクのマウントポートによって異なります.この変数を使用して、自分が必要とするUディスクかどうかを判断できます.
2.次にnew PublicVolumeクラスとVolumeBaseクラスを行い、status_を実行します.t VolumeBase::create()、ソースファイル:system/vold/VolumeBase.cpp
このときの状態は「kUnmounted」です.
3.次にmount操作を実行し、ソースファイル:system/vold/VolumeBase.cpp;system/vold/PublicVolume.cpp
PublicVolumeのdoMount()を呼び出し、mountが成功したかどうかに応じてステータス「kMounted」と「kUnmountable」を設定します.
Uディスクが1つしかマウントされていない場合は、上のコードの変数「stableName」を自分の名前に直接変更すればいいです.HUBが掛けられ、複数のUディスクがある場合は、下を見続けます.
4.mountは成功または失敗する可能性がありますが、成功するかどうかにかかわらず、Uディスクをアンインストールするときにstatus_を実行します.t VolumeBase::destroy()、これはstatus_t VolumeBase::create()対応、ソースファイル:system/vold/VolumeBase.cpp
mountステータスに応じて、「kMounted」であればunmountを実行します.
5.unmountを実行し、ソースファイル:system/vold/VolumeBase.cpp;system/vold/PublicVolume.cpp
PublicVolumeのdoUnmount()を呼び出し、
以上が必要な大まかなUディスクマウントフローです.
私の複数のUディスクのカスタムマウントパスを実現する方法は、Uディスクstatus_t PublicVolume::doMount()の場合、Diskクラスのプライベート変数「mEventPath」の値を取得し、特殊名称が必要なUディスクであるか否かを判断し、特殊名称が必要なUディスクであれば、統一名称接頭辞+数字番号、例えば「USB 1~USB 10」を使用して、合計10個のUディスクに特殊名称を使用することをサポートし、mountが必要なたびに名前番号を割り当て、グローバル変数配列(自己定義)を使用して、対応する番号が割り当てられているかどうかをマークします.割り当てられた番号は、mountが成功したり、失敗したりする可能性があります.status_t VolumeBase::destroy()で割り当てられた番号のタグをクリアします.
参照コードは次のとおりです.
以上が修正方法と参考コードです!
いくつかの注意:1.SDカードリーダーが差し込むとnew Diskクラスになりますが、mountは実行されません.私は最初はDiskのコンストラクション関数で「mEventPath」の値を直接判断し、割り当てられた名前番号で、SDカードリーダーが1つの番号を占有し、解放されないので、mountが必要なときに割り当てます.同様に、もう1つの場合もstatus_が実行されているt VolumeBase::create()ですが、mountはありません.2.status_t VolumeBase::destroy()では、status_ではなく、割り当てられた番号を解放します.t PublicVolume::doUnmount()では、mountが成功しなければunmountは実行されないため、番号が解放されません.3.時々現れ、プロセスはstatusを実行した.t VolumeBase::create()は、次に2回mountを実行します.例えば、空のSDカードリーダーを挿入した後、破損したSDカードを挿入すると、mount関数で判断しなければなりません.同じプロセスで、最初のmountはすでに番号を割り当てて、mountに行って、前に割り当てた番号を使って、新しい割り当てに行かないでください.そうしないとdestroy()のとき、最後のmount割り当てをクリアするだけです.前のリリースはできません!
プロジェクトには特殊なUディスクマウントパスや固定されたUディスクマウントパスが必要な場合がありますが、以下の方法で修正できます.
まず、Uディスクのマウントプロセスを見てみましょう.Android 8.1デフォルトのUディスクはstorageディレクトリの下にマウントされていません.また、ファイル管理にもUディスクが表示されません.ファイル管理にUディスクが表示される必要がある場合は、別のブログを参照してください.Android 8.1 OGUディスクはシステムファイル管理の変更を表示できません.
1.Uディスクを挿入すると、まずnewのDiskクラスがあり、そのコンストラクション関数は「eventPath」というパラメータを入力し、ソースファイル:system/vold/Disk.cpp
Disk::Disk(const std::string& eventPath, dev_t device,
const std::string& nickname, int flags) :
mDevice(device), mSize(-1), mNickname(nickname), mFlags(flags), mCreated(
false), mJustPartitioned(false) {
mId = StringPrintf("disk:%u,%u", major(device), minor(device));
mEventPath = eventPath; // eventPath, mEventPath
mSysPath = StringPrintf("/sys/%s", eventPath.c_str());
mDevPath = StringPrintf("/dev/block/vold/%s", mId.c_str());
CreateDeviceNode(mDevPath, mDevice);
}
クラスのプライベート変数「mEventPath」は、「/devices/platform/mt_usb/musb-hdrc.0.auto/usb 1/1-1/1-1.4/...」など、各Uディスクのデバイスパスを保存します.このパスは、USB HUBとUディスクのマウントポートによって異なります.この変数を使用して、自分が必要とするUディスクかどうかを判断できます.
2.次にnew PublicVolumeクラスとVolumeBaseクラスを行い、status_を実行します.t VolumeBase::create()、ソースファイル:system/vold/VolumeBase.cpp
status_t VolumeBase::create() {
CHECK(!mCreated);
mCreated = true;
status_t res = doCreate();
notifyEvent(ResponseCode::VolumeCreated,
StringPrintf("%d \"%s\" \"%s\"", mType, mDiskId.c_str(), mPartGuid.c_str()));
setState(State::kUnmounted);
return res;
}
このときの状態は「kUnmounted」です.
3.次にmount操作を実行し、ソースファイル:system/vold/VolumeBase.cpp;system/vold/PublicVolume.cpp
status_t VolumeBase::mount() {
if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
LOG(WARNING) << getId() << " mount requires state unmounted or unmountable";
return -EBUSY;
}
setState(State::kChecking);
status_t res = doMount();
if (res == OK) {
setState(State::kMounted);
} else {
setState(State::kUnmountable);
}
return res;
}
PublicVolumeのdoMount()を呼び出し、mountが成功したかどうかに応じてステータス「kMounted」と「kUnmountable」を設定します.
status_t PublicVolume::doMount() {
// TODO: expand to support mounting other filesystems
readMetadata();
......
// Use UUID as stable name, if available
std::string stableName = getId(); // ,
if (!mFsUuid.empty()) {
stableName = mFsUuid;
}
mRawPath = StringPrintf("/mnt/media_rw/%s", stableName.c_str());
mFuseDefault = StringPrintf("/mnt/runtime/default/%s", stableName.c_str());
mFuseRead = StringPrintf("/mnt/runtime/read/%s", stableName.c_str());
mFuseWrite = StringPrintf("/mnt/runtime/write/%s", stableName.c_str());
setInternalPath(mRawPath);
if (getMountFlags() & MountFlags::kVisible) { // storage
setPath(StringPrintf("/storage/%s", stableName.c_str()));
} else {
setPath(mRawPath);
}
if (fs_prepare_dir(mRawPath.c_str(), 0700, AID_ROOT, AID_ROOT)) {
PLOG(ERROR) << getId() << " failed to create mount points";
return -errno;
}
......
return OK;
}
Uディスクが1つしかマウントされていない場合は、上のコードの変数「stableName」を自分の名前に直接変更すればいいです.HUBが掛けられ、複数のUディスクがある場合は、下を見続けます.
4.mountは成功または失敗する可能性がありますが、成功するかどうかにかかわらず、Uディスクをアンインストールするときにstatus_を実行します.t VolumeBase::destroy()、これはstatus_t VolumeBase::create()対応、ソースファイル:system/vold/VolumeBase.cpp
status_t VolumeBase::destroy() {
CHECK(mCreated);
if (mState == State::kMounted) {
unmount();
setState(State::kBadRemoval);
} else {
setState(State::kRemoved);
}
notifyEvent(ResponseCode::VolumeDestroyed);
status_t res = doDestroy();
mCreated = false;
return res;
}
mountステータスに応じて、「kMounted」であればunmountを実行します.
5.unmountを実行し、ソースファイル:system/vold/VolumeBase.cpp;system/vold/PublicVolume.cpp
status_t VolumeBase::unmount() {
if (mState != State::kMounted) {
LOG(WARNING) << getId() << " unmount requires state mounted";
return -EBUSY;
}
setState(State::kEjecting);
for (const auto& vol : mVolumes) {
if (vol->destroy()) {
LOG(WARNING) << getId() << " failed to destroy " << vol->getId()
<< " stacked above";
}
}
mVolumes.clear();
status_t res = doUnmount();
setState(State::kUnmounted);
return res;
}
PublicVolumeのdoUnmount()を呼び出し、
status_t PublicVolume::doUnmount() {
// Unmount the storage before we kill the FUSE process. If we kill
// the FUSE process first, most file system operations will return
// ENOTCONN until the unmount completes. This is an exotic and unusual
// error code and might cause broken behaviour in applications.
KillProcessesUsingPath(getPath());
ForceUnmount(kAsecPath);
ForceUnmount(mFuseDefault);
ForceUnmount(mFuseRead);
ForceUnmount(mFuseWrite);
ForceUnmount(mRawPath);
if (mFusePid > 0) {
kill(mFusePid, SIGTERM);
TEMP_FAILURE_RETRY(waitpid(mFusePid, nullptr, 0));
mFusePid = 0;
}
rmdir(mFuseDefault.c_str());
rmdir(mFuseRead.c_str());
rmdir(mFuseWrite.c_str());
rmdir(mRawPath.c_str());
mFuseDefault.clear();
mFuseRead.clear();
mFuseWrite.clear();
mRawPath.clear();
return OK;
}
以上が必要な大まかなUディスクマウントフローです.
私の複数のUディスクのカスタムマウントパスを実現する方法は、Uディスクstatus_t PublicVolume::doMount()の場合、Diskクラスのプライベート変数「mEventPath」の値を取得し、特殊名称が必要なUディスクであるか否かを判断し、特殊名称が必要なUディスクであれば、統一名称接頭辞+数字番号、例えば「USB 1~USB 10」を使用して、合計10個のUディスクに特殊名称を使用することをサポートし、mountが必要なたびに名前番号を割り当て、グローバル変数配列(自己定義)を使用して、対応する番号が割り当てられているかどうかをマークします.割り当てられた番号は、mountが成功したり、失敗したりする可能性があります.status_t VolumeBase::destroy()で割り当てられた番号のタグをクリアします.
参照コードは次のとおりです.
status_t PublicVolume::doMount() {
// TODO: expand to support mounting other filesystems
readMetadata();
......
#if 0 //
// Use UUID as stable name, if available
std::string stableName = getId();
if (!mFsUuid.empty()) {
stableName = mFsUuid;
}
#endif
/***************************************************************************/
std::string stableName = getId();
unsigned char i;
const char *Path = getEventPath().data();// Disk mEventPath ,
// , USB HUB, HUB , 1
// , , kernel sysfs device ,
if( strncmp(Path,"/devices/platform/mt_usb/musb-hdrc.0.auto/usb1/1-1/1-1.1",strlen("/devices/platform/mt_usb/musb-hdrc.0.auto/usb1/1-1/1-1.*")) >= 0 )
{
//
for(i = 0; i < 10; i++)
{
//flag 0,
if(MountPointFlag[i] == 0) // ,
break;
}
if(i < 10)
{
stableName = StringPrintf("USB%d", (i + 1));
MountPointFlag[i] = 1; // 1,
}
}
/***************************************************************************/
// U , /mnt/media_rw , /storage
mRawPath = StringPrintf("/mnt/media_rw/%s", stableName.c_str());
mFuseDefault = StringPrintf("/mnt/runtime/default/%s", stableName.c_str());
mFuseRead = StringPrintf("/mnt/runtime/read/%s", stableName.c_str());
mFuseWrite = StringPrintf("/mnt/runtime/write/%s", stableName.c_str());
setInternalPath(mRawPath);
if (getMountFlags() & MountFlags::kVisible) { //
setPath(StringPrintf("/storage/%s", stableName.c_str()));
} else {
setPath(mRawPath);
}
// setPath(), VolumeBase “mPath”
if (fs_prepare_dir(mRawPath.c_str(), 0700, AID_ROOT, AID_ROOT)) {
PLOG(ERROR) << getId() << " failed to create mount points";
return -errno;
}
......
return OK;
}
status_t VolumeBase::destroy() {
CHECK(mCreated);
/***************************************************************************/
const std::string Path = getPath();// VolumeBase “mPath”
// U storage, storage
if( strncmp(Path.data(),"/storage/USB",strlen("/storage/USB")) == 0 )
{
//
unsigned char clear = (unsigned char)atoi(Path.substr(strlen("/storage/USB")).c_str());
// ,
if(pMountPointFlag!= NULL)
{
if( (clear > 0) && (clear <= 10) )
pMountPointFlag[clear - 1] = 0; // 0,
}
}
/***************************************************************************/
if (mState == State::kMounted) {
unmount();
setState(State::kBadRemoval);
} else {
setState(State::kRemoved);
}
notifyEvent(ResponseCode::VolumeDestroyed);
status_t res = doDestroy();
mCreated = false;
return res;
}
以上が修正方法と参考コードです!
いくつかの注意:1.SDカードリーダーが差し込むとnew Diskクラスになりますが、mountは実行されません.私は最初はDiskのコンストラクション関数で「mEventPath」の値を直接判断し、割り当てられた名前番号で、SDカードリーダーが1つの番号を占有し、解放されないので、mountが必要なときに割り当てます.同様に、もう1つの場合もstatus_が実行されているt VolumeBase::create()ですが、mountはありません.2.status_t VolumeBase::destroy()では、status_ではなく、割り当てられた番号を解放します.t PublicVolume::doUnmount()では、mountが成功しなければunmountは実行されないため、番号が解放されません.3.時々現れ、プロセスはstatusを実行した.t VolumeBase::create()は、次に2回mountを実行します.例えば、空のSDカードリーダーを挿入した後、破損したSDカードを挿入すると、mount関数で判断しなければなりません.同じプロセスで、最初のmountはすでに番号を割り当てて、mountに行って、前に割り当てた番号を使って、新しい割り当てに行かないでください.そうしないとdestroy()のとき、最後のmount割り当てをクリアするだけです.前のリリースはできません!