[FMradio] Removed deprecated enums 65/175065/2
authorRafal Walczyna <r.walczyna@partner.samsung.com>
Tue, 20 Mar 2018 06:11:36 +0000 (07:11 +0100)
committerRafal Walczyna <r.walczyna@partner.samsung.com>
Tue, 24 Apr 2018 06:43:25 +0000 (06:43 +0000)
Some of the native enums are deprecated and there is a need of changing
WebAPI's behaviour of interrupt events to use sound-manager audio focus

[ACR] http://suprem.sec.samsung.net/jira/browse/TWDAPI-190

[Verification] Auto and manual TCT 100% passrate on TM1

Change-Id: I69c3d5c30225b8b84ccdbff6993bceff5406396d
Signed-off-by: Rafal Walczyna <r.walczyna@partner.samsung.com>
src/radio/radio_manager.cc
src/radio/radio_manager.h

index 2e9ea1ea3040594f366d97f95cb731bedba681fc..f381e4b14274ca5dafef32192542bf49b77ba4b0 100644 (file)
@@ -88,24 +88,34 @@ PlatformResult CheckError(const std::string& str, int err) {
   }
 }
 
-string TranslateInterruptedCode(int code) {
-  ScopeLogger();
-#define STRINGIFY(c) \
-  case c:            \
-    return #c
-  switch (code) {
-    STRINGIFY(RADIO_INTERRUPTED_BY_MEDIA);
-    STRINGIFY(RADIO_INTERRUPTED_BY_CALL);
-    STRINGIFY(RADIO_INTERRUPTED_BY_EARJACK_UNPLUG);
-    STRINGIFY(RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT);
-    STRINGIFY(RADIO_INTERRUPTED_BY_ALARM);
-    STRINGIFY(RADIO_INTERRUPTED_BY_EMERGENCY);
-    STRINGIFY(RADIO_INTERRUPTED_BY_RESUMABLE_MEDIA);
-    STRINGIFY(RADIO_INTERRUPTED_BY_NOTIFICATION);
+string TranslateInterruptedCode(sound_stream_focus_change_reason_e reason) {
+  ScopeLogger();
+  switch (reason) {
+    case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA:
+      return "RADIO_INTERRUPTED_BY_MEDIA";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM:
+      return "RADIO_INTERRUPTED_BY_SYSTEM";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_ALARM:
+      return "RADIO_INTERRUPTED_BY_ALARM";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION:
+      return "RADIO_INTERRUPTED_BY_NOTIFICATION";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY:
+      return "RADIO_INTERRUPTED_BY_EMERGENCY";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION:
+      return "RADIO_INTERRUPTED_BY_VOICE_INFORMATION";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION:
+      return "RADIO_INTERRUPTED_BY_VOICE_RECOGNITION";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE:
+      return "RADIO_INTERRUPTED_BY_RINGTONE";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_VOIP:
+      return "RADIO_INTERRUPTED_BY_VOIP";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_CALL:
+      return "RADIO_INTERRUPTED_BY_CALL";
+    case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY:
+      return "RADIO_INTERRUPTED_BY_MEDIA_EXTERNAL_ONLY";
     default:
       return "UNKNOWN_INTERRUPTED_ERROR_CODE";
   }
-#undef STRINGIFY
 }
 
 int TokHz(double frequency) {
@@ -185,26 +195,6 @@ void ScanStopCallback(void* user_data) {
   delete data;
 }
 
-void RadioInterruptedCallback(radio_interrupted_code_e code, void* user_data) {
-  ScopeLogger();
-
-  picojson::value event{picojson::object()};
-  auto& obj = event.get<picojson::object>();
-
-  obj.insert(std::make_pair("listenerId", picojson::value("FMRadio_Interrupted")));
-
-  if (code == RADIO_INTERRUPTED_COMPLETED) {
-    obj.insert(std::make_pair("action", picojson::value("oninterruptfinished")));
-  } else {
-    obj.insert(std::make_pair("action", picojson::value("oninterrupted")));
-    obj.insert(std::make_pair("reason", picojson::value(TranslateInterruptedCode(code))));
-  }
-
-  FMRadioManager* manager = static_cast<FMRadioManager*>(user_data);
-  common::TaskQueue::GetInstance().Async(
-      std::bind(&FMRadioManager::PostMessage, manager, event.serialize()));
-}
-
 void RadioAntennaCallback(runtime_info_key_e key, void* user_data) {
   ScopeLogger();
 
@@ -225,6 +215,51 @@ void RadioAntennaCallback(runtime_info_key_e key, void* user_data) {
       std::bind(&FMRadioManager::PostMessage, manager, event.serialize()));
 }
 
+void SoundStreamFocusCallback(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask,
+                              sound_stream_focus_state_e focus_state,
+                              sound_stream_focus_change_reason_e reason_for_change,
+                              int sound_behavior, const char* additional_info, void* user_data) {
+  ScopeLogger("reason_for_change: %d", reason_for_change);
+
+  FMRadioManager* manager = static_cast<FMRadioManager*>(user_data);
+
+  picojson::value event{picojson::object()};
+  auto& obj = event.get<picojson::object>();
+
+  obj.insert(std::make_pair("listenerId", picojson::value("FMRadio_Interrupted")));
+
+  if (SOUND_STREAM_FOCUS_STATE_ACQUIRED != focus_state) {
+    LoggerD("Stopping radio");
+    const auto err_radio_stop = radio_stop(manager->GetRadioInstance());
+    if (RADIO_ERROR_NONE != err_radio_stop) {
+      LoggerE("Failed to stop radio: %d", err_radio_stop);
+    }
+
+    obj.insert(std::make_pair("action", picojson::value("oninterrupted")));
+    obj.insert(
+        std::make_pair("reason", picojson::value(TranslateInterruptedCode(reason_for_change))));
+  } else {
+    // As we stopped radio on first interrupt, we will release focus on second
+    LoggerD("Preparing to release focus");
+    auto release_focus = [&manager]() {
+      ScopeLogger("Entered into asynchronous function, release_focus");
+      const auto sound_focus_err = sound_manager_release_focus(
+          manager->GetStreamInfo(), SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
+      if (SOUND_MANAGER_ERROR_NONE != sound_focus_err) {
+        LoggerE("sound_manager_release_focus() failed: %d", sound_focus_err);
+      }
+    };
+    common::TaskQueue::GetInstance().Async(release_focus);
+
+    obj.insert(std::make_pair("action", picojson::value("oninterruptfinished")));
+  }
+
+  if (manager->IsInterruptedListenerSet()) {
+    common::TaskQueue::GetInstance().Async(
+        std::bind(&FMRadioManager::PostMessage, manager, event.serialize()));
+  }
+}
+
 }  // namespace
 
 bool FMRadioManager::IsMuted() {
@@ -293,6 +328,18 @@ const char* FMRadioManager::GetState() {
   }
 }
 
+bool FMRadioManager::IsInterruptedListenerSet() {
+  return is_interrupted_listener_set;
+}
+
+radio_h FMRadioManager::GetRadioInstance() {
+  return radio_instance_;
+};
+
+sound_stream_info_h FMRadioManager::GetStreamInfo() {
+  return stream_info_;
+}
+
 PlatformResult FMRadioManager::SetFrequency(double frequency) {
   ScopeLogger();
   return CheckError("radio_set_frequency", radio_set_frequency(radio_instance_, TokHz(frequency)));
@@ -328,7 +375,11 @@ double FMRadioManager::GetSignalStrength() {
 }
 
 FMRadioManager::FMRadioManager(RadioInstance& instance)
-    : instance_(instance), radio_instance_(nullptr), scan_data(nullptr) {
+    : instance_(instance),
+      radio_instance_(nullptr),
+      scan_data(nullptr),
+      stream_info_(nullptr),
+      is_interrupted_listener_set(false) {
   ScopeLogger();
 
   const auto err = radio_create(&radio_instance_);
@@ -337,6 +388,13 @@ FMRadioManager::FMRadioManager(RadioInstance& instance)
     LoggerE("radio_create() failed: %d", err);
     radio_instance_ = nullptr;
   }
+
+  const auto err_sound = sound_manager_create_stream_information(
+      SOUND_STREAM_TYPE_MEDIA, SoundStreamFocusCallback, this, &stream_info_);
+  if (SOUND_MANAGER_ERROR_NONE != err_sound) {
+    LoggerE("sound_manager_create_stream_information() failed: %d", err_sound);
+    stream_info_ = nullptr;
+  }
 }
 
 FMRadioManager::~FMRadioManager() {
@@ -349,6 +407,14 @@ FMRadioManager::~FMRadioManager() {
       LoggerE("radio_destroy() failed: %d", err);
     }
   }
+
+  if (nullptr != stream_info_) {
+    const auto err = sound_manager_destroy_stream_information(stream_info_);
+    if (RADIO_ERROR_NONE != err) {
+      LoggerE("sound_manager_destroy_stream_information() failed: %d", err);
+    }
+  }
+
   delete scan_data;
 }
 
@@ -366,6 +432,7 @@ PlatformResult FMRadioManager::Start(double frequency) {
   if (RADIO_STATE_READY != state && RADIO_STATE_PLAYING != state) {
     return LogAndCreateResult(ErrorCode::INVALID_STATE_ERR, "Invalid radio state.");
   }
+  LoggerD("Current radio state: %d", state);
 
   PlatformResult result = SetFrequency(frequency);
 
@@ -373,11 +440,34 @@ PlatformResult FMRadioManager::Start(double frequency) {
     return result;
   }
 
-  if (RADIO_STATE_READY == state) {
-    return CheckError("radio_start", radio_start(radio_instance_));
-  } else {
-    return result;
+  if (RADIO_STATE_PLAYING == state) {
+    LoggerD("Radio is already started.");
+    return PlatformResult(ErrorCode::NO_ERROR);
+  }
+  // state == RADIO_STATE_READY
+  sound_stream_focus_state_e state_for_playback;
+  sound_stream_focus_state_e state_for_recording;
+
+  const auto err_focus_state =
+      sound_manager_get_focus_state(stream_info_, &state_for_playback, &state_for_recording);
+
+  if (SOUND_MANAGER_ERROR_NONE != err_focus_state) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Checking sound focus state failed.",
+                              ("sound_manager_get_focus_state failed: %d", err_focus_state));
   }
+
+  if (SOUND_STREAM_FOCUS_STATE_ACQUIRED != state_for_playback) {
+    LoggerD("Current sound stream focus state: %d, acquiring focus", state_for_playback);
+    const auto err_sound_focus = sound_manager_acquire_focus(
+        stream_info_, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
+
+    if (SOUND_MANAGER_ERROR_NONE != err_sound_focus) {
+      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Acquiring sound focus failed.",
+                                ("sound_manager_acquire_focus failed: %d", err_sound_focus));
+    }
+  }
+
+  return CheckError("radio_start", radio_start(radio_instance_));
 }
 
 PlatformResult FMRadioManager::Stop() {
@@ -395,7 +485,14 @@ PlatformResult FMRadioManager::Stop() {
     return LogAndCreateResult(ErrorCode::INVALID_STATE_ERR, "Invalid radio state.");
   }
 
-  return CheckError("radio_stop", radio_stop(radio_instance_));
+  const auto err_radio_stop = radio_stop(radio_instance_);
+  const auto sound_focus_err = sound_manager_release_focus(
+      stream_info_, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
+  if (SOUND_MANAGER_ERROR_NONE != sound_focus_err) {
+    LoggerE("sound_manager_release_focus() failed: %d", sound_focus_err);
+  }
+
+  return CheckError("radio_stop", err_radio_stop);
 }
 
 void FMRadioManager::SeekUp(double callback_id) {
@@ -495,15 +592,15 @@ void FMRadioManager::ScanStop(double callback_id) {
 common::PlatformResult FMRadioManager::SetFMRadioInterruptedListener() {
   ScopeLogger();
 
-  const auto err = radio_set_interrupted_cb(radio_instance_, RadioInterruptedCallback, this);
-  return CheckError("radio_set_interrupted_cb", err);
+  is_interrupted_listener_set = true;
+  return PlatformResult(ErrorCode::NO_ERROR);
 }
 
 common::PlatformResult FMRadioManager::UnsetFMRadioInterruptedListener() {
   ScopeLogger();
 
-  const auto err = radio_unset_interrupted_cb(radio_instance_);
-  return CheckError("radio_unset_interrupted_cb", err);
+  is_interrupted_listener_set = false;
+  return PlatformResult(ErrorCode::NO_ERROR);
 }
 
 common::PlatformResult FMRadioManager::SetAntennaChangeListener() {
index e32611d57bee9e290d4a724688537288d3d60075..9484e6bbc9fb9fb3715145dca4178c946cf57f6a 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <radio.h>
 #include <runtime_info.h>
+#include <sound_manager.h>
 
 #include "common/picojson.h"
 #include "common/platform_result.h"
@@ -61,6 +62,9 @@ class FMRadioManager {
   double GetSignalStrength();
   bool HasAntenna();
   const char* GetState();
+  bool IsInterruptedListenerSet();
+  radio_h GetRadioInstance();
+  sound_stream_info_h GetStreamInfo();
 
   void PostMessage(const std::string& msg) const;
   void PostResultSuccess(double callbackId, picojson::value* event) const;
@@ -71,6 +75,8 @@ class FMRadioManager {
   RadioInstance& instance_;
   radio_h radio_instance_;
   RadioScanData* scan_data;
+  sound_stream_info_h stream_info_;
+  bool is_interrupted_listener_set;
 };
 
 struct RadioData {