Use new kernel notifications to determine if USB mass storage is available.
The usb_mass_storage switch no longer exists in our 2.6.35 kernel. Instead we will consider mass storage to be available if both USB is connected and the USB mass storage function is enable. Change-Id: I730d1b3cb3cac664fc2abcdc36cd39856a08404a Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
parent
acc9e7dcca
commit
99635f6c28
4 changed files with 78 additions and 50 deletions
|
@ -54,6 +54,8 @@ void NetlinkHandler::onEvent(NetlinkEvent *evt) {
|
|||
vm->handleBlockEvent(evt);
|
||||
} else if (!strcmp(subsys, "switch")) {
|
||||
vm->handleSwitchEvent(evt);
|
||||
} else if (!strcmp(subsys, "usb_composite")) {
|
||||
vm->handleUsbCompositeEvent(evt);
|
||||
} else if (!strcmp(subsys, "battery")) {
|
||||
} else if (!strcmp(subsys, "power_supply")) {
|
||||
}
|
||||
|
|
|
@ -55,7 +55,43 @@ VolumeManager::VolumeManager() {
|
|||
mVolumes = new VolumeCollection();
|
||||
mActiveContainers = new AsecIdCollection();
|
||||
mBroadcaster = NULL;
|
||||
mUsbMassStorageConnected = false;
|
||||
mUsbMassStorageEnabled = false;
|
||||
mUsbConnected = false;
|
||||
|
||||
readInitialState();
|
||||
}
|
||||
|
||||
void VolumeManager::readInitialState() {
|
||||
FILE *fp;
|
||||
char state[255];
|
||||
|
||||
/*
|
||||
* Read the initial mass storage enabled state
|
||||
*/
|
||||
if ((fp = fopen("/sys/devices/virtual/usb_composite/usb_mass_storage/enable", "r"))) {
|
||||
if (fgets(state, sizeof(state), fp)) {
|
||||
mUsbMassStorageEnabled = !strncmp(state, "1", 1);
|
||||
} else {
|
||||
SLOGE("Failed to read usb_mass_storage enabled state (%s)", strerror(errno));
|
||||
}
|
||||
fclose(fp);
|
||||
} else {
|
||||
SLOGD("USB mass storage support is not enabled in the kernel");
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the initial USB connected state
|
||||
*/
|
||||
if ((fp = fopen("/sys/devices/virtual/switch/usb_configuration/state", "r"))) {
|
||||
if (fgets(state, sizeof(state), fp)) {
|
||||
mUsbConnected = !strncmp(state, "1", 1);
|
||||
} else {
|
||||
SLOGE("Failed to read usb_configuration switch (%s)", strerror(errno));
|
||||
}
|
||||
fclose(fp);
|
||||
} else {
|
||||
SLOGD("usb_configuration switch is not enabled in the kernel");
|
||||
}
|
||||
}
|
||||
|
||||
VolumeManager::~VolumeManager() {
|
||||
|
@ -116,17 +152,12 @@ int VolumeManager::addVolume(Volume *v) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void VolumeManager::notifyUmsConnected(bool connected) {
|
||||
void VolumeManager::notifyUmsAvailable(bool available) {
|
||||
char msg[255];
|
||||
|
||||
if (connected) {
|
||||
mUsbMassStorageConnected = true;
|
||||
} else {
|
||||
mUsbMassStorageConnected = false;
|
||||
}
|
||||
snprintf(msg, sizeof(msg), "Share method ums now %s",
|
||||
(connected ? "available" : "unavailable"));
|
||||
|
||||
(available ? "available" : "unavailable"));
|
||||
SLOGD(msg);
|
||||
getBroadcaster()->sendBroadcast(ResponseCode::ShareAvailabilityChange,
|
||||
msg, false);
|
||||
}
|
||||
|
@ -141,17 +172,37 @@ void VolumeManager::handleSwitchEvent(NetlinkEvent *evt) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(name, "usb_mass_storage")) {
|
||||
|
||||
if (!strcmp(state, "online")) {
|
||||
notifyUmsConnected(true);
|
||||
} else {
|
||||
notifyUmsConnected(false);
|
||||
bool oldAvailable = massStorageAvailable();
|
||||
if (!strcmp(name, "usb_configuration")) {
|
||||
mUsbConnected = !strcmp(state, "1");
|
||||
SLOGD("USB %s", mUsbConnected ? "connected" : "disconnected");
|
||||
bool newAvailable = massStorageAvailable();
|
||||
if (newAvailable != oldAvailable) {
|
||||
notifyUmsAvailable(newAvailable);
|
||||
}
|
||||
} else {
|
||||
SLOGW("Ignoring unknown switch '%s'", name);
|
||||
}
|
||||
}
|
||||
void VolumeManager::handleUsbCompositeEvent(NetlinkEvent *evt) {
|
||||
const char *function = evt->findParam("FUNCTION");
|
||||
const char *enabled = evt->findParam("ENABLED");
|
||||
|
||||
if (!function || !enabled) {
|
||||
SLOGW("usb_composite event missing function/enabled info");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(function, "usb_mass_storage")) {
|
||||
bool oldAvailable = massStorageAvailable();
|
||||
mUsbMassStorageEnabled = !strcmp(enabled, "1");
|
||||
SLOGD("usb_mass_storage function %s", mUsbMassStorageEnabled ? "enabled" : "disabled");
|
||||
bool newAvailable = massStorageAvailable();
|
||||
if (newAvailable != oldAvailable) {
|
||||
notifyUmsAvailable(newAvailable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
|
||||
const char *devpath = evt->findParam("DEVPATH");
|
||||
|
@ -726,10 +777,7 @@ int VolumeManager::shareAvailable(const char *method, bool *avail) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (mUsbMassStorageConnected)
|
||||
*avail = true;
|
||||
else
|
||||
*avail = false;
|
||||
*avail = massStorageAvailable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -758,9 +806,9 @@ int VolumeManager::simulate(const char *cmd, const char *arg) {
|
|||
|
||||
if (!strcmp(cmd, "ums")) {
|
||||
if (!strcmp(arg, "connect")) {
|
||||
notifyUmsConnected(true);
|
||||
notifyUmsAvailable(true);
|
||||
} else if (!strcmp(arg, "disconnect")) {
|
||||
notifyUmsConnected(false);
|
||||
notifyUmsAvailable(false);
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
|
|
@ -38,7 +38,8 @@ private:
|
|||
|
||||
VolumeCollection *mVolumes;
|
||||
AsecIdCollection *mActiveContainers;
|
||||
bool mUsbMassStorageConnected;
|
||||
bool mUsbMassStorageEnabled;
|
||||
bool mUsbConnected;
|
||||
bool mDebug;
|
||||
|
||||
public:
|
||||
|
@ -49,6 +50,7 @@ public:
|
|||
|
||||
void handleBlockEvent(NetlinkEvent *evt);
|
||||
void handleSwitchEvent(NetlinkEvent *evt);
|
||||
void handleUsbCompositeEvent(NetlinkEvent *evt);
|
||||
|
||||
int addVolume(Volume *v);
|
||||
|
||||
|
@ -72,8 +74,6 @@ public:
|
|||
|
||||
void setDebug(bool enable);
|
||||
|
||||
// XXX: This should be moved private once switch uevents are working
|
||||
void notifyUmsConnected(bool connected);
|
||||
// XXX: Post froyo this should be moved and cleaned up
|
||||
int cleanupAsec(Volume *v, bool force);
|
||||
|
||||
|
@ -86,7 +86,11 @@ public:
|
|||
|
||||
private:
|
||||
VolumeManager();
|
||||
void readInitialState();
|
||||
Volume *lookupVolume(const char *label);
|
||||
bool isMountpointMounted(const char *mp);
|
||||
|
||||
inline bool massStorageAvailable() const { return mUsbMassStorageEnabled && mUsbConnected; }
|
||||
void notifyUmsAvailable(bool available);
|
||||
};
|
||||
#endif
|
||||
|
|
26
main.cpp
26
main.cpp
|
@ -77,32 +77,6 @@ int main() {
|
|||
}
|
||||
|
||||
coldboot("/sys/block");
|
||||
/*
|
||||
* Switch uevents are broken.
|
||||
* For now we manually bootstrap
|
||||
* the ums switch
|
||||
*/
|
||||
{
|
||||
FILE *fp;
|
||||
char state[255];
|
||||
|
||||
if ((fp = fopen("/sys/devices/virtual/switch/usb_mass_storage/state",
|
||||
"r"))) {
|
||||
if (fgets(state, sizeof(state), fp)) {
|
||||
if (!strncmp(state, "online", 6)) {
|
||||
vm->notifyUmsConnected(true);
|
||||
} else {
|
||||
vm->notifyUmsConnected(false);
|
||||
}
|
||||
} else {
|
||||
SLOGE("Failed to read switch state (%s)", strerror(errno));
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
} else {
|
||||
SLOGW("No UMS switch available");
|
||||
}
|
||||
}
|
||||
// coldboot("/sys/class/switch");
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue