gecko-dev/dom/system/gonk/MozMtpStorage.cpp

136 lines
4.2 KiB
C++

/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MozMtpStorage.h"
#include "MozMtpDatabase.h"
#include "MozMtpServer.h"
#include "base/message_loop.h"
#include "nsXULAppAPI.h"
BEGIN_MTP_NAMESPACE
using namespace android;
MozMtpStorage::MozMtpStorage(Volume* aVolume, MozMtpServer* aMozMtpServer)
: mMozMtpServer(aMozMtpServer),
mVolume(aVolume)
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
// The MtpStorageID has the physical volume in the top 16 bits, and the
// logical volumein the lower 16 bits. We treat each volume as a separate
// phsyical storage;
mStorageID = mVolume->Id() << 16 | 1;
MTP_LOG("Storage constructed for Volume %s mStorageID 0x%08x",
aVolume->NameStr(), mStorageID);
Volume::RegisterVolumeObserver(this, "MozMtpStorage");
// Get things in sync
Notify(mVolume);
}
MozMtpStorage::~MozMtpStorage()
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
MTP_LOG("Storage destructed for Volume %s mStorageID 0x%08x",
mVolume->NameStr(), mStorageID);
Volume::UnregisterVolumeObserver(this, "MozMtpStorage");
if (mMtpStorage) {
StorageUnavailable();
}
}
// virtual
void
MozMtpStorage::Notify(Volume* const& aVolume)
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
if (aVolume != mVolume) {
// Not our volume
return;
}
Volume::STATE volState = aVolume->State();
MTP_LOG("Volume %s mStorageID 0x%08x state changed to %s SharingEnabled: %d",
aVolume->NameStr(), mStorageID, aVolume->StateStr(),
aVolume->IsSharingEnabled());
// vol->IsSharingEnabled really only applies to UMS volumes. We assume that
// that as long as MTP is enabled, then all volumes will be shared. The UI
// currently doesn't give us anything more granular than on/off.
if (mMtpStorage) {
if (volState != nsIVolume::STATE_MOUNTED) {
// The volume is no longer accessible. We need to remove this storage
// from the MTP server
StorageUnavailable();
}
} else {
if (volState == nsIVolume::STATE_MOUNTED) {
// The volume is accessible. Tell the MTP server.
StorageAvailable();
}
}
}
void
MozMtpStorage::StorageAvailable()
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
nsCString mountPoint = mVolume->MountPoint();
MTP_LOG("Adding Volume %s mStorageID 0x%08x mountPoint %s to MozMtpDatabase",
mVolume->NameStr(), mStorageID, mountPoint.get());
nsRefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
db->AddStorage(mStorageID, mountPoint.get(), mVolume->NameStr());
MOZ_ASSERT(!mMtpStorage);
//TODO: Figure out what to do about maxFileSize.
mMtpStorage.reset(new MtpStorage(mStorageID, // id
mountPoint.get(), // filePath
mVolume->NameStr(), // description
1024uLL * 1024uLL, // reserveSpace
mVolume->IsHotSwappable(), // removable
2uLL * 1024uLL * 1024uLL * 1024uLL)); // maxFileSize
nsRefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
MTP_LOG("Adding Volume %s mStorageID 0x%08x mountPoint %s to MtpServer",
mVolume->NameStr(), mStorageID, mountPoint.get());
server->addStorage(mMtpStorage.get());
}
void
MozMtpStorage::StorageUnavailable()
{
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
MOZ_ASSERT(mMtpStorage);
MTP_LOG("Removing mStorageID 0x%08x from MtpServer", mStorageID);
nsRefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
server->removeStorage(mMtpStorage.get());
MTP_LOG("Removing mStorageID 0x%08x from MozMtpDatabse", mStorageID);
nsRefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
db->RemoveStorage(mStorageID);
mMtpStorage = nullptr;
}
END_MTP_NAMESPACE