最近对Android的Camera的模块来了兴趣,觉得有必要梳理一下,当然,我也是刚刚梳理,以下写的若是有所不对的地方,也请大佬们多多指点。
先抛出一张谷歌官方的架构图:

相关模块的代码位置,以及编译方式(这一步可忽略),输出路径是基于x86平台模拟器,具体按照实际平台自行对应
//app层
编译apk:mmm packages/apps/Camera2/
输出路径:/out/target/product/generic_x86/system/product/app/Camera2/Camera2.apk
//fwk Java层
/java/android/hardware/camera2/这个是整编出一个framework.jar
编译fwk base(java):mmm frameworks/base/
输出路径:/out/target/product/generic_x86/system/framework/framework.jar
//fwk cameraservice
编译fwk av(C++):mmm frameworks/av/services/camera/libcameraservice/
输出路径:/out/target/product/generic_x86/system/lib/libcameraservice.so
//hal层
编译hal层:mmm hardware/interfaces/camera/
输出路径:/out/target/product/generic_x86/vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so
一、APP层
从Camera2的入口开始着手,然后一步一步的往下走,CameraActivity.java这个activity作为入口,其基类是QuickActivity.java
CameraActivity.java,这个onCreateTasks是重写基类中的方法,等同于onCreate方法
public void onCreateTasks(Bundle state) {
try {
mCameraController = new CameraController(mAppContext, this, mMainHandler,
CameraAgentFactory.getAndroidCameraAgent(mAppContext,
CameraAgentFactory.CameraApi.API_1),
CameraAgentFactory.getAndroidCameraAgent(mAppContext,
CameraAgentFactory.CameraApi.AUTO),
mActiveCameraDeviceTracker);
mCameraController.setCameraExceptionHandler(
new CameraExceptionHandler(mCameraExceptionCallback, mMainHandler));
} catch (AssertionError e) {
Log.e(TAG, "Creating camera controller failed.", e);
mFatalErrorHandler.onGenericCameraAccessFailure();
}
// TODO: Try to move all the resources allocation to happen as soon as
// possible so we can call module.init() at the earliest time.
mModuleManager = new ModuleManagerImpl();
}
private void resume() {
...
mCurrentModule.resume();
...
}
进入CaptureModule.java,我们只关注打开流程,先不管预览流程,后续继续分析
//在CameraActivity中调用到了CameraModule.java中init的方法,通过CameraActivity中的resume调用到了CaptureModule中的resume方法
当onSurfaceTextureAvailable可用的时候就开始打开摄像头
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.d(TAG, "onSurfaceTextureAvailable");
// Force to re-apply transform matrix here as a workaround for
// b/11168275
updatePreviewTransform(width, height, true);
synchronized (mSurfaceTextureLock) {
mPreviewSurfaceTexture = surface;
}
reopenCamera();
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.d(TAG, "onSurfaceTextureDestroyed");
synchronized (mSurfaceTextureLock) {
mPreviewSurfaceTexture = null;
}
closeCamera();
return true;
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
Log.d(TAG, "onSurfaceTextureSizeChanged");
updatePreviewBufferSize();
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
if (mState == ModuleState.UPDATE_TRANSFORM_ON_NEXT_SURFACE_TEXTURE_UPDATE) {
Log.d(TAG, "onSurfaceTextureUpdated --> updatePreviewTransform");
mState = ModuleState.IDLE;
CameraAppUI appUI = mAppController.getCameraAppUI();
updatePreviewTransform(appUI.getSurfaceWidth(), appUI.getSurfaceHeight(), true);
}
}
};
//reopenCamera调用了openCameraAndStartPreview()
private void reopenCamera() {
...
openCameraAndStartPreview();
...
}
/**
* Open camera and start the preview.
*/
private void openCameraAndStartPreview() {
mOneCameraOpener.open(cameraId, captureSetting, mCameraHandler, mainThread,
imageRotationCalculator, mBurstController, mSoundPlayer,
new OpenCallback() {
...
@Override
public void onCameraOpened(@Nonnull final OneCamera camera) {
Log.d(TAG, "onCameraOpened: " + camera);
//如果打开成功,就开始调用预览的接口
mCamera = camera;
...
}
}, mAppController.getFatalErrorHandler());
}
Camera2OneCameraOpenerImpl.java(上面CaptureModule中的mOneCameraOpener就是接下来分析的对象),顺着代码接着往下看
上面CaptureModule中的mOneCameraOpener调用的open就是调用到了这里的open
@Override
public void open(
...) {
try {
Log.i(TAG, "Opening Camera: " + cameraKey);
...
//这里的CameraManager就是调用到了fkw层的camera,源码路径在上面有
mCameraManager.openCamera(cameraKey.getValue(), new CameraDevice.StateCallback() {
//打开均会有callback回调
}
...
}
}
上面就是APP层,其实看着他代码挺多,自己写个Demo的话流程很简单,最终就是通过CameraManager的接口打开摄像头,后续预览、拍照、录制视频等全部是依赖相机打开的前提,上述的TextureView主要是用来预览的窗口,下面我们通过CameraManager这条线进入framework层;
FWK层
通过上面的CameraManager正式调用到了fwk层,这其实是通过framework.jar进行调用的,这个没有什么疑问,我们接着这个类进行分析
//这个openCamera的方法就是刚才APP层调用的方法
public void openCamera(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
throws CameraAccessException {
//调用了这个方法,我们继续往下看这个方法干了啥
openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
USE_CALLING_UID);
}
public void openCameraForUid(@NonNull String cameraId,
...
//这个方法写了个寂寞,做了几个为空判断后,接着调用了下面的方法
openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);
}
//这个方法很关键,首先他返回了一个device
private CameraDevice openCameraDeviceUserAsync(String cameraId,
CameraDevice.StateCallback callback, Executor executor, final int uid)
throws CameraAccessException {
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
//这边定义了一个device,看样子应该是要对这个device进行赋值
CameraDevice device = null;
synchronized (mLock) {
//这边通过ICameraDeviceUser.aidl进行拿到对象
ICameraDeviceUser cameraUser = null;
//这边new了一个CameraDeviceImpl的对象
android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
new android.hardware.camera2.impl.CameraDeviceImpl(
cameraId,
callback,
executor,
characteristics,
mContext.getApplicationInfo().targetSdkVersion);
ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
try {
if (supportsCamera2ApiLocked(cameraId)) {
// Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
//这边是通过binder获取了一个fwk native层的CameraService的对象
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
...
//这边就通过native层的对象拿到一个cameradevice的设备
cameraUser = cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), uid);
} else {
// Use legacy camera implementation for HAL1 devices
...
Log.i(TAG, "Using legacy camera HAL.");
cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id,
getDisplaySize());
}
} ...
// TODO: factor out callback to be non-nested, then move setter to constructor
// For now, calling setRemoteDevice will fire initial
// onOpened/onUnconfigured callbacks.
// This function call may post onDisconnected and throw CAMERA_DISCONNECTED if
// cameraUser dies during setup.
//进行设置远程service防止服务挂了的机制
deviceImpl.setRemoteDevice(cameraUser);
device = deviceImpl;
}
return device;
}
通过上面的代码分析,我觉得CameraManager.java这个类中的关于open的操作其实并没有做多少工作,更多的是作为一个桥梁,通过binder的方式与cameraservice进行了通信,我们接着往下看
CameraService服务
通过之前的分析我们调用了CameraService的connectDevice的方法,我们就接着这个步骤继续往下走,这个会返回一个cameradevice,我们看下CameraService.cpp类
Status CameraService::connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const String16& cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device) {
...
//看到这里又调用了下面的方法进行拿到device,这个方法的最后一个参数即为out输出的,可以看到对最后device进行赋值,接着看connectHelper方法
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
/*api1CameraId*/-1,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
...
*device = client;
return ret;
}
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
int clientPid, apiLevel effectiveApiLevel, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
...
//这个重要,定义了一个client,最后也是对这个client进行赋值
sp<CLIENT> client = nullptr;
{
sp<BasicClient> tmp = nullptr;
//这个makeClient方法较重要,接着往下看
if(!(ret = makeClient(this, cameraCb, clientPackageName,
cameraId, api1CameraId, facing,
clientPid, clientUid, getpid(),
halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp)).isOk()) {
return ret;
}
client = static_cast<CLIENT*>(tmp.get());
//通过上面的makeClient方法拿到一个client后进行了初始化的操作
err = client->initialize(mCameraProviderManager, mMonitorTags);
} // lock is destroyed, allow further connect calls
// Important: release the mutex here so the client can call back into the service from its
// destructor (can be at the end of the call)
device = client;
return ret;
}
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
if (halVersion < 0 || halVersion == deviceVersion) {
...
//这个时候new了一个CameraDeviceClient对象
*client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
facing, clientPid, clientUid, servicePid);
...
} else {
//camera1的分支
...
}
return Status::ok();
}
接着上面的代码继续往下挖,看看CameraDeviceClient.cpp这个类里面又做了啥,上面new了一个这个类的对象
status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
const String8& monitorTags) {
//调用了initializeImpl这个方法
return initializeImpl(manager, monitorTags);
}
template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
...
status_t res;
//划重点,这句话,调用了Camera2ClientBase的init方法
res = Camera2ClientBase::initialize(providerPtr, monitorTags);
...
return OK;
}
没有悬念,继续往下挖,看看Camera2ClientBase.cpp这个类又干了啥,为啥在这初始化了这个类对象
//initialize方法
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
const String8& monitorTags) {
return initializeImpl(manager, monitorTags);
}
//还得看这个方法,这里传入的providerPtr就是之前的CameraProviderManager
template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
const String8& monitorTags) {
...
//看到这里的mDevice的init,这个mDevice看下面是通过构造函数new了一个Camera3Device的对象
res = mDevice->initialize(providerPtr, monitorTags);
...
res = mDevice->setNotifyCallback(weakThis);
return OK;
}
//通过构造函数来看这里的mDevice是new了一个Camera3Device的对象啊
mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
mDevice(new Camera3Device(cameraId)),
mDeviceActive(false), mApi1CameraId(api1CameraId)
接着奏乐,接着舞,再来看看Camera3Device.cpp类
status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
...
//定义了session,我理解为相机设备的会话
sp<ICameraDeviceSession> session;
//开始对这个session进行赋值,调用的就是CameraProviderManager中的方法,这个类也是和hal层进行通讯的类
status_t res = manager->openSession(mId.string(), this,
/*out*/ &session);
...
res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);
...
//new了一个全局的interface
mInterface = new HalInterface(session, queue, mUseHalBufManager);
...
return initializeCommonLocked();
}
这里面看到hal字样了吧,不多久我们就可以进入到hal层了,CameraProviderManager.cpp,这个类主要就是和Hal层进行通信的,走进看看这个类干了啥
status_t CameraProviderManager::openSession(const std::string &id,
const sp<device::V3_2::ICameraDeviceCallback>& callback,
/*out*/
sp<device::V3_2::ICameraDeviceSession> *session) {
...
//获取设备信息
auto deviceInfo = findDeviceInfoLocked(id,
/*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
//根据刚刚deviceInfo中对应的provider的信息,获取到对应CameraProvider服务
const sp<provider::V2_4::ICameraProvider> provider =
deviceInfo->mParentProvider->startProviderInterface();
...
//startDeviceInterface通过CameraProvider的getCameraDeviceInterface_V3_x()实例化一个CameraDevice。这一步是通过HIDL调用到了Hal层,这个CameraDevice是Hal层实作的,和前面APP部分的CameraDevice有所不同,也有所联系
auto interface = deviceInfo3->startDeviceInterface<
CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
// 这个interface就是前面startDeviceInterface()得到的CameraDevice,这里是要通过CameraDevicce::open()创建一个有效的CameraDeviceSession。这一步也是通过HIDL调用到了HAL层
ret = interface->open(callback, [&status, &session]
(Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});
...
return mapToStatusT(status);
}
//根据刚刚deviceInfo中对应的provider的信息,获取到对应CameraProvider服务,通过实际的log打印,这个mSavedInterface一直是不为空的,但由于adb看log比较晚,应该是一起动就已经走过这段逻辑了,并且保存了mSavedInterface这个值
const sp<provider::V2_4::ICameraProvider>
CameraProviderManager::ProviderInfo::startProviderInterface() {
ATRACE_CALL();
ALOGV("Request to start camera provider: %s", mProviderName.c_str());
if (mSavedInterface != nullptr) {
return mSavedInterface;
}
...
auto interface = mActiveInterface.promote();
if (interface == nullptr) {
ALOGI("Camera HAL provider needs restart, calling getService(%s)", mProviderName.c_str());
interface = mManager->mServiceProxy->getService(mProviderName);
interface->setCallback(this);
hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
if (!linked.isOk()) {
mManager->removeProvider(mProviderName);
return nullptr;
} else if (!linked) {
ALOGW("%s: Unable to link to provider '%s' death notifications",
__FUNCTION__, mProviderName.c_str());
}
// Send current device state
if (mMinorVersion >= 5) {
auto castResult = provider::V2_5::ICameraProvider::castFrom(interface);
if (castResult.isOk()) {
sp<provider::V2_5::ICameraProvider> interface_2_5 = castResult;
if (interface_2_5 != nullptr) {
ALOGV("%s: Initial device state for %s: 0x %" PRIx64,
__FUNCTION__, mProviderName.c_str(), mDeviceState);
interface_2_5->notifyDeviceStateChange(mDeviceState);
}
}
}
mActiveInterface = interface;
}
return interface;
}
//startDeviceInterface通过CameraProvider的getCameraDeviceInterface_V3_x()实例化一个CameraDevice。这一步是通过HIDL调用到了Hal层,这个CameraDevice是Hal层实作的,和前面APP部分的CameraDevice有所不同,也有所联系
template<>
sp<device::V3_2::ICameraDevice>
CameraProviderManager::ProviderInfo::startDeviceInterface
<device::V3_2::ICameraDevice>(const std::string &name) {
Status status;
sp<device::V3_2::ICameraDevice> cameraInterface;
hardware::Return<void> ret;
const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
if (interface == nullptr) {
return nullptr;
}
//这个interface是CameraProviderManager不是CameraDevice
ret = interface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Status s, sp<device::V3_2::ICameraDevice> interface) {
status = s;
cameraInterface = interface;
});
...
return cameraInterface;
}
这里面开始与hal层进行通信了,我们准备进入hal层了,做好准备了吗?
Hal层
通过分析上面的native层,看到了CameraProviderManager中的opensession已经和hal层建立了通信,通过ICameraDevice.hal、ICameraDeviceSession.hal、ICameraProvider.hal
这里涉及到两个类CameraProvider.cpp(这个是分版本的,模拟器中走的是CameraProvider_2_4.cpp)、CameraDevice.cpp也是分版本的,我们先看下CameraProvider_2_4.cpp源码
template<typename IMPL>
CameraProvider<IMPL>* getProviderImpl() {
//这里就new了一个CameraProvider的对象
CameraProvider<IMPL> *provider = new CameraProvider<IMPL>();
...
return provider;
}
ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
using namespace android::hardware::camera::provider::V2_4::implementation;
//这个里面主要是根据实际设备选择对应的实现类,通过log发现模拟器使用的是LegacyCameraProviderImpl_2_4这个,所以我们需要进入这个里面来查看对应的逻辑
ICameraProvider* provider = nullptr;
if (strcmp(name, kLegacyProviderName) == 0) {
provider = getProviderImpl<LegacyCameraProviderImpl_2_4>();
} else if (strcmp(name, kExternalProviderName) == 0) {
provider = getProviderImpl<ExternalCameraProviderImpl_2_4>();
} else {
ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
}
return provider;
}
LegacyCameraProviderImpl_2_4.cpp(刚才看到调用到hal这个里面的getCameraDeviceInterface_V3_x)
//这个方法主要就是new了一个CameraDevice的对象
Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
const hidl_string& cameraDeviceName,
ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) {
sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl;
// ICameraDevice 3.4 or upper
if (deviceVersion >= kHAL3_4) {
ALOGV("Constructing v3.4+ camera device");
if (deviceVersion == kHAL3_4) {
deviceImpl = new android::hardware::camera::device::V3_4::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
} else if (deviceVersion == kHAL3_5) {
deviceImpl = new android::hardware::camera::device::V3_5::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
}
...
_hidl_cb (Status::OK, deviceImpl->getInterface());
return Void();
}
// ICameraDevice 3.2 and 3.3
// Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
// to the newest possible Treble HAL revision, but allow for override if needed via
// system property.
switch (mPreferredHal3MinorVersion) {
case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
ALOGV("Constructing v3.2 camera device");
deviceImpl = new android::hardware::camera::device::V3_2::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
...
break;
}
case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
ALOGV("Constructing v3.3 camera device");
deviceImpl = new android::hardware::camera::device::V3_3::implementation::CameraDevice(
mModule, cameraId, mCameraDeviceNames);
...
break;
}
...
}
_hidl_cb (Status::OK, deviceImpl->getInterface());
return Void();
}
//初始化init这里已经new了一个全局CameraModule的对象
bool LegacyCameraProviderImpl_2_4::initialize() {
camera_module_t *rawModule;
...
//这两句是new了一个全局的mModule对象并进行init方法的调用
mModule = new CameraModule(rawModule);
err = mModule->init();
...
// Setup callback now because we are going to try openLegacy next
//设置callback
err = mModule->setCallbacks(this);
...
//获取相机摄像头设备的数量
mNumberOfLegacyCameras = mModule->getNumberOfCameras();
for (int i = 0; i < mNumberOfLegacyCameras; i++) {
struct camera_info info;
auto rc = mModule->getCameraInfo(i, &info);
...
//添加摄像头设备到本地
addDeviceNames(i);
}
return false; // mInitFailed
}
还记得我们在上面分析CameraProviderManager类的时候说到的通过hidl接口调用到hal层的那个interface了吗,对就是这里的open方法,我们进入代码看下
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback,
ICameraDevice::open_cb _hidl_cb) {
Status status = initStatus();
sp<CameraDeviceSession> session = nullptr;
if (callback == nullptr) {
ALOGE("%s: cannot open camera %s. callback is null!",
__FUNCTION__, mCameraId.c_str());
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}
if (status != Status::OK) {
...
} else {
mLock.lock();
ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
session = mSession.promote();
...
/** Open HAL device */
status_t res;
camera3_device_t *device;
//这里就调用到具体module的open方法
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
...
//获取camerainfo
struct camera_info info;
res = mModule->getCameraInfo(mCameraIdInt, &info);
...
session = createSession(
device, info.static_camera_characteristics, callback);
...
mSession = session;
...
mLock.unlock();
}
_hidl_cb(status, session->getInterface());
return Void();
}
追根到底,再来看看CameraModule.cpp源码
调用到module的open方法
int CameraModule::open(const char* id, struct hw_device_t** device) {
int res;
ATRACE_BEGIN("camera_module->open");
res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
ATRACE_END();
return res;
}
这个接下来就是从各个厂商摄像头的设备数据了,整个Camera2的流程从应用层,再到framework层,再到cameraservice层,再到hal层(有个provider@2.4的服务)整个链路上还是比较清晰的,但是具体的代码还是挺多的,由于工作因素,只能闲暇时间梳理,梳理的没有那么详细,大概的流程吧,仅供参考。
坑点:
1.Android Q中按照以往方法修改frameworks/base/core/目录,然后将make framework编译出的framework.jar,直接adb push到手机system/framework/目录下,重启机器会出现无法启动现象,循环报出boot image异常,导致system server无法启动。
解决方案:
修改build/make/core目录下的board_config.mk和dex_preopt_config.mk文件。
1.board_config.mk文件,修改:
WITH_DEXPREOPT := ture 为WITH_DEXPREOPT := false
2.dex_preopt_config.mk文件,修改:
WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY ?= ture 修改为WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY ?= false
注释下面的一段话
ifeq (,$(filter eng, $(TARGET_BUILD_VARIANT)))
ifneq (true,$(WITH_DEXPREOPT))
ifneq (true,$(WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY))
$(call pretty-error, DEXPREOPT must be enabled for user and userdebug builds)
endif
endif
endif
修改截图:

修改完之后,全编代码,刷编译完成后的版本,后面就可以在修改完frameworks/base/后直接make framework单编,然后将生成的framework.jar push到手机system/framework/验证修改。
文章详细梳理了AndroidCamera2模块的工作流程,从APP层的CameraActivity开始,通过CameraManager与fwk层交互,深入到fwkcameraservice和hal层,最终到达硬件接口。过程中涉及CameraModule、CameraDevice、CameraService、CameraProviderManager和HAL层的CameraModule、CameraDevice等关键组件,揭示了Android系统如何通过层层调用来实现相机功能。

3166

被折叠的 条评论
为什么被折叠?



