int SoftapController::startSoftap() { int i, ret = 0; THostapdCLICmd cmd; if(mPid == 1) { LOGE("Softap already started"); return 0; } if (property_set("ctl.start", "hostapd") < 0) { LOGE("Failed to start hostapd"); return -1; } cmd.eCmdType = HOSTAPD_CLI_CMD_PING; for(i=0; i < HOSTAPD_MAX_RETRIES; i++) { usleep(AP_BSS_START_DELAY); ret = HostapdCLI_RunCommand("tiap0", &cmd); if(ret == -1) { continue; } else { LOGD("Softap startap - Ok"); mPid = 1; return 0; } } acquire_wake_lock(PARTIAL_WAKE_LOCK,"hotspot_wake_lock"); return ret; }
/******************************************************************************* ** ** Function GKI_run ** ** Description This function runs a task ** ** Parameters: start: TRUE start system tick (again), FALSE stop ** ** Returns void ** *********************************************************************************/ void gki_system_tick_start_stop_cback(BOOLEAN start) { tGKI_OS *p_os = &gki_cb.os; volatile int *p_run_cond = &p_os->no_timer_suspend; volatile static int wake_lock_count; if ( FALSE == start ) { /* this can lead to a race condition. however as we only read this variable in the timer loop * we should be fine with this approach. otherwise uncomment below mutexes. */ /* GKI_disable(); */ *p_run_cond = GKI_TIMER_TICK_STOP_COND; /* GKI_enable(); */ #ifdef GKI_TICK_TIMER_DEBUG BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> STOP GKI_timer_update(), wake_lock_count:%d", --wake_lock_count); #endif release_wake_lock(WAKE_LOCK_ID); gki_cb.os.gki_timer_wake_lock_on = 0; } else { /* restart GKI_timer_update() loop */ acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); gki_cb.os.gki_timer_wake_lock_on = 1; *p_run_cond = GKI_TIMER_TICK_RUN_COND; pthread_mutex_lock( &p_os->gki_timer_mutex ); pthread_cond_signal( &p_os->gki_timer_cond ); pthread_mutex_unlock( &p_os->gki_timer_mutex ); #ifdef GKI_TICK_TIMER_DEBUG BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> START GKI_timer_update(), wake_lock_count:%d", ++wake_lock_count ); #endif } }
static void acquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj) { if (idObj == NULL) { throw_NullPointerException(env, "id is null"); return ; } const char *id = env->GetStringUTFChars(idObj, NULL); acquire_wake_lock(lock, id); env->ReleaseStringUTFChars(idObj, id); }
void gki_system_tick_start_stop_cback(BOOLEAN start) { tGKI_OS *p_os = &gki_cb.os; int *p_run_cond = &p_os->no_timer_suspend; static int wake_lock_count; if ( FALSE == start ) { /* gki_system_tick_start_stop_cback() maybe called even so it was already stopped! */ if (GKI_TIMER_TICK_RUN_COND == *p_run_cond) { #ifdef NO_GKI_RUN_RETURN /* take free mutex to block timer thread */ pthread_mutex_lock(&p_os->gki_timer_mutex); #endif /* this can lead to a race condition. however as we only read this variable in the * timer loop we should be fine with this approach. otherwise uncomment below mutexes. */ /* GKI_disable(); */ *p_run_cond = GKI_TIMER_TICK_STOP_COND; /* GKI_enable(); */ GKI_TIMER_TRACE(">>> STOP GKI_timer_update(), wake_lock_count:%d", --wake_lock_count); release_wake_lock(WAKE_LOCK_ID); g_GkiTimerWakeLockOn = 0; } } else { /* restart GKI_timer_update() loop */ acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); g_GkiTimerWakeLockOn = 1; *p_run_cond = GKI_TIMER_TICK_RUN_COND; #ifdef NO_GKI_RUN_RETURN pthread_mutex_unlock( &p_os->gki_timer_mutex ); #else pthread_mutex_lock( &p_os->gki_timer_mutex ); pthread_cond_signal( &p_os->gki_timer_cond ); pthread_mutex_unlock( &p_os->gki_timer_mutex ); #endif GKI_TIMER_TRACE(">>> START GKI_timer_update(), wake_lock_count:%d", ++wake_lock_count ); } }
static void bt_hold_wake_lock(int hold) { if (hold == 1){ // acquire wake lock if (!wake_lock_acquired){ acquire_wake_lock(PARTIAL_WAKE_LOCK, "btdrv");aa wake_lock_acquired = 1; } } else if (hold == 0){ // release wake lock if (wake_lock_acquired){ release_wake_lock("btdrv"); wake_lock_acquired = 0; } } }
ssize_t AudioStreamInALSA::read(void *buffer, ssize_t bytes) { /*m@nufront start*/ /*AutoMutex lock(mLock);*/ android::AutoMutex lock(mLock); /*m@nufront end*/ if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioInLock"); mPowerLock = true; } acoustic_device_t *aDev = acoustics(); // If there is an acoustics module read method, then it overrides this // implementation (unlike AudioStreamOutALSA write). if (aDev && aDev->read) return aDev->read(aDev, buffer, bytes); snd_pcm_sframes_t n, frames = snd_pcm_bytes_to_frames(mHandle->handle, bytes); status_t err; do { n = snd_pcm_readi(mHandle->handle, buffer, frames); /*a@nufront start*/ if (n == -EPIPE) { ZJFLOGD("xrun."); xrun(mHandle->handle); } /*a@nufront end*/ if (n < frames) { if (mHandle->handle) { if (n < 0) { n = snd_pcm_recover(mHandle->handle, n, 0); if (aDev && aDev->recover) aDev->recover(aDev, n); } else n = snd_pcm_prepare(mHandle->handle); } return static_cast<ssize_t>(n); } } while (n == -EAGAIN); return static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n)); }
status_t SpeechVMRecorder::Open() { mMutex.lock(); ALOGD("+%s()", __FUNCTION__); ASSERT(mEnable == false); int ret = acquire_wake_lock(PARTIAL_WAKE_LOCK, VM_RECORD_WAKELOCK_NAME); ALOGD("%s(), acquire_wake_lock: %s, return %d.", __FUNCTION__, VM_RECORD_WAKELOCK_NAME, ret); // create another thread to avoid fwrite() block CCCI read thread pthread_create(&mRecordThread, NULL, DumpVMRecordDataThread, (void *)this); mMutex.unlock(); mEnable = true; ALOGD("-%s(), mEnable=%d ", __FUNCTION__, mEnable ); return NO_ERROR; }
status_t SpeechVMRecorder::Open() { pthread_mutex_lock(&mMutex); ALOGD("+%s()", __FUNCTION__); ASSERT(mStarting == false); int ret = acquire_wake_lock(PARTIAL_WAKE_LOCK, VM_RECORD_WAKELOCK_NAME); ALOGD("%s(), acquire_wake_lock: %s, return %d.", __FUNCTION__, VM_RECORD_WAKELOCK_NAME, ret); // open modem record function // open record file // create another thread to avoid fwrite() block CCCI read thread pthread_create(&mRecordThread, NULL, DumpVMRecordDataThread, (void *)this); pthread_mutex_unlock(&mMutex); ALOGD("-%s()", __FUNCTION__); return NO_ERROR; }
void TrimTask::run() { acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock); for (const auto& path : mPaths) { LOG(DEBUG) << "Starting trim of " << path; int fd = open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW); if (fd < 0) { PLOG(WARNING) << "Failed to open " << path; continue; } struct fstrim_range range; memset(&range, 0, sizeof(range)); range.len = ULLONG_MAX; nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME); if (ioctl(fd, (mFlags & Flags::kDeepTrim) ? FIDTRIM : FITRIM, &range)) { PLOG(WARNING) << "Trim failed on " << path; notifyResult(path, -1, -1); } else { nsecs_t delta = systemTime(SYSTEM_TIME_BOOTTIME) - start; LOG(INFO) << "Trimmed " << range.len << " bytes on " << path << " in " << nanoseconds_to_milliseconds(delta) << "ms"; notifyResult(path, range.len, delta); } close(fd); if (mFlags & Flags::kBenchmarkAfter) { #if BENCHMARK_ENABLED BenchmarkPrivate(path); #else LOG(DEBUG) << "Benchmark disabled"; #endif } } release_wake_lock(kWakeLock); }
static int processRxBuffer(RilClientPrv *prv, void *buffer, size_t buflen) { Parcel p; int32_t response_type; status_t status; int ret = RIL_CLIENT_ERR_SUCCESS; acquire_wake_lock(PARTIAL_WAKE_LOCK, RIL_CLIENT_WAKE_LOCK); p.setData((uint8_t *)buffer, buflen); status = p.readInt32(&response_type); if (DBG) ALOGD("%s: status %d response_type %d", __FUNCTION__, status, response_type); if (status != NO_ERROR) { ret = RIL_CLIENT_ERR_IO; goto EXIT; } // FOr unsolicited response. if (response_type == RESPONSE_UNSOLICITED) { ret = processUnsolicited(prv, p); } // For solicited response. else if (response_type == RESPONSE_SOLICITED) { ret = processSolicited(prv, p); if (ret != RIL_CLIENT_ERR_SUCCESS && prv->err_cb) { prv->err_cb(prv->err_cb_data, ret); } } else { ret = RIL_CLIENT_ERR_INVAL; } EXIT: release_wake_lock(RIL_CLIENT_WAKE_LOCK); return ret; }
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { ALOG_ASSERT(bufferSize >= 1); AutoMutex _l(mLock); struct input_event readBuffer[bufferSize]; RawEvent* event = buffer; size_t capacity = bufferSize; bool awoken = false; for (;;) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); // Reopen input devices if needed. if (mNeedToReopenDevices) { mNeedToReopenDevices = false; LOGI("Reopening all input devices due to a configuration change."); closeAllDevicesLocked(); mNeedToScanDevices = true; break; // return to the caller before we actually rescan } // Report any devices that had last been added/removed. while (mClosingDevices) { Device* device = mClosingDevices; ALOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; event->when = now; event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; event->type = DEVICE_REMOVED; event += 1; delete device; mNeedToSendFinishedDeviceScan = true; if (--capacity == 0) { break; } } if (mNeedToScanDevices) { mNeedToScanDevices = false; scanDevicesLocked(); mNeedToSendFinishedDeviceScan = true; } while (mOpeningDevices != NULL) { Device* device = mOpeningDevices; ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; event->when = now; event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; event->type = DEVICE_ADDED; event += 1; mNeedToSendFinishedDeviceScan = true; if (--capacity == 0) { break; } } if (mNeedToSendFinishedDeviceScan) { mNeedToSendFinishedDeviceScan = false; event->when = now; event->type = FINISHED_DEVICE_SCAN; event += 1; if (--capacity == 0) { break; } } // Grab the next input event. bool deviceChanged = false; while (mPendingEventIndex < mPendingEventCount) { const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++]; if (eventItem.data.u32 == EPOLL_ID_INOTIFY) { if (eventItem.events & EPOLLIN) { mPendingINotify = true; } else { ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events); } continue; } if (eventItem.data.u32 == EPOLL_ID_WAKE) { if (eventItem.events & EPOLLIN) { ALOGV("awoken after wake()"); awoken = true; char buffer[16]; ssize_t nRead; do { nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); } else { ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.", eventItem.events); } continue; } ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32); if (deviceIndex < 0) { ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.", eventItem.events, eventItem.data.u32); continue; } Device* device = mDevices.valueAt(deviceIndex); if (eventItem.events & EPOLLIN) { int32_t readSize = read(device->fd, readBuffer, sizeof(struct input_event) * capacity); if (readSize == 0 || (readSize < 0 && errno == ENODEV)) { // Device was removed before INotify noticed. ALOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d capacity: %d errno: %d)\n", device->fd, readSize, bufferSize, capacity, errno); deviceChanged = true; closeDeviceLocked(device); } else if (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { ALOGW("could not get event (errno=%d)", errno); } } else if ((readSize % sizeof(struct input_event)) != 0) { LOGE("could not get event (wrong size: %d)", readSize); } else { int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; size_t count = size_t(readSize) / sizeof(struct input_event); for (size_t i = 0; i < count; i++) { const struct input_event& iev = readBuffer[i]; ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); #ifdef HAVE_POSIX_CLOCKS // Use the time specified in the event instead of the current time // so that downstream code can get more accurate estimates of // event dispatch latency from the time the event is enqueued onto // the evdev client buffer. // // The event's timestamp fortuitously uses the same monotonic clock // time base as the rest of Android. The kernel event device driver // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts(). // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a // system call that also queries ktime_get_ts(). event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL + nsecs_t(iev.time.tv_usec) * 1000LL; ALOGV("event time %lld, now %lld", event->when, now); #else event->when = now; #endif event->deviceId = deviceId; event->type = iev.type; event->scanCode = iev.code; event->value = iev.value; event->keyCode = AKEYCODE_UNKNOWN; event->flags = 0; if (iev.type == EV_KEY && device->keyMap.haveKeyLayout()) { status_t err = device->keyMap.keyLayoutMap->mapKey(iev.code, &event->keyCode, &event->flags); ALOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n", iev.code, event->keyCode, event->flags, err); } event += 1; } capacity -= count; if (capacity == 0) { // The result buffer is full. Reset the pending event index // so we will try to read the device again on the next iteration. mPendingEventIndex -= 1; break; } } } else { ALOGW("Received unexpected epoll event 0x%08x for device %s.", eventItem.events, device->identifier.name.string()); } } // readNotify() will modify the list of devices so this must be done after // processing all other events to ensure that we read all remaining events // before closing the devices. if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) { mPendingINotify = false; readNotifyLocked(); deviceChanged = true; } // Report added or removed devices immediately. if (deviceChanged) { continue; } // Return now if we have collected any events or if we were explicitly awoken. if (event != buffer || awoken) { break; } // Poll for events. Mind the wake lock dance! // We hold a wake lock at all times except during epoll_wait(). This works due to some // subtle choreography. When a device driver has pending (unread) events, it acquires // a kernel wake lock. However, once the last pending event has been read, the device // driver will release the kernel wake lock. To prevent the system from going to sleep // when this happens, the EventHub holds onto its own user wake lock while the client // is processing events. Thus the system can only sleep if there are no events // pending or currently being processed. // // The timeout is advisory only. If the device is asleep, it will not wake just to // service the timeout. mPendingEventIndex = 0; mLock.unlock(); // release lock before poll, must be before release_wake_lock release_wake_lock(WAKE_LOCK_ID); int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock if (pollResult == 0) { // Timed out. mPendingEventCount = 0; break; } if (pollResult < 0) { // An error occurred. mPendingEventCount = 0; // Sleep after errors to avoid locking up the system. // Hopefully the error is transient. if (errno != EINTR) { ALOGW("poll failed (errno=%d)\n", errno); usleep(100000); } } else { // Some events occurred. mPendingEventCount = size_t(pollResult); // On an SMP system, it is possible for the framework to read input events // faster than the kernel input device driver can produce a complete packet. // Because poll() wakes up as soon as the first input event becomes available, // the framework will often end up reading one event at a time until the // packet is complete. Instead of one call to read() returning 71 events, // it could take 71 calls to read() each returning 1 event. // // Sleep for a short period of time after waking up from the poll() to give // the kernel time to finish writing the entire packet of input events. if (mNumCpus > 1) { usleep(250); } } } // All done, return the number of events we read. return event - buffer; }
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes) { AutoMutex lock(mLock); if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); mPowerLock = true; mHandle->module->popAttenu(0); // 20100604 [email protected], No pop noise set(amp on delay) [START_LGE] mHandle->module->route(mHandle, mHandle->curDev, mHandle->curMode); //[email protected] 20100308 codec_onoff usleep(35000); //201104011 [email protected], fix sound tick noise from global B } /* check if handle is still valid, otherwise we are coming out of standby */ if(mHandle->handle == NULL) { nsecs_t previously = systemTime(); mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); nsecs_t delta = systemTime() - previously; LOGE("1.RE-OPEN AFTER STANDBY:: took %llu msecs\n", ns2ms(delta)); } acoustic_device_t *aDev = acoustics(); // For output, we will pass the data on to the acoustics module, but the actual // data is expected to be sent to the audio device directly as well. if (aDev && aDev->write) aDev->write(aDev, buffer, bytes); #if 0 snd_pcm_sframes_t n; #else //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. snd_pcm_sframes_t n = 0; #endif size_t sent = 0; status_t err; do { //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [START] if(mHandle->handle != NULL) { //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [END] n = snd_pcm_writei(mHandle->handle, (char *)buffer + sent, snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent)); //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [START] } else{ nsecs_t previously = systemTime(); mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); nsecs_t delta = systemTime() - previously; LOGD("2.RE-OPEN AFTER STANDBY:: took %llu msecs\n", ns2ms(delta)); } //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [END] if (n == -EBADFD) { // Somehow the stream is in a bad state. The driver probably // has a bug and snd_pcm_recover() doesn't seem to handle this. mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); if (aDev && aDev->recover) aDev->recover(aDev, n); //bail if (n) return static_cast<ssize_t>(n); } else if (n < 0) { if (mHandle->handle) { // snd_pcm_recover() will return 0 if successful in recovering from // an error, or -errno if the error was unrecoverable. n = snd_pcm_recover(mHandle->handle, n, 1); if (aDev && aDev->recover) aDev->recover(aDev, n); if (n) return static_cast<ssize_t>(n); } } else { if(mHandle->handle){ //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. mFrameCount += n; sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n)); //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [START] } else{ nsecs_t previously = systemTime(); mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); nsecs_t delta = systemTime() - previously; LOGD("3.RE-OPEN AFTER STANDBY:: took %llu msecs\n", ns2ms(delta)); } //[email protected] - BT connect -> music play -> voice dialer start/end 시 music restart 되는 현상 수정. [END] } } while (mHandle->handle && sent < bytes); return sent; }
bool EventHub::getEvent(RawEvent* outEvent) { outEvent->deviceId = 0; outEvent->type = 0; outEvent->scanCode = 0; outEvent->keyCode = 0; outEvent->flags = 0; outEvent->value = 0; outEvent->when = 0; status_t err; LOGV("EventHub::getEvent() enter"); // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; mNeedToSendFinishedDeviceScan = true; } for (;;) { // Report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = DEVICE_REMOVED; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); delete device; mNeedToSendFinishedDeviceScan = true; return true; } if (mOpeningDevices != NULL) { device_t* device = mOpeningDevices; LOGV("Reporting device opened: id=0x%x, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = DEVICE_ADDED; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); mNeedToSendFinishedDeviceScan = true; return true; } if (mNeedToSendFinishedDeviceScan) { mNeedToSendFinishedDeviceScan = false; outEvent->type = FINISHED_DEVICE_SCAN; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); return true; } // Grab the next input event for device mDevices[mInputDeviceIndex]. for (;;) { #ifdef HAVE_TSLIB //Checks if we have to send any more TS events read by input-raw plugin //else we process other events if (tsSamp.total_events && tsSamp.tsSampleReady) { LOGV("Processing TS Event"); outEvent->deviceId = mDevices[tsSamp.tsIndex]->id; outEvent->type = tsSamp.ev[numOfEventsSent].type; outEvent->scanCode = tsSamp.ev[numOfEventsSent].code; outEvent->keyCode = tsSamp.ev[numOfEventsSent].code; outEvent->value = tsSamp.ev[numOfEventsSent].value; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); switch (outEvent->type) { case EV_KEY: outEvent->keyCode = AKEYCODE_UNKNOWN; outEvent->flags = 0; break; case EV_ABS: switch (outEvent->scanCode) { case ABS_X: outEvent->value = tsSamp.x; LOGV("outEvent->valueX=%d",outEvent->value); break; case ABS_Y: outEvent->value = tsSamp.y; LOGV("outEvent->valueY=%d",outEvent->value); break; case ABS_PRESSURE: outEvent->value = tsSamp.pressure; LOGV("outEvent->valueP=%d",outEvent->value); break; } break; } LOGV("%s (id: 0x%x) got: t0=%d, t1=%d, type=%d, code=%d, v=%d," " keyCode=%d, flags=0x%08x", mDevices[tsSamp.tsIndex]->path.string(), outEvent->deviceId, (int) tsSamp.ev[numOfEventsSent].time.tv_sec, (int) tsSamp.ev[numOfEventsSent].time.tv_usec, outEvent->type,outEvent->scanCode, outEvent->value, outEvent->keyCode,outEvent->flags); numOfEventsSent++; LOGV("numOfEventsSent: %d, tsSamp.total_events: %d", numOfEventsSent, tsSamp.total_events); LOGV("EventHub::getEvent() exit"); if (numOfEventsSent == tsSamp.total_events){ //All the events from the read call have been dealt with, //clearing tsSamp for next call. tsSamp.total_events = 0; tsSamp.tsSampleReady = 0; numOfEventsSent = 0; } return true; } #endif // Consume buffered input events, if any. if (mInputBufferIndex < mInputBufferCount) { const struct input_event& iev = mInputBufferData[mInputBufferIndex++]; const device_t* device = mDevices[mInputDeviceIndex]; LOGV("%s (id: 0x%x) got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(), device->id,(int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = iev.type; outEvent->scanCode = iev.code; if (iev.type == EV_KEY) { err = device->layoutMap->map(iev.code,& outEvent->keyCode, & outEvent->flags); if (err != 0) { LOGV("EV_KEY event, error (%d) accessing device layout map \n",err); outEvent->keyCode = AKEYCODE_UNKNOWN; outEvent->flags = 0; } } else { outEvent->keyCode = iev.code; } LOGV("iev.code=%d keyCode=%d flags=0x%08x \n",iev.code, outEvent->keyCode, outEvent->flags); outEvent->value = iev.value; // Use an event timestamp in the same timebase as // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis() // as expected by the rest of the system. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); LOGV("EventHub::getEvent() exit"); return true; } // Finish reading all events from devices identified in previous poll(). // This code assumes that mInputDeviceIndex is initially 0 and that the // revents member of pollfd is initialized to 0 when the device is first added. // Since mFDs[0] is used for inotify, we process regular events starting at index 1. mInputDeviceIndex += 1; if (mInputDeviceIndex >= mFDCount) { LOGV("Done processing events received in last poll for all devices."); break; } const struct pollfd& pfd = mFDs[mInputDeviceIndex]; if (pfd.revents & POLLIN) { #ifdef HAVE_TSLIB LOGV("Reading events from device. id: 0x%x , mInputDeviceIndex: %d, fd: %d, mTS->fd: %d", mDevices[mInputDeviceIndex]->id,mInputDeviceIndex, mFDs[mInputDeviceIndex].fd, mTS->fd); if (mTS != NULL) { if (mFDs[mInputDeviceIndex].fd != mTS->fd ) { #endif int32_t readSize = read(pfd.fd, mInputBufferData, sizeof(struct input_event) * INPUT_BUFFER_SIZE); if (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { LOGW("could not get event (errno=%d)", errno); } } else if ((readSize % sizeof(struct input_event)) != 0) { LOGE("could not get event (wrong size: %d)", readSize); } else { mInputBufferCount = readSize / sizeof(struct input_event); mInputBufferIndex = 0; LOGV("Buffered %d events from device", mInputBufferCount); } #ifdef HAVE_TSLIB } else{ int res = ts_read(mTS, &tsSamp, 1); if (res < 0) { LOGE("[EventHub::after poll] Error in ts_read()"); } else { tsSamp.tsIndex = mInputDeviceIndex; LOGV("After ts_read call: tsSamp[total_events: %d," " tsIndex: %d tsSampleReady: %d] res:%d ", tsSamp.total_events,tsSamp.tsIndex, tsSamp.tsSampleReady,res); //we have read a TS event, we want to process this now. } } } else { LOGE("EventHub:: ERROR in setup of mTS: mTS is NULL!"); } #endif }//end of if (pfd.revents & POLLIN) } //end of for(;;) get next input event #if HAVE_INOTIFY // readNotify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { readNotify(mFDs[0].fd); mFDs[0].revents = 0; LOGV("After readNotify()"); continue; // report added or removed devices immediately } #endif mInputDeviceIndex = 0; // Poll for events. Mind the wake lock dance! // We hold a wake lock at all times except during poll(). This works due to some // subtle choreography. When a device driver has pending (unread) events, it acquires // a kernel wake lock. However, once the last pending event has been read, the device // driver will release the kernel wake lock. To prevent the system from going to sleep // when this happens, the EventHub holds onto its own user wake lock while the client // is processing events. Thus the system can only sleep if there are no events // pending or currently being processed. release_wake_lock(WAKE_LOCK_ID); LOGV("Calling Poll()"); int pollResult = poll(mFDs, mFDCount, -1); LOGV("After calling Poll()"); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollResult <= 0) { if (errno != EINTR) { LOGW("poll failed (errno=%d)\n", errno); usleep(100000); } } }//end of for(;;) }//end of getEvent()
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes) { AutoMutex lock(mLock); if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); mPowerLock = true; usleep(35000); //201104011 [email protected], fix sound tick noise from global B } /* check if handle is still valid, otherwise we are coming out of standby */ if(mHandle->handle == NULL) { nsecs_t previously = systemTime(); mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode, mHandle->curChannels); nsecs_t delta = systemTime() - previously; LOGE("RE-OPEN AFTER STANDBY:: took %llu msecs\n", ns2ms(delta)); } acoustic_device_t *aDev = acoustics(); // For output, we will pass the data on to the acoustics module, but the actual // data is expected to be sent to the audio device directly as well. if (aDev && aDev->write) aDev->write(aDev, buffer, bytes); snd_pcm_sframes_t n; size_t sent = 0; status_t err; while (mHandle->handle && sent < bytes) { n = snd_pcm_writei(mHandle->handle, (char *)buffer + sent, snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent)); if (n == -EBADFD) { // Somehow the stream is in a bad state. The driver probably // has a bug and snd_pcm_recover() doesn't seem to handle this. mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode, mHandle->curChannels); if (aDev && aDev->recover) aDev->recover(aDev, n); } else if (n < 0) { if (mHandle->handle) { // snd_pcm_recover() will return 0 if successful in recovering from // an error, or -errno if the error was unrecoverable. n = snd_pcm_recover(mHandle->handle, n, 1); if (aDev && aDev->recover) aDev->recover(aDev, n); if (n) return static_cast<ssize_t>(n); } } else { if (mHandle->handle) { mFrameCount += n; sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n)); } } } return sent; }
ssize_t AudioStreamInALSA::read(void *buffer, ssize_t bytes) { AutoMutex lock(mLock); if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioInLock"); mPowerLock = true; } acoustic_device_t *aDev = acoustics(); // If there is an acoustics module read method, then it overrides this // implementation (unlike AudioStreamOutALSA write). if (aDev && aDev->read) return aDev->read(aDev, buffer, bytes); snd_pcm_sframes_t n, frames = snd_pcm_bytes_to_frames(mHandle->handle, bytes); status_t err; do { n = snd_pcm_readi(mHandle->handle, buffer, frames); #ifdef DROPFRAME #ifdef DROPFRAME2 FrameNumber++; if (!(FrameNumber % 17) && (FrameNumber <= 1700)) { n = snd_pcm_readi(mHandle->handle, buffer, frames); } if (!(FrameNumber % 176)) { n = snd_pcm_readi(mHandle->handle, buffer, frames); } if (FrameNumber == 1764) { FrameNumber = 0; n = snd_pcm_readi(mHandle->handle, buffer, frames); } #else FrameNumber++; if (FrameNumber == 624/*137* rane@2012 07 20*/) { FrameNumber = 0; n = snd_pcm_readi(mHandle->handle, buffer, frames); } #endif #endif if (n < frames) { if (mHandle->handle) { if (n < 0) { n = snd_pcm_recover(mHandle->handle, n, 0); if (aDev && aDev->recover) aDev->recover(aDev, n); } else n = snd_pcm_prepare(mHandle->handle); } return static_cast<ssize_t>(n); } } while (n == -EAGAIN); return static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n)); }
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType, int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen) { *outDeviceId = 0; *outType = 0; *outScancode = 0; *outKeycode = 0; *outFlags = 0; *outValue = 0; *outWhen = 0; status_t err; fd_set readfds; int maxFd = -1; int cc; int i; int res; int pollres; struct input_event iev; // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; } while(1) { #ifdef HAVE_TSLIB //Checks if we have to send any more events read by input-raw plugin. if(!samp.total_events) { #endif // First, report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_REMOVED; delete device; return true; } if (mOpeningDevices != NULL) { device_t* device = mOpeningDevices; LOGV("Reporting device opened: id=0x%x, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_ADDED; return true; } release_wake_lock(WAKE_LOCK_ID); pollres = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollres <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } continue; } //printf("poll %d, returned %d\n", mFDCount, pollres); // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] for(i = 1; i < mFDCount; i++) { if(mFDs[i].revents) { LOGV("revents for %d = 0x%08x", i, mFDs[i].revents); if(mFDs[i].revents & POLLIN) { #ifdef HAVE_TSLIB LOGV("Inside EventHub.cpp with mFDs[i].fd=%d \n", mFDs[i].fd); if (mTS != NULL) { if (mFDs[i].fd != mTS->fd ) { LOGV("mFDs[%d].fd = %d and mTS->fd = %d", i, mFDs[i].fd, mTS->fd); #endif res = read(mFDs[i].fd, &iev, sizeof(iev)); #ifdef HAVE_TSLIB } else{ LOGV("mTS->fd = %d", mTS->fd); LOGV("tslib: calling ts_read from eventhub\n"); res = ts_read(mTS, &samp, 1); if (res < 0) { LOGE("[EventHub.cpp:: After Poll] Error in ts_read()\n"); } else { numOfEventsSent = 0; samp.tsIndex = i; break; } } } else { LOGE("ERROR in setup of mTS: mTS is NULL!\n"); } #endif if (res == sizeof(iev) #ifdef HAVE_TSLIB || ((iev.code == 0x1d || iev.code == 0x1e) && res >= 0) #endif ) { LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", mDevices[i]->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); *outDeviceId = mDevices[i]->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = iev.type; *outScancode = iev.code; if (iev.type == EV_KEY) { err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags); LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n", iev.code, *outKeycode, *outFlags, err); if (err != 0) { *outKeycode = 0; *outFlags = 0; } } else { *outKeycode = iev.code; } *outValue = iev.value; *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); return true; } else { if (res<0) { LOGW("could not get event (errno=%d)", errno); } else { LOGE("could not get event (wrong size: %d)", res); } continue; } } } } // read_notify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { read_notify(mFDs[0].fd); } #ifdef HAVE_TSLIB } if(samp.total_events) { *outDeviceId = mDevices[samp.tsIndex]->id; *outType = samp.ev[numOfEventsSent].type; *outScancode = samp.ev[numOfEventsSent].code; if (samp.ev[numOfEventsSent].type == EV_KEY) { err = mDevices[samp.tsIndex]->layoutMap->map(samp.ev[numOfEventsSent].code, outKeycode, outFlags); if (err != 0) { *outKeycode = 0; *outFlags = 0; } } else { *outKeycode = samp.ev[numOfEventsSent].code; } if(*outType == EV_ABS) { if(*outScancode == ABS_X) *outValue = samp.x; if(*outScancode == ABS_Y) *outValue = samp.y; if(*outScancode == ABS_PRESSURE) *outValue = samp.pressure; } else { *outValue = samp.ev[numOfEventsSent].value; *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); } if(++numOfEventsSent == samp.total_events) samp.total_events = 0; return true; } #endif } }
ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes) { android::AutoMutex lock(mLock); if (!mPowerLock) { acquire_wake_lock (PARTIAL_WAKE_LOCK, "AudioOutLock"); mPowerLock = true; } acoustic_device_t *aDev = acoustics(); // For output, we will pass the data on to the acoustics module, but the actual // data is expected to be sent to the audio device directly as well. if (aDev && aDev->write) aDev->write(aDev, buffer, bytes); snd_pcm_sframes_t n; size_t sent = 0; status_t err = 0; do { if (mHandle->mmap) n = snd_pcm_mmap_writei(mHandle->handle, (char *)buffer + sent, snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent)); else n = snd_pcm_writei(mHandle->handle, (char *)buffer + sent, snd_pcm_bytes_to_frames(mHandle->handle, bytes - sent)); if (n == -EBADFD) { LOGW("badstate and do recovery....."); switch(snd_pcm_state(mHandle->handle)){ case SND_PCM_STATE_SETUP: err = snd_pcm_prepare(mHandle->handle); if(err < 0) LOGW("snd_pcm_prepare failed"); break; case SND_PCM_STATE_SUSPENDED: snd_pcm_resume(mHandle->handle); if(err < 0) LOGW("snd_pcm_resume failed"); snd_pcm_prepare(mHandle->handle); if(err < 0) LOGW("snd_pcm_prepare failed"); break; default: // Somehow the stream is in a bad state. The driver probably // has a bug and snd_pcm_recover() doesn't seem to handle this. mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); break; } if(err < 0 ) mHandle->module->open(mHandle, mHandle->curDev, mHandle->curMode); if (aDev && aDev->recover) aDev->recover(aDev, n); } else if (n < 0) { if (mHandle->handle) { LOGW("underrun and do recovery....."); // snd_pcm_recover() will return 0 if successful in recovering from // an error, or -errno if the error was unrecoverable. n = snd_pcm_recover(mHandle->handle, n, 1); if (aDev && aDev->recover) aDev->recover(aDev, n); if (n) return static_cast<ssize_t>(n); } } else { mFrameCount += n; sent += static_cast<ssize_t>(snd_pcm_frames_to_bytes(mHandle->handle, n)); } } while (mHandle->handle && sent < bytes); return sent; }
static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) { ScopedUtfChars name(env, nameStr); acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str()); }
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType, int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen) { *outDeviceId = 0; *outType = 0; *outScancode = 0; *outKeycode = 0; *outFlags = 0; *outValue = 0; *outWhen = 0; status_t err; fd_set readfds; int maxFd = -1; int cc; int i; int res; int pollres; struct input_event iev; // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; } while(1) { // First, report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_REMOVED; delete device; return true; } if (mOpeningDevices != NULL) { device_t* device = mOpeningDevices; LOGV("Reporting device opened: id=0x%x, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_ADDED; return true; } release_wake_lock(WAKE_LOCK_ID); pollres = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollres <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } continue; } //printf("poll %d, returned %d\n", mFDCount, pollres); // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] for(i = 1; i < mFDCount; i++) { if(mFDs[i].revents) { LOGV("revents for %d = 0x%08x", i, mFDs[i].revents); if(mFDs[i].revents & POLLIN) { res = read(mFDs[i].fd, &iev, sizeof(iev)); if (res == sizeof(iev)) { LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", mDevices[i]->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); *outDeviceId = mDevices[i]->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = iev.type; *outScancode = iev.code; if (iev.type == EV_KEY) { err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags); LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n", iev.code, *outKeycode, *outFlags, err); if (err != 0) { *outKeycode = 0; *outFlags = 0; } } else { *outKeycode = iev.code; } *outValue = iev.value; *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); return true; } else { if (res<0) { LOGW("could not get event (errno=%d)", errno); } else { LOGE("could not get event (wrong size: %d)", res); } continue; } } } } // read_notify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { read_notify(mFDs[0].fd); } } }
status_t LoopbackManager::SetLoopbackOn(loopback_t loopback_type, loopback_output_device_t loopback_output_device) { ALOGD("+%s(), loopback_type = %d, loopback_output_device = %d", __FUNCTION__, loopback_type, loopback_output_device); Mutex::Autolock _l(mLock); if (mLoopbackType != NO_LOOPBACK) // check no loobpack function on { ALOGD("-%s() : Please Turn off Loopback Type %d First!!", __FUNCTION__, mLoopbackType); return ALREADY_EXISTS; } else if (CheckLoopbackTypeIsValid(loopback_type) != NO_ERROR) // to avoid using undefined loopback type & ref/dual mic in single mic project { ALOGW("-%s(): No such Loopback type %d", __FUNCTION__, loopback_type); return BAD_TYPE; } // suspend & standby all input/output streams AudioALSAStreamManager::getInstance()->setAllStreamsSuspend(true); AudioALSAStreamManager::getInstance()->standbyAllStreams(); // copy current device // TODO(Harvey): recover device //mInputDeviceCopy = (audio_devices_t)pAudioResourceManager->getUlInputDevice(); //mOutputDeviceCopy = (audio_devices_t)pAudioResourceManager->getDlOutputDevice(); // get loopback device audio_devices_t input_device = GetInputDeviceByLoopbackType(loopback_type); audio_devices_t output_device = GetOutputDeviceByLoopbackType(loopback_type, loopback_output_device); // set specific mic type if (loopback_type == AP_MAIN_MIC_AFE_LOOPBACK || loopback_type == MD_MAIN_MIC_ACOUSTIC_LOOPBACK) { AudioALSAHardwareResourceManager::getInstance()->setBuiltInMicSpecificType(BUILTIN_MIC_MIC1_ONLY); } else if (loopback_type == AP_REF_MIC_AFE_LOOPBACK || loopback_type == MD_REF_MIC_ACOUSTIC_LOOPBACK) { AudioALSAHardwareResourceManager::getInstance()->setBuiltInMicSpecificType(BUILTIN_MIC_MIC2_ONLY); } else if (loopback_type == AP_3RD_MIC_AFE_LOOPBACK || loopback_type == MD_3RD_MIC_ACOUSTIC_LOOPBACK) { AudioALSAHardwareResourceManager::getInstance()->setBuiltInMicSpecificType(BUILTIN_MIC_MIC3_ONLY); } // check modem status if (CheckIsModemLoopback(loopback_type) == true) { SpeechDriverInterface *pSpeechDriver = SpeechDriverFactory::GetInstance()->GetSpeechDriverByIndex(mWorkingModemIndex); if (pSpeechDriver->CheckModemIsReady() == false) // modem is sleep... { for (int modem_index = MODEM_1; modem_index < NUM_MODEM; modem_index++) // get working modem index { pSpeechDriver = SpeechDriverFactory::GetInstance()->GetSpeechDriverByIndex((modem_index_t)modem_index); if (pSpeechDriver != NULL && pSpeechDriver->CheckModemIsReady() == true) { mWorkingModemIndex = (modem_index_t)modem_index; SpeechDriverFactory::GetInstance()->SetActiveModemIndex(mWorkingModemIndex); break; } } } } // to avoid BT test being interferenced by modem side speech enhancement mBtHeadsetNrecOnCopy = SpeechEnhancementController::GetInstance()->GetBtHeadsetNrecOn(); if (loopback_type == MD_BT_LOOPBACK || loopback_type == MD_BT_LOOPBACK_NO_CODEC) { SpeechEnhancementController::GetInstance()->SetBtHeadsetNrecOnToAllModem(false); } // to turn on/off DMNR if (loopback_type == MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITHOUT_DMNR || loopback_type == MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITH_DMNR) { mMaskCopy = SpeechEnhancementController::GetInstance()->GetSpeechEnhancementMask(); // copy DMNR mask sph_enh_mask_struct_t mask = mMaskCopy; if (loopback_type == MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITHOUT_DMNR) { mask.dynamic_func &= (~SPH_ENH_DYNAMIC_MASK_DMNR); } else if (loopback_type == MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITH_DMNR) { mask.dynamic_func |= SPH_ENH_DYNAMIC_MASK_DMNR; } SpeechDriverFactory::GetInstance()->GetSpeechDriverByIndex(mWorkingModemIndex)->SetSpeechEnhancementMask(mask); } // BT CVSD if (loopback_type == AP_BT_LOOPBACK) { AudioALSALoopbackController::getInstance()->SetApBTCodec(true); AudioALSALoopbackController::getInstance()->OpenAudioLoopbackControlFlow(input_device, output_device); } else if (loopback_type == AP_BT_LOOPBACK_NO_CODEC) { AudioALSALoopbackController::getInstance()->SetApBTCodec(false); AudioALSALoopbackController::getInstance()->OpenAudioLoopbackControlFlow(input_device, output_device); } else if (loopback_type == MD_BT_LOOPBACK) { AudioALSASpeechLoopbackController::getInstance()->SetModemBTCodec(true); AudioALSASpeechLoopbackController::getInstance()->OpenModemLoopbackControlFlow(input_device, output_device); } else if (loopback_type == MD_BT_LOOPBACK_NO_CODEC) { AudioALSASpeechLoopbackController::getInstance()->SetModemBTCodec(false); AudioALSASpeechLoopbackController::getInstance()->OpenModemLoopbackControlFlow(input_device, output_device); } else { // Enable loopback function switch (loopback_type) { case AP_MAIN_MIC_AFE_LOOPBACK: case AP_HEADSET_MIC_AFE_LOOPBACK: case AP_REF_MIC_AFE_LOOPBACK: case AP_3RD_MIC_AFE_LOOPBACK: //case AP_BT_LOOPBACK: //case AP_BT_LOOPBACK_NO_CODEC: { AudioALSALoopbackController::getInstance()->open(output_device, input_device); break; } case MD_MAIN_MIC_ACOUSTIC_LOOPBACK: case MD_HEADSET_MIC_ACOUSTIC_LOOPBACK: case MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITHOUT_DMNR: case MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITH_DMNR: case MD_REF_MIC_ACOUSTIC_LOOPBACK: case MD_3RD_MIC_ACOUSTIC_LOOPBACK: //case MD_BT_LOOPBACK: //case MD_BT_LOOPBACK_NO_CODEC: { #if defined(MTK_AUDIO_GAIN_TABLE)&&defined(MTK_AUDIO_SPH_LPBK_PARAM) AudioALSAStreamManager::getInstance()->UpdateSpeechLpbkParams(); #endif AudioALSASpeechLoopbackController::getInstance()->open(output_device, input_device); break; } default: { ALOGW("%s(): Loopback type %d not implemented!!", __FUNCTION__, loopback_type); ASSERT(0); } } } /* // only use L ch data, so mute R ch. (Disconnect ADC_I2S_IN_R -> MODEM_PCM_TX_R) if (loopback_type == MD_MAIN_MIC_ACOUSTIC_LOOPBACK || loopback_type == MD_REF_MIC_ACOUSTIC_LOOPBACK) { AudioDigitalControlFactory::CreateAudioDigitalControl()->SetinputConnection( AudioDigitalType::DisConnect, AudioDigitalType::I04, (mWorkingModemIndex == MODEM_1) ? AudioDigitalType::O18 : AudioDigitalType::O08); } */ // save opened loobpack type mLoopbackType = loopback_type; // acquire wake lock int ret = acquire_wake_lock(PARTIAL_WAKE_LOCK, LOOPBACK_WAKELOCK_NAME); ALOGD("%s(), acquire_wake_lock:%s, return %d.", __FUNCTION__, LOOPBACK_WAKELOCK_NAME, ret); // Volume if ((loopback_type != AP_BT_LOOPBACK) && (loopback_type != AP_BT_LOOPBACK_NO_CODEC) && (loopback_type != MD_BT_LOOPBACK) && (loopback_type != MD_BT_LOOPBACK_NO_CODEC)) { if (CheckIsModemLoopback(loopback_type) == true) { mVoiceVolumeCopy = mAudioALSAVolumeController->getVoiceVolume(); mAudioALSAVolumeController->setVoiceVolume(kVoiceVolumeForLoopback, AUDIO_MODE_IN_CALL, output_device); } else { mMasterVolumeCopy = mAudioALSAVolumeController->getMasterVolume(); mAudioALSAVolumeController->setMasterVolume(kMasterVolumeForLoopback, AUDIO_MODE_NORMAL, output_device); } } ALOGD("-%s(), loopback_type = %d, loopback_output_device = %d", __FUNCTION__, loopback_type, loopback_output_device); return NO_ERROR; }
static int acquire_wake_lock_cb(const char* lock_name) { acquire_wake_lock(PARTIAL_WAKE_LOCK, lock_name); return BT_STATUS_SUCCESS; };
/* * Arguments: * argv[2] - wlan interface * argv[3] - softap interface * argv[4] - SSID * argv[5] - Security * argv[6] - Key * argv[7] - Channel * argv[8] - Preamble * argv[9] - Max SCB */ int SoftapController::setSoftap(int argc, char *argv[]) { int ret = 0; char buf[1024]; int sta_chan, is_g_mode; LOGD("%s - %s - %s - %s - %s - %s",argv[2],argv[3],argv[4],argv[5],argv[6],argv[7]); if (argc < 4) { LOGE("Softap set - missing arguments"); return -1; } FILE* fp = fopen(HOSTAPD_CONF_TEMPLATE_FILE, "r"); if (!fp) { LOGE("Softap set - hostapd template file read failed"); return -1; } FILE* fp2 = fopen(HOSTAPD_CONF_FILE, "w"); if (!fp2) { LOGE("Softap set - hostapd.conf file read failed"); fclose(fp); return -1; } while (fgets(buf, sizeof(buf), fp)) { if((strncmp(buf, "ssid=",5) == 0) || (strncmp(buf, "wpa=",4) == 0) || (strncmp(buf, "wpa_passphrase=",15) == 0) || (strncmp(buf, "wpa_key_mgmt=",12) == 0) || (strncmp(buf, "wpa_pairwise=",12) == 0) || (strncmp(buf, "rsn_pairwise=",12) == 0) || (strncmp(buf, "interface=",10) == 0)) { continue; } fputs(buf,fp2); } // Update interface sprintf(buf, "interface=%s\n", AP_INTERFACE); fputs(buf, fp2); // Update SSID sprintf(buf, "ssid=%s\n",argv[4]); fputs(buf, fp2); // Update security if(strncmp(argv[5],"wpa2-psk",8) == 0) { sprintf(buf, "wpa=2\nwpa_passphrase=%s\nwpa_key_mgmt=WPA-PSK\n" "wpa_pairwise=CCMP\nrsn_pairwise=CCMP\n", argv[6]); fputs(buf, fp2); } if(strncmp(argv[5],"wpa-psk",7) == 0) { sprintf(buf, "wpa=1\nwpa_passphrase=%s\nwpa_key_mgmt=WPA-PSK\n" "wpa_pairwise=TKIP\nrsn_pairwise=TKIP\n", argv[6]); fputs(buf, fp2); } // Choose the correct channel - based on the current channel of the STA if (getStaChanAndMode(&sta_chan, &is_g_mode) != 0 || sta_chan == 0) { /* default to channel 11 on G */ sta_chan = 11; is_g_mode = 1; } LOGD("AP starting on channel %d g_mode: %d", sta_chan, is_g_mode); sprintf(buf, "hw_mode=%s\nchannel=%d\n", is_g_mode ? "g" : "a", sta_chan); fputs(buf, fp2); fclose(fp); fclose(fp2); // we take the wakelock here because the stop/start is lengthy acquire_wake_lock(PARTIAL_WAKE_LOCK, AP_WAKE_LOCK); // switch interface to wlan1 ret = switchInterface(true); if (ret != 0) goto fail_switch; // restart hostapd to update configuration ret = stopHostapd(); if (ret != 0) goto fail; ret = startHostapd(); if (ret != 0) goto fail; LOGD("hostapd set - Ok"); return 0; fail: switchInterface(false); fail_switch: release_wake_lock(AP_WAKE_LOCK); LOGD("hostapd set - failed. AP is off."); return ret; }
bool EventHub::getEvent(RawEvent* outEvent) { outEvent->deviceId = 0; outEvent->type = 0; outEvent->scanCode = 0; outEvent->keyCode = 0; outEvent->flags = 0; outEvent->value = 0; outEvent->when = 0; // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; mNeedToSendFinishedDeviceScan = true; } for (;;) { // Report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = DEVICE_REMOVED; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); delete device; mNeedToSendFinishedDeviceScan = true; return true; } if (mOpeningDevices != NULL) { device_t* device = mOpeningDevices; LOGV("Reporting device opened: id=0x%x, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = DEVICE_ADDED; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); mNeedToSendFinishedDeviceScan = true; return true; } if (mNeedToSendFinishedDeviceScan) { mNeedToSendFinishedDeviceScan = false; outEvent->type = FINISHED_DEVICE_SCAN; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); return true; } // Grab the next input event. for (;;) { // Consume buffered input events, if any. if (mInputBufferIndex < mInputBufferCount) { const struct input_event& iev = mInputBufferData[mInputBufferIndex++]; const device_t* device = mDevices[mInputDeviceIndex]; LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = iev.type; outEvent->scanCode = iev.code; if (iev.type == EV_KEY) { status_t err = device->layoutMap->map(iev.code, & outEvent->keyCode, & outEvent->flags); LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n", iev.code, outEvent->keyCode, outEvent->flags, err); if (err != 0) { outEvent->keyCode = AKEYCODE_UNKNOWN; outEvent->flags = 0; } } else { outEvent->keyCode = iev.code; } outEvent->value = iev.value; // Use an event timestamp in the same timebase as // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis() // as expected by the rest of the system. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); return true; } // Finish reading all events from devices identified in previous poll(). // This code assumes that mInputDeviceIndex is initially 0 and that the // revents member of pollfd is initialized to 0 when the device is first added. // Since mFDs[0] is used for inotify, we process regular events starting at index 1. mInputDeviceIndex += 1; if (mInputDeviceIndex >= mFDCount) { break; } const struct pollfd& pfd = mFDs[mInputDeviceIndex]; if (pfd.revents & POLLIN) { int32_t readSize = read(pfd.fd, mInputBufferData, sizeof(struct input_event) * INPUT_BUFFER_SIZE); if (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { LOGW("could not get event (errno=%d)", errno); } } else if ((readSize % sizeof(struct input_event)) != 0) { LOGE("could not get event (wrong size: %d)", readSize); } else { mInputBufferCount = readSize / sizeof(struct input_event); mInputBufferIndex = 0; } } } #if HAVE_INOTIFY // readNotify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { readNotify(mFDs[0].fd); mFDs[0].revents = 0; continue; // report added or removed devices immediately } #endif mInputDeviceIndex = 0; // Poll for events. Mind the wake lock dance! // We hold a wake lock at all times except during poll(). This works due to some // subtle choreography. When a device driver has pending (unread) events, it acquires // a kernel wake lock. However, once the last pending event has been read, the device // driver will release the kernel wake lock. To prevent the system from going to sleep // when this happens, the EventHub holds onto its own user wake lock while the client // is processing events. Thus the system can only sleep if there are no events // pending or currently being processed. release_wake_lock(WAKE_LOCK_ID); int pollResult = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollResult <= 0) { if (errno != EINTR) { LOGW("poll failed (errno=%d)\n", errno); usleep(100000); } } } }
/* * Arguments: * argv[2] - wlan interface * argv[3] - SSID * argv[4] - Broadcast/Hidden * argv[5] - Channel * argv[6] - Security * argv[7] - Key */ int SoftapController::setSoftap(int argc, char *argv[]) { int ret = 0; char buf[1024]; int channel = AP_CHANNEL_DEFAULT; ALOGD("%s - %s - %s - %s - %s - %s",argv[2],argv[3],argv[4],argv[5],argv[6],argv[7]); if (argc < 4) { ALOGE("Softap set - missing arguments"); return -1; } FILE* fp = fopen(HOSTAPD_CONF_TEMPLATE_FILE, "r"); if (!fp) { ALOGE("Softap set - hostapd template file read failed"); return -1; } FILE* fp2 = fopen(HOSTAPD_CONF_FILE, "w"); if (!fp2) { ALOGE("Softap set - hostapd.conf file read failed"); fclose(fp); return -1; } while (fgets(buf, sizeof(buf), fp)) { if((strncmp(buf, "ssid=",5) == 0) || (strncmp(buf, "wpa=",4) == 0) || (strncmp(buf, "wpa_passphrase=",15) == 0) || (strncmp(buf, "wpa_key_mgmt=",12) == 0) || (strncmp(buf, "wpa_pairwise=",12) == 0) || (strncmp(buf, "rsn_pairwise=",12) == 0) || (strncmp(buf, "interface=",10) == 0)) { continue; } fputs(buf,fp2); } // Update interface sprintf(buf, "interface=%s\n", AP_INTERFACE); fputs(buf, fp2); // Update interface path sprintf(buf, "ctrl_interface=%s\n", AP_INTERFACE_PATH); fputs(buf, fp2); // Update SSID sprintf(buf, "ssid=%s\n",argv[3]); fputs(buf, fp2); // Update Channel if (argc >= 5) { channel = atoi(argv[5]); if (channel <= 0) { channel = AP_CHANNEL_DEFAULT; } sprintf(buf, "channel=%d\n",channel); } // Update security if (argc > 7) { if(strncmp(argv[6],"wpa2-psk",8) == 0) { sprintf(buf, "wpa=2\nwpa_passphrase=%s\nwpa_key_mgmt=WPA-PSK\n" "wpa_pairwise=CCMP\nrsn_pairwise=CCMP\n", argv[7]); fputs(buf, fp2); } if(strncmp(argv[6],"wpa-psk",7) == 0) { sprintf(buf, "wpa=1\nwpa_passphrase=%s\nwpa_key_mgmt=WPA-PSK\n" "wpa_pairwise=TKIP\nrsn_pairwise=TKIP\n", argv[7]); fputs(buf, fp2); } } fclose(fp); fclose(fp2); if (chmod(HOSTAPD_CONF_FILE, 0660) < 0) { ALOGE("Error changing permissions of %s to 0660: %s", HOSTAPD_CONF_FILE, strerror(errno)); unlink(HOSTAPD_CONF_FILE); return -1; } if (chown(HOSTAPD_CONF_FILE, AID_SYSTEM, AID_WIFI) < 0) { ALOGE("Error changing group ownership of %s to %d: %s", HOSTAPD_CONF_FILE, AID_WIFI, strerror(errno)); unlink(HOSTAPD_CONF_FILE); return -1; } // we take the wakelock here because the stop/start is lengthy acquire_wake_lock(PARTIAL_WAKE_LOCK, AP_WAKE_LOCK); // restart hostapd to update configuration ret = stopHostapd(); if (ret != 0) goto fail_switch; ret = startHostapd(); if (ret != 0) goto fail_switch; ALOGD("hostapd set - Ok"); return 0; fail_switch: release_wake_lock(AP_WAKE_LOCK); ALOGD("hostapd set - failed. AP is off."); return ret; }
bool AudioYusuStreamIn::RecOpen() { bool ret = true; m_no_data_count = 0; ALOGD("+RecOpen, mSampleRateModem:%d mSampleRate = %d",mSampleRateModem,mSampleRate); // this will set Mic gain base on current routing if(mSetSphEnh && mHw->SetMicGain(mInputSource) == false){ ALOGD("RecOpen SetMicGain -- IN_CALL MODE"); } if(mSetSphEnh == false){ // VOICE_RECOGNITION, must disable sph enhancement // Remember to turn on again if we turn off it. int Device= mHw->Audio_Match_Input_device(mDevice,true); // turn on this deivce ALOGD("+RecOpen, mSetSphEnh=false mDevice = %x",Device); if(Device == android_audio_legacy::AudioSystem::DEVICE_IN_WIRED_HEADSET){ mHw->mVolumeController->SetLadMicGain(Voice_Rec_Mic_Headset); } else{ mHw->mVolumeController->SetLadMicGain(Voice_Rec_Mic_Handset); } //pLad->LAD_Set_Speech_Enhancement(mSetSphEnh); pLad->LAD_SetSpeechMode((ENUM_Speech_Mode)SPH_MODE_BT_CORDLESS); pLad->LAD_SetInputSource (LADIN_Microphone1); pLad->LAD_SetOutputDevice (LADOUT_SPEAKER2); } //Get Wake Lock for phone call recording acquire_wake_lock(PARTIAL_WAKE_LOCK, MD_RECORD_WAKELOCK_NAME); //Set Modem Sampling rate int32 mode; mHw->getMode(&mode); if ( mode == android_audio_legacy::AudioSystem::MODE_IN_CALL ) { mSampleRateModem = pLad->LAD_RecordSR()/*8000*/; } else if ( mSampleRate <= 8000 ) { mSampleRateModem = 8000; } else { mSampleRateModem = 16000; } //Modem Sampling rate convert to index int32 srIdx; if ( mSampleRateModem == 8000 ) srIdx = Record_8k; else if ( mSampleRateModem == 16000 ) srIdx = Record_16k; else { YAD_LOGE("RecOpen modem SR error, use 8k Hz \n"); srIdx = Record_8k; } // call this function to decide set whick mode to modem. bool bStereoRecOn = false; SetHdrecordingMode(mode,&bStereoRecOn); // get real ch num for BLI uint8 mRealChNum; #if defined(MTK_AUDIO_HD_REC_SUPPORT) if ((mHw->GetVmFlag() == true && mode == android_audio_legacy::AudioSystem::MODE_IN_CALL ) || (mHw->META_Get_DualMic_Test_Mode()==TRUE) || (mHw->GetCtm4WayFlag() == true && mode == android_audio_legacy::AudioSystem::MODE_IN_CALL ) || (mode == android_audio_legacy::AudioSystem::MODE_IN_CALL)){ mRealChNum = 1; } else { mRealChNum = (bStereoRecOn == true) ? 2 : 1; ALOGD(" mRealChNum = %d bStereoRecOn = %d",mRealChNum,bStereoRecOn); } #else mRealChNum = 1; #endif ALOGD("RecOpen Sampling Rate : %d, Modem Sample Rate : %d \n", mSampleRate, mSampleRateModem); //If modem sampling rate different from sampling rate, SRC required if ( (mSampleRateModem != mSampleRate) || mChNum != 1 && mFormat != android_audio_legacy::AudioSystem::VM_FMT ) { ALOGD("mSampleRateModem=%d, mRealChNum=%d, mSampleRate=%d need src pSrcHdl = %p mChNum = %d", mSampleRateModem,mRealChNum,mSampleRate,pSrcHdl,mChNum); uint32 srcBufLen; if(pSrcHdl == NULL){ BLI_GetMemSize( mSampleRateModem, mRealChNum, mSampleRate, mChNum, &srcBufLen); pSrcBuf = new int8[srcBufLen]; pSrcHdl = BLI_Open( mSampleRateModem, mRealChNum, mSampleRate, mChNum, pSrcBuf); } else{ ALOGD("pSrcHdl exit = %p",pSrcHdl); } if ( !pSrcHdl ) return false; } // Add delay 10ms for Recording. Because record process is on-off-on (very quickly. about 2~8 tick counts), // modem side DSP has control flow problem. The recorded sound is bad. // So just add delay to work around this issue. // Modem side will also find out the root cause. If modem side fix this issue, remove this work around. usleep(10*1000); if( true == CanRecordFM(mode) ) { pLad->LAD_SetInputSource(LADIN_FM_Radio); ALOGD("RecOpen, LAD_SetInputSource, LADIN_FM_Radio"); } else { // pLad->LAD_SetInputSource(LADIN_Microphone1); // ALOGD("RecOpen, LAD_SetInputSource, LADIN_Microphone1"); } //reset read and write pointer of internal buffer inBuf.pRead = inBuf.pBufBase; inBuf.pWrite = inBuf.pBufBase; ALOGD("SetRecDropFrameCount(%d)", m_DropFrameCount); pLad->LAD_SetRecDropFrameCount(m_DropFrameCount); //Start recording if ( mHw->GetVmFlag() == true && mode == android_audio_legacy::AudioSystem::MODE_IN_CALL ){ ret &= pLad->LAD_OpenNormalRecPath(LADDATA_VM, 0); ALOGD("-RecOpen, LADDATA_VM"); } #if defined(MTK_DUAL_MIC_SUPPORT)||defined(MTK_AUDIO_HD_REC_SUPPORT) else if(mHw->META_Get_DualMic_Test_Mode()==TRUE){ pLad->LAD_SetInputSource(LADIN_DualAnalogMic); // set rec level uint32 ladLevel = 0xffffff - (MAX_MIC_GAIN_DB - mHw->mDualMicTool_micGain) * 2; // in 0.5dB ALOGD("set dual mic rec level level Rec: 0x%x, ladlevel: 0x%x",mHw->mDualMicTool_micGain,ladLevel); pLad->LAD_SetMicrophoneVolume(ladLevel); // start record ret &= pLad->LAD_OpenNormalRecPath(LADDATA_DUAL_MIC_VM, 0); ALOGD("-RecOpen, LADDATA_DUAL_MIC"); } #endif else if ( mHw->GetCtm4WayFlag() == true && mode == android_audio_legacy::AudioSystem::MODE_IN_CALL ){ ret &= pLad->LAD_OpenNormalRecPath(LADDATA_CTM_4WAY, 0); ALOGD("-RecOpen, LADDATA_CTM_4WAY"); } #if !defined(MTK_AUDIO_HD_REC_SUPPORT) else{ ret &= pLad->LAD_OpenNormalRecPath(LADDATA_PCM, srIdx); } #else //MTK_AUDIO_HD_REC_SUPPORT = yes else if ( mode == android_audio_legacy::AudioSystem::MODE_IN_CALL ){
static void acquire_wakelock_callback() { FUN_ENTER; acquire_wake_lock(PARTIAL_WAKE_LOCK, GPSNATIVETEST_WAKE_LOCK_NAME); FUN_EXIT; }
static void acquire_wakelock_callback() { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); }
status_t LoopbackManager::SetLoopbackOn(loopback_t loopback_type, loopback_output_device_t loopback_output_device) { Mutex::Autolock _l(mLock); ALOGD("+%s(), loopback_type = %d, loopback_output_device = %d", __FUNCTION__, loopback_type, loopback_output_device); if (mLoopbackType != NO_LOOPBACK) { // check no loobpack function on ALOGD("-%s() : Please Turn off Loopback Type %d First!!", __FUNCTION__, mLoopbackType); return ALREADY_EXISTS; } else if (CheckLoopbackTypeIsValid(loopback_type) != NO_ERROR) { // to avoid using undefined loopback type & ref/dual mic in single mic project ALOGW("-%s(): No such Loopback type %d", __FUNCTION__, loopback_type); return BAD_TYPE; } // lock AudioResourceManagerInterface *pAudioResourceManager = AudioResourceManagerFactory::CreateAudioResource(); pAudioResourceManager->EnableAudioLock(AudioResourceManagerInterface::AUDIO_HARDWARE_LOCK, 3000); pAudioResourceManager->EnableAudioLock(AudioResourceManagerInterface::AUDIO_MODE_LOCK, 3000); pAudioResourceManager->EnableAudioLock(AudioResourceManagerInterface::AUDIO_VOLUME_LOCK, 3000); // force all input/output streams standby AudioMTKStreamManager::getInstance()->ForceAllStandby(); // copy current device mInputDeviceCopy = (audio_devices_t)pAudioResourceManager->getUlInputDevice(); mOutputDeviceCopy = (audio_devices_t)pAudioResourceManager->getDlOutputDevice(); // get loopback device audio_devices_t input_device = GetInputDeviceByLoopbackType(loopback_type); audio_devices_t output_device = GetOutputDeviceByLoopbackType(loopback_type, loopback_output_device); // check modem status SpeechDriverInterface *pSpeechDriver = SpeechDriverFactory::GetInstance()->GetSpeechDriverByIndex(mWorkingModemIndex); if (pSpeechDriver->CheckModemIsReady() == false) { // modem is sleep... for (int modem_index = MODEM_1; modem_index < NUM_MODEM; modem_index++) { // get working modem index pSpeechDriver = SpeechDriverFactory::GetInstance()->GetSpeechDriverByIndex((modem_index_t)modem_index); if (pSpeechDriver != NULL && pSpeechDriver->CheckModemIsReady() == true) { mWorkingModemIndex = (modem_index_t)modem_index; break; } } } // to avoid BT test being interferenced by modem side speech enhancement if (loopback_type == MD_BT_LOOPBACK) { SpeechDriverFactory::GetInstance()->GetSpeechDriverByIndex(mWorkingModemIndex)->SetSpeechEnhancement(false); } // to turn on/off DMNR if (loopback_type == MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITHOUT_DMNR || loopback_type == MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITH_DMNR) { mMaskCopy = SpeechEnhancementController::GetInstance()->GetSpeechEnhancementMask(); // copy DMNR mask sph_enh_mask_struct_t mask = mMaskCopy; if (loopback_type == MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITHOUT_DMNR) { mask.dynamic_func &= (~SPH_ENH_DYNAMIC_MASK_DMNR); } else if (loopback_type == MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITH_DMNR) { mask.dynamic_func |= SPH_ENH_DYNAMIC_MASK_DMNR; } SpeechDriverFactory::GetInstance()->GetSpeechDriverByIndex(mWorkingModemIndex)->SetSpeechEnhancementMask(mask); } // Enable loopback function switch (loopback_type) { case AP_MAIN_MIC_AFE_LOOPBACK: case AP_HEADSET_MIC_AFE_LOOPBACK: case AP_REF_MIC_AFE_LOOPBACK: case AP_BT_LOOPBACK: { AudioLoopbackController::GetInstance()->OpenAudioLoopbackControlFlow(input_device, output_device); break; } case MD_MAIN_MIC_ACOUSTIC_LOOPBACK: case MD_HEADSET_MIC_ACOUSTIC_LOOPBACK: case MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITHOUT_DMNR: case MD_DUAL_MIC_ACOUSTIC_LOOPBACK_WITH_DMNR: case MD_REF_MIC_ACOUSTIC_LOOPBACK: case MD_BT_LOOPBACK: { SpeechLoopbackController::GetInstance()->OpenModemLoopbackControlFlow(mWorkingModemIndex, input_device, output_device); break; } default: { ALOGW("%s(): Loopback type %d not implemented!!", __FUNCTION__, loopback_type); ASSERT(0); } } // only use L ch data, so mute R ch. (Disconnect ADC_I2S_IN_R -> MODEM_PCM_TX_R) if (loopback_type == MD_MAIN_MIC_ACOUSTIC_LOOPBACK || loopback_type == MD_REF_MIC_ACOUSTIC_LOOPBACK) { AudioDigitalControlFactory::CreateAudioDigitalControl()->SetinputConnection( AudioDigitalType::DisConnect, AudioDigitalType::I04, (mWorkingModemIndex == MODEM_1) ? AudioDigitalType::O18 : AudioDigitalType::O08); } // save opened loobpack type mLoopbackType = loopback_type; // acquire wake lock int ret = acquire_wake_lock(PARTIAL_WAKE_LOCK, LOOPBACK_WAKELOCK_NAME); ALOGD("%s(), acquire_wake_lock:%s, return %d.", __FUNCTION__, LOOPBACK_WAKELOCK_NAME, ret); // unlock pAudioResourceManager->DisableAudioLock(AudioResourceManagerInterface::AUDIO_VOLUME_LOCK); pAudioResourceManager->DisableAudioLock(AudioResourceManagerInterface::AUDIO_MODE_LOCK); pAudioResourceManager->DisableAudioLock(AudioResourceManagerInterface::AUDIO_HARDWARE_LOCK); ALOGD("-%s(), loopback_type = %d, loopback_output_device = %d", __FUNCTION__, loopback_type, loopback_output_device); return NO_ERROR; }
static void AcquireWakelock() { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); }
static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, size_t bytes) { struct astream_out *out = (struct astream_out *)stream; int ret; size_t frames_total = bytes / sizeof(uint32_t); // always stereo 16 bit uint32_t *buf = (uint32_t *)buffer; size_t frames_written = 0; pthread_mutex_lock(&out->buf_lock); pthread_mutex_lock(&out->lock); if (!out->bt_enabled || out->suspended) { LOGV("a2dp write: bluetooth disabled bt_en %d, suspended %d", out->bt_enabled, out->suspended); ret = -1; goto err_bt_disabled; } if (out->standby) { acquire_wake_lock(PARTIAL_WAKE_LOCK, A2DP_WAKE_LOCK_NAME); out->standby = false; out->last_write_time = system_time(); out->buf_rd_idx = 0; out->buf_wr_idx = 0; out->buf_frames_ready = 0; } ret = _out_init_locked(out, NULL); if (ret < 0) { goto err_init; } pthread_mutex_unlock(&out->lock); if(isToMono){ int16_t mono; int16_t *stereoData = (int16_t *)buffer; uint16_t i; for(i = 0; i<bytes/4; i++) { // to Mono mono = (int16_t)(((int32_t)*(stereoData+2*i) + (int32_t)*(stereoData+2*i+1)) >> 1); // to Stereo again *(stereoData+2*i) = *(stereoData+2*i+1) = mono; } } while (frames_written < frames_total) { size_t frames = _out_frames_available_locked(out); if (frames == 0) { int ret = pthread_cond_timeout_np(&out->buf_cond, &out->buf_lock, BUF_WRITE_AVAILABILITY_TIMEOUT_MS); if (ret != 0) { pthread_mutex_lock(&out->lock); goto err_write; } frames = _out_frames_available_locked(out); } if (frames > frames_total - frames_written) { frames = frames_total - frames_written; } memcpy(out->buf + out->buf_wr_idx, buf + frames_written, frames * sizeof(uint32_t)); frames_written += frames; _out_inc_wr_idx_locked(out, frames); pthread_mutex_lock(&out->lock); if (out->standby) { goto err_write; } pthread_mutex_unlock(&out->lock); } pthread_mutex_unlock(&out->buf_lock); return bytes; /* out->lock must be locked and out->buf_lock unlocked when jumping here */ err_write: err_init: err_bt_disabled: pthread_mutex_unlock(&out->buf_lock); LOGV("!!!! write error"); out_standby_stream_locked(out); pthread_mutex_unlock(&out->lock); /* XXX: simulate audio output timing in case of error?!?! */ usleep(out->buffer_duration_us); return ret; }