| Index: chrome/browser/extensions/api/api_resource_event_notifier.cc | 
| diff --git a/chrome/browser/extensions/api/api_resource_event_notifier.cc b/chrome/browser/extensions/api/api_resource_event_notifier.cc | 
| index ef33c5897cf673d137dd8d8398a8552796a2b4da..6a15809c143c532ffabe941127e148f003f26a02 100644 | 
| --- a/chrome/browser/extensions/api/api_resource_event_notifier.cc | 
| +++ b/chrome/browser/extensions/api/api_resource_event_notifier.cc | 
| @@ -14,18 +14,20 @@ | 
| using content::BrowserThread; | 
|  | 
| namespace events { | 
| -// TODO(miket): This should be generic, but at the moment only socket sends | 
| -// onEvent events. We'll fix this when serial becomes nonblocking. | 
| -const char kOnAPIResourceEvent[] = "experimental.socket.onEvent"; | 
| +const char kExperimentalSocketOnEvent[] = "experimental.socket.onEvent"; | 
| +const char kExperimentalUsbOnEvent[] = "experimental.usb.onEvent"; | 
| }; | 
|  | 
| namespace extensions { | 
|  | 
| const char kEventTypeKey[] = "type"; | 
| + | 
| const char kEventTypeConnectComplete[] = "connectComplete"; | 
| const char kEventTypeDataRead[] = "dataRead"; | 
| const char kEventTypeWriteComplete[] = "writeComplete"; | 
|  | 
| +const char kEventTypeTransferComplete[] = "transferComplete"; | 
| + | 
| const char kSrcIdKey[] = "srcId"; | 
| const char kIsFinalEventKey[] = "isFinalEvent"; | 
|  | 
| @@ -48,7 +50,8 @@ APIResourceEventNotifier::APIResourceEventNotifier( | 
| } | 
|  | 
| void APIResourceEventNotifier::OnConnectComplete(int result_code) { | 
| -  SendEventWithResultCode(API_RESOURCE_EVENT_CONNECT_COMPLETE, result_code); | 
| +  SendEventWithResultCode(events::kExperimentalSocketOnEvent, | 
| +                          API_RESOURCE_EVENT_CONNECT_COMPLETE, result_code); | 
| } | 
|  | 
| void APIResourceEventNotifier::OnDataRead(int result_code, | 
| @@ -70,11 +73,26 @@ void APIResourceEventNotifier::OnDataRead(int result_code, | 
| event->Set(kDataKey, data); | 
| event->SetString(kAddressKey, address); | 
| event->SetInteger(kPortKey, port); | 
| -  DispatchEvent(event); | 
| +  DispatchEvent(events::kExperimentalSocketOnEvent, event); | 
| } | 
|  | 
| void APIResourceEventNotifier::OnWriteComplete(int result_code) { | 
| -  SendEventWithResultCode(API_RESOURCE_EVENT_WRITE_COMPLETE, result_code); | 
| +  SendEventWithResultCode(events::kExperimentalSocketOnEvent, | 
| +                          API_RESOURCE_EVENT_WRITE_COMPLETE, result_code); | 
| +} | 
| + | 
| +void APIResourceEventNotifier::OnTransferComplete(int result_code, | 
| +                                                  base::ListValue* data) { | 
| +  if (src_id_ < 0) { | 
| +    delete data; | 
| +    return; | 
| +  } | 
| + | 
| +  DictionaryValue* event = CreateAPIResourceEvent( | 
| +      API_RESOURCE_EVENT_TRANSFER_COMPLETE); | 
| +  event->SetInteger(kResultCodeKey, result_code); | 
| +  event->Set(kDataKey, data); | 
| +  DispatchEvent(events::kExperimentalUsbOnEvent, event); | 
| } | 
|  | 
| // static | 
| @@ -87,6 +105,8 @@ std::string APIResourceEventNotifier::APIResourceEventTypeToString( | 
| return kEventTypeDataRead; | 
| case API_RESOURCE_EVENT_WRITE_COMPLETE: | 
| return kEventTypeWriteComplete; | 
| +    case API_RESOURCE_EVENT_TRANSFER_COMPLETE: | 
| +      return kEventTypeTransferComplete; | 
| } | 
|  | 
| NOTREACHED(); | 
| @@ -95,15 +115,17 @@ std::string APIResourceEventNotifier::APIResourceEventTypeToString( | 
|  | 
| APIResourceEventNotifier::~APIResourceEventNotifier() {} | 
|  | 
| -void APIResourceEventNotifier::DispatchEvent(DictionaryValue* event) { | 
| +void APIResourceEventNotifier::DispatchEvent(const std::string &extension, | 
| +                                             DictionaryValue* event) { | 
| BrowserThread::PostTask( | 
| BrowserThread::UI, FROM_HERE, | 
| base::Bind( | 
| -          &APIResourceEventNotifier::DispatchEventOnUIThread, this, event)); | 
| +          &APIResourceEventNotifier::DispatchEventOnUIThread, this, extension, | 
| +          event)); | 
| } | 
|  | 
| void APIResourceEventNotifier::DispatchEventOnUIThread( | 
| -    DictionaryValue* event) { | 
| +    const std::string &extension, DictionaryValue* event) { | 
| ListValue args; | 
|  | 
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| @@ -111,9 +133,8 @@ void APIResourceEventNotifier::DispatchEventOnUIThread( | 
| args.Set(0, event); | 
| std::string json_args; | 
| base::JSONWriter::Write(&args, &json_args); | 
| -  router_->DispatchEventToExtension(src_extension_id_, | 
| -                                    events::kOnAPIResourceEvent, | 
| -                                    json_args, profile_, src_url_); | 
| +  router_->DispatchEventToExtension(src_extension_id_, extension, json_args, | 
| +                                    profile_, src_url_); | 
| } | 
|  | 
| DictionaryValue* APIResourceEventNotifier::CreateAPIResourceEvent( | 
| @@ -132,6 +153,7 @@ DictionaryValue* APIResourceEventNotifier::CreateAPIResourceEvent( | 
| } | 
|  | 
| void APIResourceEventNotifier::SendEventWithResultCode( | 
| +    const std::string &extension, | 
| APIResourceEventType event_type, | 
| int result_code) { | 
| if (src_id_ < 0) | 
| @@ -139,7 +161,7 @@ void APIResourceEventNotifier::SendEventWithResultCode( | 
|  | 
| DictionaryValue* event = CreateAPIResourceEvent(event_type); | 
| event->SetInteger(kResultCodeKey, result_code); | 
| -  DispatchEvent(event); | 
| +  DispatchEvent(extension, event); | 
| } | 
|  | 
| }  // namespace extensions | 
|  |