Merge "Implement broadcast radio announcements."

This commit is contained in:
Tomasz Wasilczyk
2018-01-03 20:13:28 +00:00
committed by Android (Google) Code Review
9 changed files with 196 additions and 2 deletions

View File

@@ -8,7 +8,9 @@ hidl_interface {
},
srcs: [
"types.hal",
"IAnnouncementObserver.hal",
"IBroadcastRadio.hal",
"ICloseHandle.hal",
"ITunerCallback.hal",
"ITunerSession.hal",
],
@@ -18,6 +20,8 @@ hidl_interface {
types: [
"AmFmBandRange",
"AmFmRegionConfig",
"Announcement",
"AnnouncementType",
"ConfigFlag",
"Constants",
"DabTableEntry",

View File

@@ -0,0 +1,30 @@
/* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.broadcastradio@2.0;
/**
* Callback interface for announcement observer.
*
* For typical configuration, the observer is a broadcast radio service.
*/
interface IAnnouncementObserver {
/**
* Called whenever announcement list has changed.
*
* @param announcements The complete list of currently active announcements.
*/
oneway onListUpdated(vec<Announcement> announcements);
};

View File

@@ -15,6 +15,8 @@
package android.hardware.broadcastradio@2.0;
import IAnnouncementObserver;
import ICloseHandle;
import ITunerCallback;
import ITunerSession;
@@ -66,7 +68,7 @@ interface IBroadcastRadio {
* @return session The session interface.
*/
openSession(ITunerCallback callback)
generates (Result result, ITunerSession session);
generates (Result result, ITunerSession session);
/**
* Fetch image from radio module cache.
@@ -100,4 +102,28 @@ interface IBroadcastRadio {
* or a zero-length vector if identifier doesn't exist.
*/
getImage(uint32_t id) generates (vec<uint8_t> image);
/**
* Registers announcement observer.
*
* If there is at least one observer registered, HAL implementation must
* notify about announcements even if no sessions are active.
*
* If the observer dies, the HAL implementation must unregister observer
* automatically.
*
* @param enabled The list of announcement types to watch for.
* @param cb The callback interface.
* @return result OK in case of success.
* NOT_SUPPORTED if the tuner doesn't support announcements.
* @return closeHandle A handle to unregister observer,
* nullptr if result was not OK.
*/
registerAnnouncementObserver(
vec<AnnouncementType> enabled,
IAnnouncementObserver cb
) generates (
Result result,
ICloseHandle closeHandle
);
};

View File

@@ -0,0 +1,32 @@
/* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.broadcastradio@2.0;
/**
* Represents a generic close handle to remove a callback that doesn't need
* active interface.
*/
interface ICloseHandle {
/**
* Closes the handle.
*
* The call must not fail and must only be issued once.
*
* After the close call is executed, no other calls to this interface
* are allowed.
*/
close();
};

View File

@@ -154,7 +154,7 @@ interface ITunerSession {
* @return results Operation completion status for parameters being set.
*/
setParameters(vec<VendorKeyValue> parameters)
generates (vec<VendorKeyValue> results);
generates (vec<VendorKeyValue> results);
/**
* Generic method for retrieving vendor-specific parameter values.

View File

@@ -141,6 +141,15 @@ Return<void> BroadcastRadio::getImage(uint32_t id, getImage_cb _hidl_cb) {
return {};
}
Return<void> BroadcastRadio::registerAnnouncementObserver(
const hidl_vec<AnnouncementType>& enabled, const sp<IAnnouncementObserver>& /* cb */,
registerAnnouncementObserver_cb _hidl_cb) {
ALOGV("%s(%s)", __func__, toString(enabled).c_str());
_hidl_cb(Result::NOT_SUPPORTED, nullptr);
return {};
}
} // namespace implementation
} // namespace V2_0
} // namespace broadcastradio

View File

@@ -36,6 +36,9 @@ struct BroadcastRadio : public IBroadcastRadio {
Return<void> getDabRegionConfig(getDabRegionConfig_cb _hidl_cb);
Return<void> openSession(const sp<ITunerCallback>& callback, openSession_cb _hidl_cb) override;
Return<void> getImage(uint32_t id, getImage_cb _hidl_cb);
Return<void> registerAnnouncementObserver(const hidl_vec<AnnouncementType>& enabled,
const sp<IAnnouncementObserver>& cb,
registerAnnouncementObserver_cb _hidl_cb);
std::reference_wrapper<const VirtualRadio> mVirtualRadio;
Properties mProperties;

View File

@@ -777,3 +777,55 @@ struct ProgramFilter {
*/
bool excludeModifications;
};
/**
* Type of an announcement.
*
* It maps to different announcement types per each radio technology.
*/
enum AnnouncementType : uint8_t {
/** DAB alarm, RDS emergency program type (PTY 31). */
EMERGENCY = 1,
/** DAB warning. */
WARNING,
/** DAB road traffic, RDS TA, HD Radio transportation. */
TRAFFIC,
/** Weather. */
WEATHER,
/** News. */
NEWS,
/** DAB event, special event. */
EVENT,
/** DAB sport report, RDS sports. */
SPORT,
/** All others. */
MISC,
};
/**
* A pointer to a station broadcasting active announcement.
*/
struct Announcement {
/**
* Program selector to tune to the announcement.
*/
ProgramSelector selector;
/** Announcement type. */
AnnouncementType type;
/**
* Vendor-specific information.
*
* It may be used for extra features, not supported by the platform,
* for example: com.me.hdradio.urgency=100; com.me.hdradio.certainity=50.
*/
vec<VendorKeyValue> vendorInfo;
};

View File

@@ -89,6 +89,10 @@ class TunerCallbackMock : public ITunerCallback {
utils::ProgramInfoSet mProgramList;
};
struct AnnouncementObserverMock : public IAnnouncementObserver {
MOCK_METHOD1(onListUpdated, Return<void>(const hidl_vec<Announcement>&));
};
class BroadcastRadioHalTest : public ::testing::VtsHalHidlTargetTestBase {
protected:
virtual void SetUp() override;
@@ -660,6 +664,40 @@ TEST_F(BroadcastRadioHalTest, GetProgramList) {
EXPECT_TRUE(stopResult.isOk());
}
/**
* Test announcement observer registration.
*
* Verifies that:
* - registerAnnouncementObserver either succeeds or returns NOT_SUPPORTED;
* - if it succeeds, it returns a valid close handle (which is a nullptr otherwise);
* - closing handle does not crash.
*/
TEST_F(BroadcastRadioHalTest, AnnouncementObserverRegistration) {
sp<AnnouncementObserverMock> observer = new AnnouncementObserverMock();
Result halResult = Result::UNKNOWN_ERROR;
sp<ICloseHandle> closeHandle = nullptr;
auto cb = [&](Result result, const sp<ICloseHandle>& closeHandle_) {
halResult = result;
closeHandle = closeHandle_;
};
auto hidlResult =
mModule->registerAnnouncementObserver({AnnouncementType::EMERGENCY}, observer, cb);
ASSERT_TRUE(hidlResult.isOk());
if (halResult == Result::NOT_SUPPORTED) {
ASSERT_EQ(nullptr, closeHandle.get());
printSkipped("Announcements not supported");
return;
}
ASSERT_EQ(Result::OK, halResult);
ASSERT_NE(nullptr, closeHandle.get());
closeHandle->close();
}
// TODO(b/70939328): test ProgramInfo's currentlyTunedId and
// currentlyTunedChannel once the program list is implemented.