You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
5.2 KiB
161 lines
5.2 KiB
/*
|
|
* Copyright (C) 2019 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.
|
|
*/
|
|
|
|
//#define LOG_NDEBUG 0
|
|
#define LOG_TAG "ECOService"
|
|
|
|
#include "eco/ECOService.h"
|
|
|
|
#include <binder/BinderService.h>
|
|
#include <cutils/atomic.h>
|
|
#include <inttypes.h>
|
|
#include <pthread.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <algorithm>
|
|
#include <climits>
|
|
#include <cstring>
|
|
#include <ctime>
|
|
#include <string>
|
|
|
|
#include "eco/ECODebug.h"
|
|
|
|
namespace android {
|
|
namespace media {
|
|
namespace eco {
|
|
|
|
ECOService::ECOService() : BnECOService() {
|
|
ALOGD("ECOService created");
|
|
updateLogLevel();
|
|
}
|
|
|
|
/*virtual*/ ::android::binder::Status ECOService::obtainSession(
|
|
int32_t width, int32_t height, bool isCameraRecording,
|
|
::android::sp<::android::media::eco::IECOSession>* _aidl_return) {
|
|
ECOLOGI("ECOService::obtainSession w: %d, h: %d, isCameraRecording: %d", width, height,
|
|
isCameraRecording);
|
|
|
|
bool disable = property_get_bool(kDisableEcoServiceProperty, false);
|
|
if (disable) {
|
|
ECOLOGE("ECOService:: Failed to obtainSession as ECOService is disable");
|
|
return STATUS_ERROR(ERROR_UNSUPPORTED, "ECOService is disable");
|
|
}
|
|
|
|
if (width <= 0) {
|
|
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Width can not be <= 0");
|
|
}
|
|
|
|
if (height <= 0) {
|
|
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Height can not be <= 0");
|
|
}
|
|
|
|
SessionConfig newCfg(width, height, isCameraRecording);
|
|
|
|
ECOLOGD("session count before is %zu", mSessionConfigToSessionMap.size());
|
|
|
|
Mutex::Autolock lock(mServiceLock);
|
|
bool foundSession = false;
|
|
// Instead of looking up the map directly, take the chance to scan the map and evict all the
|
|
// invalid sessions.
|
|
SanitizeSession([&](MapIterType iter) {
|
|
if (iter->first == newCfg) {
|
|
sp<ECOSession> session = iter->second.promote();
|
|
foundSession = true;
|
|
*_aidl_return = session;
|
|
}
|
|
});
|
|
|
|
if (foundSession) {
|
|
return binder::Status::ok();
|
|
}
|
|
|
|
// Create a new session and add it to the record.
|
|
sp<ECOSession> newSession = ECOSession::createECOSession(width, height, isCameraRecording);
|
|
if (newSession == nullptr) {
|
|
ECOLOGE("ECOService failed to create ECOSession w: %d, h: %d, isCameraRecording: %d", width,
|
|
height, isCameraRecording);
|
|
return STATUS_ERROR(ERROR_UNSUPPORTED, "Failed to create eco session");
|
|
}
|
|
*_aidl_return = newSession;
|
|
// Insert the new session into the map.
|
|
mSessionConfigToSessionMap[newCfg] = newSession;
|
|
ECOLOGD("session count after is %zu", mSessionConfigToSessionMap.size());
|
|
|
|
return binder::Status::ok();
|
|
}
|
|
|
|
/*virtual*/ ::android::binder::Status ECOService::getNumOfSessions(int32_t* _aidl_return) {
|
|
Mutex::Autolock lock(mServiceLock);
|
|
SanitizeSession(std::function<void(MapIterType it)>()); // empty callback
|
|
*_aidl_return = mSessionConfigToSessionMap.size();
|
|
return binder::Status::ok();
|
|
}
|
|
|
|
/*virtual*/ ::android::binder::Status ECOService::getSessions(
|
|
::std::vector<::android::sp<::android::IBinder>>* _aidl_return) {
|
|
// Clear all the entries in the vector.
|
|
_aidl_return->clear();
|
|
|
|
Mutex::Autolock lock(mServiceLock);
|
|
SanitizeSession([&](MapIterType iter) {
|
|
sp<ECOSession> session = iter->second.promote();
|
|
_aidl_return->push_back(IInterface::asBinder(session));
|
|
});
|
|
return binder::Status::ok();
|
|
}
|
|
|
|
inline bool isEmptySession(const android::wp<ECOSession>& entry) {
|
|
sp<ECOSession> session = entry.promote();
|
|
return session == nullptr;
|
|
}
|
|
|
|
void ECOService::SanitizeSession(
|
|
const std::function<void(std::unordered_map<SessionConfig, wp<ECOSession>,
|
|
SessionConfigHash>::iterator it)>& callback) {
|
|
for (auto it = mSessionConfigToSessionMap.begin(), end = mSessionConfigToSessionMap.end();
|
|
it != end;) {
|
|
if (isEmptySession(it->second)) {
|
|
it = mSessionConfigToSessionMap.erase(it);
|
|
} else {
|
|
if (callback != nullptr) {
|
|
callback(it);
|
|
};
|
|
it++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*virtual*/ void ECOService::binderDied(const wp<IBinder>& /*who*/) {}
|
|
|
|
status_t ECOService::dump(int fd, const Vector<String16>& args) {
|
|
Mutex::Autolock lock(mServiceLock);
|
|
dprintf(fd, "\n== ECO Service info: ==\n\n");
|
|
dprintf(fd, "Number of ECOServices: %zu\n", mSessionConfigToSessionMap.size());
|
|
for (auto it = mSessionConfigToSessionMap.begin(), end = mSessionConfigToSessionMap.end();
|
|
it != end; it++) {
|
|
sp<ECOSession> session = it->second.promote();
|
|
if (session != nullptr) {
|
|
session->dump(fd, args);
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
} // namespace eco
|
|
} // namespace media
|
|
} // namespace android
|