1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "MozMtpStorage.h"
8 #include "MozMtpDatabase.h"
9 #include "MozMtpServer.h"
10
11 #include "base/message_loop.h"
12 #include "nsXULAppAPI.h"
13
14 BEGIN_MTP_NAMESPACE
15 using namespace android;
16
MozMtpStorage(Volume * aVolume,MozMtpServer * aMozMtpServer)17 MozMtpStorage::MozMtpStorage(Volume* aVolume, MozMtpServer* aMozMtpServer)
18 : mMozMtpServer(aMozMtpServer),
19 mVolume(aVolume)
20 {
21 MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
22
23 // The MtpStorageID has the physical volume in the top 16 bits, and the
24 // logical volumein the lower 16 bits. We treat each volume as a separate
25 // phsyical storage;
26 mStorageID = mVolume->Id() << 16 | 1;
27
28 MTP_LOG("Storage constructed for Volume %s mStorageID 0x%08x",
29 aVolume->NameStr(), mStorageID);
30
31 Volume::RegisterVolumeObserver(this, "MozMtpStorage");
32
33 // Get things in sync
34 Notify(mVolume);
35 }
36
~MozMtpStorage()37 MozMtpStorage::~MozMtpStorage()
38 {
39 MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
40
41 MTP_LOG("Storage destructed for Volume %s mStorageID 0x%08x",
42 mVolume->NameStr(), mStorageID);
43
44 Volume::UnregisterVolumeObserver(this, "MozMtpStorage");
45 if (mMtpStorage) {
46 StorageUnavailable();
47 }
48 }
49
50 // virtual
51 void
Notify(Volume * const & aVolume)52 MozMtpStorage::Notify(Volume* const& aVolume)
53 {
54 MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
55
56 if (aVolume != mVolume) {
57 // Not our volume
58 return;
59 }
60 Volume::STATE volState = aVolume->State();
61
62 MTP_LOG("Volume %s mStorageID 0x%08x state changed to %s SharingEnabled: %d",
63 aVolume->NameStr(), mStorageID, aVolume->StateStr(),
64 aVolume->IsSharingEnabled());
65
66 // vol->IsSharingEnabled really only applies to UMS volumes. We assume that
67 // that as long as MTP is enabled, then all volumes will be shared. The UI
68 // currently doesn't give us anything more granular than on/off.
69
70 if (mMtpStorage) {
71 if (volState != nsIVolume::STATE_MOUNTED) {
72 // The volume is no longer accessible. We need to remove this storage
73 // from the MTP server
74 StorageUnavailable();
75 }
76 } else {
77 if (volState == nsIVolume::STATE_MOUNTED) {
78 // The volume is accessible. Tell the MTP server.
79 StorageAvailable();
80 }
81 }
82 }
83
84 void
StorageAvailable()85 MozMtpStorage::StorageAvailable()
86 {
87 MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
88
89 nsCString mountPoint = mVolume->MountPoint();
90
91 MTP_LOG("Adding Volume %s mStorageID 0x%08x mountPoint %s to MozMtpDatabase",
92 mVolume->NameStr(), mStorageID, mountPoint.get());
93
94 RefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
95 db->AddStorage(mStorageID, mountPoint.get(), mVolume->NameStr());
96
97 MOZ_ASSERT(!mMtpStorage);
98
99 //TODO: Figure out what to do about maxFileSize.
100
101 mMtpStorage.reset(new MtpStorage(mStorageID, // id
102 mountPoint.get(), // filePath
103 mVolume->NameStr(), // description
104 1024uLL * 1024uLL, // reserveSpace
105 mVolume->IsHotSwappable(), // removable
106 2uLL * 1024uLL * 1024uLL * 1024uLL)); // maxFileSize
107 RefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
108
109 MTP_LOG("Adding Volume %s mStorageID 0x%08x mountPoint %s to MtpServer",
110 mVolume->NameStr(), mStorageID, mountPoint.get());
111 server->addStorage(mMtpStorage.get());
112 }
113
114 void
StorageUnavailable()115 MozMtpStorage::StorageUnavailable()
116 {
117 MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
118 MOZ_ASSERT(mMtpStorage);
119
120 MTP_LOG("Removing mStorageID 0x%08x from MtpServer", mStorageID);
121
122 RefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
123 server->removeStorage(mMtpStorage.get());
124
125 MTP_LOG("Removing mStorageID 0x%08x from MozMtpDatabse", mStorageID);
126
127 RefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
128 db->RemoveStorage(mStorageID);
129
130 mMtpStorage = nullptr;
131 }
132
133 END_MTP_NAMESPACE
134
135
136