summaryrefslogtreecommitdiffstats
path: root/dom/system/gonk/MozMtpStorage.cpp
blob: 9c358a1324304b9c24808c420aede91004e6babd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* -*- 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());

  RefPtr<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
  RefPtr<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);

  RefPtr<RefCountedMtpServer> server = mMozMtpServer->GetMtpServer();
  server->removeStorage(mMtpStorage.get());

  MTP_LOG("Removing mStorageID 0x%08x from MozMtpDatabse", mStorageID);

  RefPtr<MozMtpDatabase> db = mMozMtpServer->GetMozMtpDatabase();
  db->RemoveStorage(mStorageID);

  mMtpStorage = nullptr;
}

END_MTP_NAMESPACE