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:
Mike Lockwood 2010-06-25 23:04:04 -04:00
parent acc9e7dcca
commit 99635f6c28
4 changed files with 78 additions and 50 deletions

View file

@ -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")) {
}

View file

@ -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;

View file

@ -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

View file

@ -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");
/*