1,在camera模块的源码中我们发现DisableCameraReceiver的这样一个类,是继承自BroadcastReceiver一个广播接收器,在AndroidManifest.xml中发现这个reciver的intent-filter为<action android:name="android.intent.action.BOOT_COMPLETED" />,当系统启动之后,该模块就会收到这条系统广播,然后进行相应的处理。
path: packages/apps/Camera/src/com/android/camera/DisableCameraReceiver.java
@Override
public void onReceive(Context context, Intent intent) {
// Disable camera-related activities if there is no camera.
boolean needCameraActivity = FeatureSwitcher.isOnlyCheckBackCamera()
? hasBackCamera()
: hasCamera();
if (!needCameraActivity) {
Log.i(TAG, "disable all camera activities");
for (int i = 0; i < ACTIVITIES.length; i++) {
disableComponent(context, ACTIVITIES[i]);
}
}
// Disable this receiver so it won't run again.
disableComponent(context, "com.android.camera.DisableCameraReceiver");
}
2,可以看到,是通过disableComponent(xx, xx);来实现对camera应用的隐藏。
private void disableComponent(Context context, String klass) {
ComponentName name = new ComponentName(context, klass);
PackageManager pm = context.getPackageManager();
// We need the DONT_KILL_APP flag, otherwise we will be killed
// immediately because we are in the same app.
pm.setComponentEnabledSetting(name,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
3,是否需要隐藏camera应用,是通过needCameraActivity的值来判断的,如果其值为true,则显示camera应用,否则,就隐藏掉。那么needCameraActivity的值则是通过hasCamera()这个方法读取出来的。
private boolean hasCamera() {
int n = FrameworksClassFactory.getNumberOfCameras();
Log.i(TAG, "number of camera: " + n);
return (n > 0);
}
path: packages/apps/Camera/src/com/android/camera/FrameworksClassFactory.java
public static int getNumberOfCameras() {
if (MOCK_CAMERA) {
return MockCamera.getNumberOfCameras();
} else {
return Camera.getNumberOfCameras();
}
}
4,通过阅读代码可以了解到,是通过frameworks/base/core/java/android/hardware/Camera.java中的getNumberOfCameras()方法来获取camera的个数。通过这个函数声明,我们知道,这是一个本地方法,是通过JNI调用来获取的。
public native static int getNumberOfCameras();
5,最后在 frameworks/av/camera/CameraBase.cpp中发现对getNumberOfCameras()函数的实现。
int CameraBase<TCam, TCamTraits>::getNumberOfCameras() {
const sp<ICameraService> cs = getCameraService();
if (!cs.get()) {
// as required by the public Java APIs
return 0;
}
return cs->getNumberOfCameras();
}
6,cs是CameraService的一个弱引用,找到frameworks/av/services/camera/libcameraservice/CameraService.cpp中的getNumberOfCameras()函数。
int32_t CameraService::getNumberOfCameras() {
LOG1("[getNumberOfCameras] NumberOfCameras:%d \n", mNumberOfCameras);
return mNumberOfCameras;
}
7,mNumberOfCameras是一个全局变量,定义在CameraService.h中,其赋值的地方在CameraService.cpp中,
void CameraService::onFirstRef()
{
LOG1("CameraService::onFirstRef");
BnCameraService::onFirstRef();
if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&mModule) < 0) {
ALOGE("Could not load camera HAL module");
mNumberOfCameras = 0;
} else {
ALOGI("Loaded \"%s\" camera module", mModule->common.name);
mNumberOfCameras = mModule->get_number_of_cameras();
if (mNumberOfCameras > MAX_CAMERAS) {
ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
mNumberOfCameras, MAX_CAMERAS);
mNumberOfCameras = MAX_CAMERAS;
}
//for (int i = 0; i < mNumberOfCameras; i++) {
for (int i = 0; i < MAX_CAMERAS; i++) { // workaround for MATV
LOG1("setCameraFree(%d)", i);
setCameraFree(i);
}
if (mModule->common.module_api_version >=
CAMERA_MODULE_API_VERSION_2_1) {
mModule->set_callbacks(this);
}
CameraDeviceFactory::registerService(this);
}
}
至此,整个隐藏camera应用的流程分析完成,通过对Camera的个数的判断,来解析是否有必要显示此应用的图标。