| Index: chrome/browser/chrome_content_browser_client.cc | 
| diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc | 
| index e3ae8430cec806a0579d1fb3054a56e0a57932a8..646b62b2ec29c428e1062c395a62a1031b408474 100644 | 
| --- a/chrome/browser/chrome_content_browser_client.cc | 
| +++ b/chrome/browser/chrome_content_browser_client.cc | 
| @@ -29,23 +29,23 @@ | 
| #include "chrome/browser/chrome_net_benchmarking_message_filter.h" | 
| #include "chrome/browser/chrome_quota_permission_context.h" | 
| #include "chrome/browser/content_settings/cookie_settings.h" | 
| +#include "chrome/browser/content_settings/permission_context.h" | 
| +#include "chrome/browser/content_settings/permission_observer.h" | 
| +#include "chrome/browser/content_settings/permission_observer_factory.h" | 
| #include "chrome/browser/content_settings/tab_specific_content_settings.h" | 
| #include "chrome/browser/defaults.h" | 
| #include "chrome/browser/download/download_prefs.h" | 
| #include "chrome/browser/font_family_cache.h" | 
| #include "chrome/browser/geolocation/chrome_access_token_store.h" | 
| #include "chrome/browser/geolocation/geolocation_permission_context.h" | 
| -#include "chrome/browser/geolocation/geolocation_permission_context_factory.h" | 
| #include "chrome/browser/media/media_capture_devices_dispatcher.h" | 
| #include "chrome/browser/media/midi_permission_context.h" | 
| -#include "chrome/browser/media/midi_permission_context_factory.h" | 
| #include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h" | 
| #include "chrome/browser/nacl_host/nacl_browser_delegate_impl.h" | 
| #include "chrome/browser/net/chrome_net_log.h" | 
| #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings.h" | 
| #include "chrome/browser/net/spdyproxy/data_reduction_proxy_chrome_settings_factory.h" | 
| #include "chrome/browser/notifications/desktop_notification_service.h" | 
| -#include "chrome/browser/notifications/desktop_notification_service_factory.h" | 
| #include "chrome/browser/notifications/platform_notification_service_impl.h" | 
| #include "chrome/browser/platform_util.h" | 
| #include "chrome/browser/prerender/prerender_final_status.h" | 
| @@ -57,7 +57,6 @@ | 
| #include "chrome/browser/profiles/profile.h" | 
| #include "chrome/browser/profiles/profile_io_data.h" | 
| #include "chrome/browser/push_messaging/push_messaging_permission_context.h" | 
| -#include "chrome/browser/push_messaging/push_messaging_permission_context_factory.h" | 
| #include "chrome/browser/renderer_host/chrome_render_message_filter.h" | 
| #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h" | 
| #include "chrome/browser/search/instant_service.h" | 
| @@ -171,7 +170,6 @@ | 
|  | 
| #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 
| #include "chrome/browser/media/protected_media_identifier_permission_context.h" | 
| -#include "chrome/browser/media/protected_media_identifier_permission_context_factory.h" | 
| #endif | 
|  | 
| #if defined(OS_POSIX) && !defined(OS_MACOSX) | 
| @@ -628,37 +626,6 @@ ContentSettingToPermissionStatus(ContentSetting setting) { | 
| return content::PERMISSION_STATUS_DENIED; | 
| } | 
|  | 
| -PermissionContextBase* GetPermissionContext(Profile* profile, | 
| -    content::PermissionType permission) { | 
| -  switch (permission) { | 
| -    case content::PERMISSION_MIDI_SYSEX: | 
| -      return MidiPermissionContextFactory::GetForProfile(profile); | 
| -    case content::PERMISSION_NOTIFICATIONS: | 
| -#if defined(ENABLE_NOTIFICATIONS) | 
| -      return DesktopNotificationServiceFactory::GetForProfile(profile); | 
| -#else | 
| -      NOTIMPLEMENTED(); | 
| -      break; | 
| -#endif | 
| -    case content::PERMISSION_GEOLOCATION: | 
| -      return GeolocationPermissionContextFactory::GetForProfile(profile); | 
| -    case content::PERMISSION_PROTECTED_MEDIA_IDENTIFIER: | 
| -#if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 
| -      return ProtectedMediaIdentifierPermissionContextFactory::GetForProfile( | 
| -          profile); | 
| -#else | 
| -      NOTIMPLEMENTED(); | 
| -      break; | 
| -#endif | 
| -    case content::PERMISSION_PUSH_MESSAGING: | 
| -      return PushMessagingPermissionContextFactory::GetForProfile(profile); | 
| -    case content::PERMISSION_NUM: | 
| -      NOTREACHED() << "Invalid RequestPermission for " << permission; | 
| -      break; | 
| -  } | 
| -  return nullptr; | 
| -} | 
| - | 
| // Helper method to translate from Permissions to ContentSettings | 
| ContentSettingsType PermissionToContentSetting( | 
| content::PermissionType permission) { | 
| @@ -681,7 +648,7 @@ ContentSettingsType PermissionToContentSetting( | 
| } | 
| } | 
|  | 
| -void OnRequestPermission( | 
| +void PermissionStatusCallbackWrapper( | 
| const base::Callback<void(content::PermissionStatus)>& callback, | 
| ContentSetting content_setting) { | 
| callback.Run(ContentSettingToPermissionStatus(content_setting)); | 
| @@ -1946,14 +1913,16 @@ void ChromeContentBrowserClient::RequestPermission( | 
| requesting_frame); | 
| Profile* profile = | 
| Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 
| -  PermissionContextBase* context = GetPermissionContext(profile, permission); | 
| +  PermissionContextBase* context = | 
| +      PermissionContext::Get(profile, PermissionToContentSetting(permission)); | 
|  | 
| if (!context) | 
| return; | 
|  | 
| context->RequestPermission(web_contents, request_id, requesting_frame, | 
| user_gesture, | 
| -                             base::Bind(&OnRequestPermission, result_callback)); | 
| +                             base::Bind(&PermissionStatusCallbackWrapper, | 
| +                                        result_callback)); | 
| } | 
|  | 
| content::PermissionStatus ChromeContentBrowserClient::GetPermissionStatus( | 
| @@ -1963,7 +1932,8 @@ content::PermissionStatus ChromeContentBrowserClient::GetPermissionStatus( | 
| const GURL& embedding_origin) { | 
| DCHECK(browser_context); | 
| Profile* profile = Profile::FromBrowserContext(browser_context); | 
| -  PermissionContextBase* context = GetPermissionContext(profile, permission); | 
| +  PermissionContextBase* context = | 
| +      PermissionContext::Get(profile, PermissionToContentSetting(permission)); | 
|  | 
| if (!context) | 
| return content::PERMISSION_STATUS_ASK; | 
| @@ -1973,6 +1943,29 @@ content::PermissionStatus ChromeContentBrowserClient::GetPermissionStatus( | 
| embedding_origin.GetOrigin())); | 
| } | 
|  | 
| +int ChromeContentBrowserClient::SubscribePermissionStatusChange( | 
| +    content::PermissionType permission, | 
| +    content::BrowserContext* browser_context, | 
| +    const GURL& requesting_origin, | 
| +    const GURL& embedding_origin, | 
| +    const base::Callback<void(content::PermissionStatus)>& callback) { | 
| +  return PermissionObserverFactory::GetForProfile( | 
| +      Profile::FromBrowserContext(browser_context)) | 
| +          ->Subscribe(PermissionToContentSetting(permission), | 
| +                      requesting_origin, | 
| +                      embedding_origin, | 
| +                      base::Bind(&PermissionStatusCallbackWrapper, | 
| +                                 callback)); | 
| +} | 
| + | 
| +void ChromeContentBrowserClient::UnsubscribePermissionStatusChange( | 
| +    content::BrowserContext* browser_context, | 
| +    int subscription_id) { | 
| +  PermissionObserverFactory::GetForProfile( | 
| +      Profile::FromBrowserContext(browser_context)) | 
| +          ->Unsubscribe(subscription_id); | 
| +} | 
| + | 
| void ChromeContentBrowserClient::ResetPermission( | 
| content::PermissionType permission, | 
| content::BrowserContext* browser_context, | 
| @@ -1980,7 +1973,8 @@ void ChromeContentBrowserClient::ResetPermission( | 
| const GURL& embedding_origin) { | 
| DCHECK(browser_context); | 
| Profile* profile = Profile::FromBrowserContext(browser_context); | 
| -  PermissionContextBase* context = GetPermissionContext(profile, permission); | 
| +  PermissionContextBase* context = | 
| +      PermissionContext::Get(profile, PermissionToContentSetting(permission)); | 
|  | 
| if (!context) | 
| return; | 
| @@ -2002,7 +1996,8 @@ void ChromeContentBrowserClient::CancelPermissionRequest( | 
| requesting_frame); | 
| Profile* profile = | 
| Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 
| -  PermissionContextBase* context = GetPermissionContext(profile, permission); | 
| +  PermissionContextBase* context = | 
| +      PermissionContext::Get(profile, PermissionToContentSetting(permission)); | 
| if (!context) | 
| return; | 
| context->CancelPermissionRequest(web_contents, request_id); | 
|  |