// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/media/media_web_contents_observer.h"

#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "content/browser/media/cdm/browser_cdm_manager.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message_macros.h"

#if defined(OS_ANDROID)
#include "content/browser/android/media_players_observer.h"
#include "content/browser/media/android/browser_media_player_manager.h"
#include "content/common/media/media_player_messages_android.h"
#include "media/base/android/media_player_android.h"
#endif  // defined(OS_ANDROID)

namespace content {

MediaWebContentsObserver::MediaWebContentsObserver(
    WebContents* web_contents)
    : WebContentsObserver(web_contents)
{
}

MediaWebContentsObserver::~MediaWebContentsObserver() {
}

void MediaWebContentsObserver::RenderFrameDeleted(
    RenderFrameHost* render_frame_host) {
#if defined(OS_ANDROID)
  uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
  // Always destroy the media players before CDMs because we do not support
  // detaching CDMs from media players yet. See http://crbug.com/330324
  media_player_managers_.erase(key);

  MediaPlayersObserver* audio_observer = GetMediaPlayersObserver();
  if (audio_observer)
    audio_observer->RenderFrameDeleted(render_frame_host);
#endif
  // TODO(xhwang): Currently MediaWebContentsObserver, BrowserMediaPlayerManager
  // and BrowserCdmManager all run on browser UI thread. So this call is okay.
  // In the future we need to support the case where MediaWebContentsObserver
  // get notified on browser UI thread, but BrowserMediaPlayerManager and
  // BrowserCdmManager run on a different thread.
  BrowserCdmManager* browser_cdm_manager =
      BrowserCdmManager::FromProcess(render_frame_host->GetProcess()->GetID());
  if (browser_cdm_manager)
    browser_cdm_manager->RenderFrameDeleted(render_frame_host->GetRoutingID());
}

#if defined(OS_ANDROID)

bool MediaWebContentsObserver::OnMessageReceived(
    const IPC::Message& msg,
    RenderFrameHost* render_frame_host) {
  if (OnMediaPlayerMessageReceived(msg, render_frame_host))
    return true;

  if (OnMediaPlayerSetCdmMessageReceived(msg, render_frame_host))
    return true;

  return false;
}

bool MediaWebContentsObserver::OnMediaPlayerMessageReceived(
    const IPC::Message& msg,
    RenderFrameHost* render_frame_host) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver, msg)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnEnterFullscreen)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnInitialize)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnStart)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnSeek)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnPause)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnSetVolume)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnSetPoster)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Release,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnReleaseResources)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnDestroyPlayer)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_RequestRemotePlayback,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnRequestRemotePlayback)
    IPC_MESSAGE_FORWARD(
        MediaPlayerHostMsg_RequestRemotePlaybackControl,
        GetMediaPlayerManager(render_frame_host),
        BrowserMediaPlayerManager::OnRequestRemotePlaybackControl)
#if defined(VIDEO_HOLE)
    IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface,
                        GetMediaPlayerManager(render_frame_host),
                        BrowserMediaPlayerManager::OnNotifyExternalSurface)
#endif  // defined(VIDEO_HOLE)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

bool MediaWebContentsObserver::OnMediaPlayerSetCdmMessageReceived(
    const IPC::Message& msg,
    RenderFrameHost* render_frame_host) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(
      MediaWebContentsObserver, msg, render_frame_host)
    IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetCdm, OnSetCdm)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void MediaWebContentsObserver::OnSetCdm(RenderFrameHost* render_frame_host,
                                        int player_id,
                                        int cdm_id) {
  media::MediaPlayerAndroid* media_player =
      GetMediaPlayerManager(render_frame_host)->GetPlayer(player_id);
  if (!media_player) {
    NOTREACHED() << "OnSetCdm: MediaPlayer not found for " << player_id;
    return;
  }

  // MediaPlayerAndroid runs on the same thread as BrowserCdmManager.
  BrowserCdmManager* browser_cdm_manager =
      BrowserCdmManager::FromProcess(render_frame_host->GetProcess()->GetID());
  if (!browser_cdm_manager) {
    NOTREACHED() << "OnSetCdm: CDM not found for " << cdm_id;
    return;
  }

  media::BrowserCdm* cdm =
      browser_cdm_manager->GetCdm(render_frame_host->GetRoutingID(), cdm_id);
  if (!cdm) {
    NOTREACHED() << "OnSetCdm: CDM not found for " << cdm_id;
    return;
  }

  // TODO(xhwang): This could possibly fail. In that case we should reject the
  // promise.
  media_player->SetCdm(cdm);
}

BrowserMediaPlayerManager* MediaWebContentsObserver::GetMediaPlayerManager(
    RenderFrameHost* render_frame_host) {
  uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
  if (!media_player_managers_.contains(key)) {
    media_player_managers_.set(
        key,
        make_scoped_ptr(BrowserMediaPlayerManager::Create(
            render_frame_host, GetMediaPlayersObserver())));
  }
  return media_player_managers_.get(key);
}

MediaPlayersObserver*
MediaWebContentsObserver::GetMediaPlayersObserver() const {
  AudioStateProvider* provider =
      static_cast<WebContentsImpl*>(web_contents())->audio_state_provider();

  MediaPlayersObserver* audio_observer =
      static_cast<MediaPlayersObserver*>(provider);

  DCHECK(audio_observer);
  return audio_observer;
}

#if defined(VIDEO_HOLE)
void MediaWebContentsObserver::OnFrameInfoUpdated() {
  for (MediaPlayerManagerMap::iterator iter = media_player_managers_.begin();
      iter != media_player_managers_.end(); ++iter) {
    BrowserMediaPlayerManager* manager = iter->second;
    manager->OnFrameInfoUpdated();
  }
}
#endif  // defined(VIDEO_HOLE)

#endif  // defined(OS_ANDROID)

}  // namespace content
