зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset d1ad5d5bc00f (Bug 1041085) for red
This commit is contained in:
Родитель
1ec7ec8a2f
Коммит
610334f023
36
hal/Hal.cpp
36
hal/Hal.cpp
|
@ -1004,15 +1004,12 @@ ProcessPriorityToString(ProcessPriority aPriority,
|
||||||
}
|
}
|
||||||
|
|
||||||
static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
|
static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
|
||||||
static StaticAutoPtr<ObserverList<FMRadioRDSGroup> > sFMRadioRDSObservers;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
InitializeFMRadioObserver()
|
InitializeFMRadioObserver()
|
||||||
{
|
{
|
||||||
if (!sFMRadioObservers) {
|
if (!sFMRadioObservers) {
|
||||||
sFMRadioObservers = new ObserverList<FMRadioOperationInformation>;
|
sFMRadioObservers = new ObserverList<FMRadioOperationInformation>;
|
||||||
sFMRadioRDSObservers = new ObserverList<FMRadioRDSGroup>;
|
|
||||||
ClearOnShutdown(&sFMRadioRDSObservers);
|
|
||||||
ClearOnShutdown(&sFMRadioObservers);
|
ClearOnShutdown(&sFMRadioObservers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1037,27 +1034,6 @@ NotifyFMRadioStatus(const FMRadioOperationInformation& aFMRadioState) {
|
||||||
sFMRadioObservers->Broadcast(aFMRadioState);
|
sFMRadioObservers->Broadcast(aFMRadioState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
RegisterFMRadioRDSObserver(FMRadioRDSObserver* aFMRadioRDSObserver) {
|
|
||||||
AssertMainThread();
|
|
||||||
InitializeFMRadioObserver();
|
|
||||||
sFMRadioRDSObservers->AddObserver(aFMRadioRDSObserver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
UnregisterFMRadioRDSObserver(FMRadioRDSObserver* aFMRadioRDSObserver) {
|
|
||||||
AssertMainThread();
|
|
||||||
InitializeFMRadioObserver();
|
|
||||||
sFMRadioRDSObservers->RemoveObserver(aFMRadioRDSObserver);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
NotifyFMRadioRDSGroup(const FMRadioRDSGroup& aRDSGroup) {
|
|
||||||
InitializeFMRadioObserver();
|
|
||||||
sFMRadioRDSObservers->Broadcast(aRDSGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EnableFMRadio(const FMRadioSettings& aInfo) {
|
EnableFMRadio(const FMRadioSettings& aInfo) {
|
||||||
AssertMainThread();
|
AssertMainThread();
|
||||||
|
@ -1112,18 +1088,6 @@ CancelFMRadioSeek() {
|
||||||
PROXY_IF_SANDBOXED(CancelFMRadioSeek());
|
PROXY_IF_SANDBOXED(CancelFMRadioSeek());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
EnableRDS(uint32_t aMask) {
|
|
||||||
AssertMainThread();
|
|
||||||
PROXY_IF_SANDBOXED(EnableRDS(aMask));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DisableRDS() {
|
|
||||||
AssertMainThread();
|
|
||||||
PROXY_IF_SANDBOXED(DisableRDS());
|
|
||||||
}
|
|
||||||
|
|
||||||
FMRadioSettings
|
FMRadioSettings
|
||||||
GetFMBandSettings(FMRadioCountry aCountry) {
|
GetFMBandSettings(FMRadioCountry aCountry) {
|
||||||
FMRadioSettings settings;
|
FMRadioSettings settings;
|
||||||
|
|
26
hal/Hal.h
26
hal/Hal.h
|
@ -503,28 +503,12 @@ void RegisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
|
||||||
*/
|
*/
|
||||||
void UnregisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
|
void UnregisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
|
||||||
|
|
||||||
/**
|
|
||||||
* Register an observer for the FM radio.
|
|
||||||
*/
|
|
||||||
void RegisterFMRadioRDSObserver(hal::FMRadioRDSObserver* aRDSObserver);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister the observer for the FM radio.
|
|
||||||
*/
|
|
||||||
void UnregisterFMRadioRDSObserver(hal::FMRadioRDSObserver* aRDSObserver);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify observers that a call to EnableFMRadio, DisableFMRadio, or FMRadioSeek
|
* Notify observers that a call to EnableFMRadio, DisableFMRadio, or FMRadioSeek
|
||||||
* has completed, and indicate what the call returned.
|
* has completed, and indicate what the call returned.
|
||||||
*/
|
*/
|
||||||
void NotifyFMRadioStatus(const hal::FMRadioOperationInformation& aRadioState);
|
void NotifyFMRadioStatus(const hal::FMRadioOperationInformation& aRadioState);
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify observers of new RDS data
|
|
||||||
* This can be called on any thread.
|
|
||||||
*/
|
|
||||||
void NotifyFMRadioRDSGroup(const hal::FMRadioRDSGroup& aRDSGroup);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable the FM radio and configure it according to the settings in aInfo.
|
* Enable the FM radio and configure it according to the settings in aInfo.
|
||||||
*/
|
*/
|
||||||
|
@ -581,16 +565,6 @@ void CancelFMRadioSeek();
|
||||||
*/
|
*/
|
||||||
hal::FMRadioSettings GetFMBandSettings(hal::FMRadioCountry aCountry);
|
hal::FMRadioSettings GetFMBandSettings(hal::FMRadioCountry aCountry);
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable RDS data reception
|
|
||||||
*/
|
|
||||||
void EnableRDS(uint32_t aMask);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable RDS data reception
|
|
||||||
*/
|
|
||||||
void DisableRDS();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a watchdog to compulsively shutdown the system if it hangs.
|
* Start a watchdog to compulsively shutdown the system if it hangs.
|
||||||
* @param aMode Specify how to shutdown the system.
|
* @param aMode Specify how to shutdown the system.
|
||||||
|
|
|
@ -225,9 +225,7 @@ enum FMRadioCountry {
|
||||||
NUM_FM_RADIO_COUNTRY
|
NUM_FM_RADIO_COUNTRY
|
||||||
};
|
};
|
||||||
|
|
||||||
class FMRadioRDSGroup;
|
|
||||||
typedef Observer<FMRadioOperationInformation> FMRadioObserver;
|
typedef Observer<FMRadioOperationInformation> FMRadioObserver;
|
||||||
typedef Observer<FMRadioRDSGroup> FMRadioRDSObserver;
|
|
||||||
} // namespace hal
|
} // namespace hal
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -57,13 +57,5 @@ void
|
||||||
CancelFMRadioSeek()
|
CancelFMRadioSeek()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void
|
|
||||||
EnableRDS(uint32_t aMask)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void
|
|
||||||
DisableRDS()
|
|
||||||
{}
|
|
||||||
|
|
||||||
} // hal_impl
|
} // hal_impl
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -50,13 +49,10 @@ uint32_t GetFMRadioFrequency();
|
||||||
|
|
||||||
static int sRadioFD;
|
static int sRadioFD;
|
||||||
static bool sRadioEnabled;
|
static bool sRadioEnabled;
|
||||||
static bool sRDSEnabled;
|
|
||||||
static pthread_t sRadioThread;
|
static pthread_t sRadioThread;
|
||||||
static pthread_t sRDSThread;
|
|
||||||
static hal::FMRadioSettings sRadioSettings;
|
static hal::FMRadioSettings sRadioSettings;
|
||||||
static int sMsmFMVersion;
|
static int sMsmFMVersion;
|
||||||
static bool sMsmFMMode;
|
static bool sMsmFMMode;
|
||||||
static bool sRDSSupported;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
setControl(uint32_t id, int32_t value)
|
setControl(uint32_t id, int32_t value)
|
||||||
|
@ -315,8 +311,6 @@ EnableFMRadio(const hal::FMRadioSettings& aInfo)
|
||||||
hal::NotifyFMRadioStatus(info);
|
hal::NotifyFMRadioStatus(info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sRDSSupported = cap.capabilities & V4L2_CAP_RDS_CAPTURE;
|
|
||||||
sRadioSettings = aInfo;
|
sRadioSettings = aInfo;
|
||||||
|
|
||||||
if (sMsmFMMode) {
|
if (sMsmFMMode) {
|
||||||
|
@ -372,9 +366,6 @@ DisableFMRadio()
|
||||||
if (!sRadioEnabled)
|
if (!sRadioEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sRDSEnabled)
|
|
||||||
DisableRDS();
|
|
||||||
|
|
||||||
sRadioEnabled = false;
|
sRadioEnabled = false;
|
||||||
|
|
||||||
if (sMsmFMMode) {
|
if (sMsmFMMode) {
|
||||||
|
@ -503,186 +494,5 @@ void
|
||||||
CancelFMRadioSeek()
|
CancelFMRadioSeek()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/* Runs on the rds thread */
|
|
||||||
static void*
|
|
||||||
readRDSDataThread(void* data)
|
|
||||||
{
|
|
||||||
v4l2_rds_data rdsblocks[16];
|
|
||||||
uint16_t blocks[4];
|
|
||||||
|
|
||||||
ScopedClose pipefd((int)data);
|
|
||||||
|
|
||||||
ScopedClose epollfd(epoll_create(2));
|
|
||||||
if (epollfd < 0) {
|
|
||||||
HAL_LOG(("Could not create epoll FD for RDS thread (%d)", errno));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
epoll_event event = {
|
|
||||||
EPOLLIN,
|
|
||||||
{ 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
event.data.fd = pipefd;
|
|
||||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, pipefd, &event) < 0) {
|
|
||||||
HAL_LOG(("Could not set up epoll FD for RDS thread (%d)", errno));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.data.fd = sRadioFD;
|
|
||||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sRadioFD, &event) < 0) {
|
|
||||||
HAL_LOG(("Could not set up epoll FD for RDS thread (%d)", errno));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
epoll_event events[2] = {{ 0 }};
|
|
||||||
int event_count;
|
|
||||||
uint32_t block_bitmap = 0;
|
|
||||||
while ((event_count = epoll_wait(epollfd, events, 2, -1)) > 0 ||
|
|
||||||
errno == EINTR) {
|
|
||||||
bool RDSDataAvailable = false;
|
|
||||||
for (int i = 0; i < event_count; i++) {
|
|
||||||
if (events[i].data.fd == pipefd) {
|
|
||||||
if (!sRDSEnabled)
|
|
||||||
return nullptr;
|
|
||||||
char tmp[32];
|
|
||||||
TEMP_FAILURE_RETRY(read(pipefd, tmp, sizeof(tmp)));
|
|
||||||
} else if (events[i].data.fd == sRadioFD) {
|
|
||||||
RDSDataAvailable = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RDSDataAvailable)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ssize_t len =
|
|
||||||
TEMP_FAILURE_RETRY(read(sRadioFD, rdsblocks, sizeof(rdsblocks)));
|
|
||||||
if (len < 0) {
|
|
||||||
HAL_LOG(("Unexpected error while reading RDS data %d", errno));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int blockcount = len / sizeof(rdsblocks[0]);
|
|
||||||
int lastblock = -1;
|
|
||||||
for (int i = 0; i < blockcount; i++) {
|
|
||||||
if ((rdsblocks[i].block & V4L2_RDS_BLOCK_MSK) == V4L2_RDS_BLOCK_INVALID ||
|
|
||||||
rdsblocks[i].block & V4L2_RDS_BLOCK_ERROR) {
|
|
||||||
block_bitmap |= 1 << V4L2_RDS_BLOCK_INVALID;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int blocknum = rdsblocks[i].block & V4L2_RDS_BLOCK_MSK;
|
|
||||||
// In some cases, the full set of bits in an RDS group isn't
|
|
||||||
// needed, in which case version B RDS groups can be sent.
|
|
||||||
// Version B groups replace block C with block C' (V4L2_RDS_BLOCK_C_ALT).
|
|
||||||
// Block C' always stores the PI code, so receivers can find the PI
|
|
||||||
// code more quickly/reliably.
|
|
||||||
// However, we only process whole RDS groups, so it doesn't matter here.
|
|
||||||
if (blocknum == V4L2_RDS_BLOCK_C_ALT)
|
|
||||||
blocknum = V4L2_RDS_BLOCK_C;
|
|
||||||
if (blocknum > V4L2_RDS_BLOCK_D) {
|
|
||||||
HAL_LOG(("Unexpected RDS block number %d. This is a driver bug.",
|
|
||||||
blocknum));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blocknum == V4L2_RDS_BLOCK_A)
|
|
||||||
block_bitmap = 0;
|
|
||||||
|
|
||||||
// Skip the group if we skipped a block.
|
|
||||||
// This stops us from processing blocks sent out of order.
|
|
||||||
if (block_bitmap != ((1 << blocknum) - 1)) {
|
|
||||||
block_bitmap |= 1 << V4L2_RDS_BLOCK_INVALID;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
block_bitmap |= 1 << blocknum;
|
|
||||||
|
|
||||||
lastblock = blocknum;
|
|
||||||
blocks[blocknum] = (rdsblocks[i].msb << 8) | rdsblocks[i].lsb;
|
|
||||||
|
|
||||||
// Make sure we have all 4 blocks and that they're valid
|
|
||||||
if (block_bitmap != 0x0F)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
FMRadioRDSGroup group;
|
|
||||||
group.blockA() = blocks[V4L2_RDS_BLOCK_A];
|
|
||||||
group.blockB() = blocks[V4L2_RDS_BLOCK_B];
|
|
||||||
group.blockC() = blocks[V4L2_RDS_BLOCK_C];
|
|
||||||
group.blockD() = blocks[V4L2_RDS_BLOCK_D];
|
|
||||||
NotifyFMRadioRDSGroup(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sRDSPipeFD;
|
|
||||||
|
|
||||||
void
|
|
||||||
EnableRDS(uint32_t aMask)
|
|
||||||
{
|
|
||||||
if (!sRadioEnabled || !sRDSSupported)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (sMsmFMMode)
|
|
||||||
setControl(V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK, aMask);
|
|
||||||
|
|
||||||
if (sRDSEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int pipefd[2];
|
|
||||||
int rc = pipe2(pipefd, O_NONBLOCK);
|
|
||||||
if (rc < 0) {
|
|
||||||
HAL_LOG(("Could not create RDS thread signaling pipes (%d)", rc));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedClose writefd(pipefd[1]);
|
|
||||||
ScopedClose readfd(pipefd[0]);
|
|
||||||
|
|
||||||
rc = setControl(V4L2_CID_RDS_RECEPTION, true);
|
|
||||||
if (rc < 0) {
|
|
||||||
HAL_LOG(("Could not enable RDS reception (%d)", rc));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sRDSPipeFD = writefd;
|
|
||||||
|
|
||||||
sRDSEnabled = true;
|
|
||||||
|
|
||||||
rc = pthread_create(&sRDSThread, nullptr,
|
|
||||||
readRDSDataThread, (void*)pipefd[0]);
|
|
||||||
if (rc) {
|
|
||||||
HAL_LOG(("Could not start RDS reception thread (%d)", rc));
|
|
||||||
setControl(V4L2_CID_RDS_RECEPTION, false);
|
|
||||||
sRDSEnabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
readfd.forget();
|
|
||||||
writefd.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DisableRDS()
|
|
||||||
{
|
|
||||||
if (!sRadioEnabled || !sRDSEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int rc = setControl(V4L2_CID_RDS_RECEPTION, false);
|
|
||||||
if (rc < 0) {
|
|
||||||
HAL_LOG(("Could not disable RDS reception (%d)", rc));
|
|
||||||
}
|
|
||||||
|
|
||||||
sRDSEnabled = false;
|
|
||||||
|
|
||||||
write(sRDSPipeFD, "x", 1);
|
|
||||||
|
|
||||||
pthread_join(sRDSThread, nullptr);
|
|
||||||
|
|
||||||
close(sRDSPipeFD);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // hal_impl
|
} // hal_impl
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -69,13 +69,6 @@ struct FMRadioOperationInformation {
|
||||||
uint32_t frequency;
|
uint32_t frequency;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FMRadioRDSGroup {
|
|
||||||
uint16_t blockA;
|
|
||||||
uint16_t blockB;
|
|
||||||
uint16_t blockC;
|
|
||||||
uint16_t blockD;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FMRadioSettings {
|
struct FMRadioSettings {
|
||||||
FMRadioCountry country;
|
FMRadioCountry country;
|
||||||
uint32_t upperLimit;
|
uint32_t upperLimit;
|
||||||
|
|
|
@ -426,18 +426,6 @@ CancelFMRadioSeek()
|
||||||
NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
|
NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
EnableRDS(uint32_t aMask)
|
|
||||||
{
|
|
||||||
NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DisableRDS()
|
|
||||||
{
|
|
||||||
NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FactoryReset(FactoryResetReason& aReason)
|
FactoryReset(FactoryResetReason& aReason)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче