最近接触Firefly aio3399j 开发板,并使用其开源代码编译了固件并烧写在板子上面,并且尝试性地修改了部分framework代码。
官方Wiki:http://wiki.t-firefly.com/zh_CN/AIO-3399J/compile_android8.1_firmware.html
论坛地址:http://dev.t-firefly.com/portal.php?mod=topic&topicid=11
修改内容包括:
1.boot开机logo和android开机logo的修改
2.桌面权限直接赋予,不必申请
3.关机方法的底层修改,使应用层能够调用关机
4.串口权限的修改,使应用层能够读写串口
5.usb midi连接提示框去掉,改成默认进行连接
6.录音回声消除
aio3399j安卓8.1源码编译系统执行步骤:
- ./FFTools/make.sh -d rk3399-firefly-aio -j8 -l rk3399_firefly_aio_mid-userdebug
- mkimage.sh
- device.mk
- full_base.mk
- generic_no_telephony.mk
- core.mk
编译安卓8.1源码步骤:
拷贝源码解压包到linux
复制解压包到工作目录下
执行git reset --hard检出代码
git remote add gitlab https://gitlab.com/TeeFirefly/firenow-oreo-rk3399.git
git pull gitlab firefly-rk3399:firefly-rk3399
-
修改prebuilts/sdk/tools/jack-admin,在JACK_SERVER_VM_ARGUMENTS的后面添加-Xmx4096M,26行和451行
./prebuilts/sdk/tools/jack-admin kill-server
./prebuilts/sdk/tools/jack-admin start-server编译 ./FFTools/make.sh -d rk3399-firefly-aio -j2 -l rk3399_firefly_aio_mid-userdebug
./FFTools/mkupdate/mkupdate.sh -l rk3399_firefly_aio_mid-userdebug
- 打包:复制RKTools/windows/AndroidTool 到windows操作系统,解压rockdev和AndroidTool_Release_v2.41,复制编译之后生成的镜像文件 rockdev/编译的版本/* 到rockdev/Image,修改rockdev/package-file里面的所有路径一一对应Image里面文件的路径,修改mkupdate.bat里面的Loader路径对应Image里面的Loader路径,双击mkupdate.bat执行打包
- 烧录:按照官方教程,不再赘述
以下全部基于aio3399j主板以及官方安卓8.1系统源码
桌面NavBar的电源按钮事件触发流程
在systemui中,frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java中的poweroffClick方法中发送Intent.ACTION_SYSTEMUI_FIREFLY_POWEROFF广播
private void poweroffClick(View v) {
Intent intent=new Intent(Intent.ACTION_SYSTEMUI_FIREFLY_POWEROFF);
getContext().sendBroadcast(intent);
}
PhoneWindowManager接收广播调用showGlobalActionsInternal()方法
void showGlobalActionsInternal() {
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
if (mGlobalActions == null) {
mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
}
final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
if (keyguardShowing) {
// since it took two seconds of long press to bring this up,
// poke the wake lock so they have some time to see the dialog.
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
}
PowerManager
public void userActivity(long when, int event, int flags) {
try {
mService.userActivity(when, event, flags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
PowerManagerService
@Override // Binder call
public void userActivity(long eventTime, int event, int flags) {
final long now = SystemClock.uptimeMillis();
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED
&& mContext.checkCallingOrSelfPermission(
android.Manifest.permission.USER_ACTIVITY)
!= PackageManager.PERMISSION_GRANTED) {
// Once upon a time applications could call userActivity().
// Now we require the DEVICE_POWER permission. Log a warning and ignore the
// request instead of throwing a SecurityException so we don't break old apps.
synchronized (mLock) {
if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
mLastWarningAboutUserActivityPermission = now;
Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
+ "caller does not have DEVICE_POWER or USER_ACTIVITY "
+ "permission. Please fix your app! "
+ " pid=" + Binder.getCallingPid()
+ " uid=" + Binder.getCallingUid());
}
}
return;
}
if (eventTime > now) {
throw new IllegalArgumentException("event time must not be in the future");
}
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
userActivityInternal(eventTime, event, flags, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
修改代码集合
修改摄像头最大支持数量:
hardware\rockchip\camera\CameraHal\CameraHal_Module.h
#if defined(TARGET_RK3399)
#define CAMERAS_SUPPORTED_SIMUL_MAX 8
#else
#define CAMERAS_SUPPORTED_SIMUL_MAX 8
#endif
摄像头修改https://blog.csdn.net/kris_fei/article/details/81508302
diff --git a/CameraHal/CameraHal_Module.cpp b/CameraHal/CameraHal_Module.cpp
index 01afa0d..07380f2 100755
--- a/CameraHal/CameraHal_Module.cpp
+++ b/CameraHal/CameraHal_Module.cpp
@@ -835,7 +839,7 @@ int camera_get_number_of_cameras(void)
fd = open(cam_path, O_RDONLY);
if (fd < 0) {
LOGE("Open %s failed! strr: %s",cam_path,strerror(errno));
- break;
+ continue;
}
LOGD("Open %s success!",cam_path);
@@ -849,13 +853,13 @@ int camera_get_number_of_cameras(void)
LOGD("Video device(%s): video capture not supported.\n",cam_path);
} else {
rk_cam_total_info* pNewCamInfo = new rk_cam_total_info();
- memset(camInfoTmp[cam_cnt&0x01].device_path,0x00, sizeof(camInfoTmp[cam_cnt&0x01].device_path));
- strcat(camInfoTmp[cam_cnt&0x01].device_path,cam_path);
- memset(camInfoTmp[cam_cnt&0x01].fival_list,0x00, sizeof(camInfoTmp[cam_cnt&0x01].fival_list));
- memcpy(camInfoTmp[cam_cnt&0x01].driver,capability.driver, sizeof(camInfoTmp[cam_cnt&0x01].driver));
- camInfoTmp[cam_cnt&0x01].version = capability.version;
+ memset(camInfoTmp[cam_cnt].device_path,0x00, sizeof(camInfoTmp[cam_cnt].device_path));
+ strcat(camInfoTmp[cam_cnt].device_path,cam_path);
+ memset(camInfoTmp[cam_cnt].fival_list,0x00, sizeof(camInfoTmp[cam_cnt].fival_list));
+ memcpy(camInfoTmp[cam_cnt].driver,capability.driver, sizeof(camInfoTmp[cam_cnt].driver));
+ camInfoTmp[cam_cnt].version = capability.version;
if (strstr((char*)&capability.card[0], "front") != NULL) {
- camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT;
+ camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_FRONT;
#ifdef LAPTOP
} else if (strstr((char*)&capability.card[0], "HP HD") != NULL
|| strstr((char*)&capability.card[0], "HP IR")) {
@@ -866,14 +870,14 @@ int camera_get_number_of_cameras(void)
LOGD("Camera %d name: %s", (cam_cnt&0x01), gUsbCameraNames[cam_cnt&0x01].string());
#endif
} else {
- camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_BACK;
+ camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_BACK;
}
ptr = strstr((char*)&capability.card[0],"-");
if (ptr != NULL) {
ptr++;
- camInfoTmp[cam_cnt&0x01].facing_info.orientation = atoi(ptr);
+ camInfoTmp[cam_cnt].facing_info.orientation = atoi(ptr);
} else {
- camInfoTmp[cam_cnt&0x01].facing_info.orientation = 0;
+ camInfoTmp[cam_cnt].facing_info.orientation = 0;
}
memset(version,0x00,sizeof(version));
@@ -1207,8 +1211,11 @@ int camera_get_number_of_cameras(void)
}
#endif
- memcpy(&gCamInfos[0], &camInfoTmp[0], sizeof(rk_cam_info_t));
- memcpy(&gCamInfos[1], &camInfoTmp[1], sizeof(rk_cam_info_t));
+ for (int i = 0; i < gCamerasNumber; i++) {
+ memcpy(&gCamInfos[i], &camInfoTmp[i], sizeof(rk_cam_info_t));
+ }
property_get("ro.sf.hwrotation", property, "0");
diff --git a/CameraHal/CameraHal_Module.h b/CameraHal/CameraHal_Module.h
index 45c81ec..69be491 100755
--- a/CameraHal/CameraHal_Module.h
+++ b/CameraHal/CameraHal_Module.h
@@ -11,11 +11,11 @@ using namespace android;
#define CAMERA_DEFAULT_PREVIEW_FPS_MIN 8000 //8 fps
#define CAMERA_DEFAULT_PREVIEW_FPS_MAX 15000
#endif
-#define CAMERAS_SUPPORT_MAX 2
+#define CAMERAS_SUPPORT_MAX 10
#if defined(TARGET_RK3399)
- #define CAMERAS_SUPPORTED_SIMUL_MAX 2
+ #define CAMERAS_SUPPORTED_SIMUL_MAX 10
#else
- #define CAMERAS_SUPPORTED_SIMUL_MAX 1
+ #define CAMERAS_SUPPORTED_SIMUL_MAX 10
#endif
#define CAMERA_DEVICE_NAME "/dev/video"
#define CAMERA_MODULE_NAME "RK29_ICS_CameraHal_Module"
为禁用掉HDMI声卡切换修改:
/services/java/com/android/server/WiredAccessoryManager.java
注释掉386-396行
为使用USB声卡,需要在开发和选项中开启USB音频设备
为强制APP横屏,修改了WindowManagerService:2589行
boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId) {
long ident = Binder.clearCallingIdentity();
try {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
//TODO huanghai modify
//--------------以下为修改-----------------
//final int req = dc.getOrientation();
final int req = Surface.ROTATION_0;
//--------------修改完成-------------------
if (req != dc.getLastOrientation()) {
dc.setLastOrientation(req);
//send a message to Policy indicating orientation change to take
//action like disabling/enabling sensors etc.,
// TODO(multi-display): Implement policy for secondary displays.
if (dc.isDefaultDisplay) {
mPolicy.setCurrentOrientationLw(req);
}
if (dc.updateRotationUnchecked(inTransaction)) {
// changed
return true;
}
}
return false;
} finally {
Binder.restoreCallingIdentity(ident);
}
}
为缩小屏幕元素显示,修改了rk3399_firefly_aio_mid.mk:46行,现由于底部旋转图标消失已改回240
修改前
ro.sf.lcd_density=240
修改后
ro.sf.lcd_density=160
为给到串口权限,修改了init.rk3399.rc:8行
chmod 0766 /dev/ttysWK3
为修改开机画面,修改了kernel文件夹的logo.bmp和logo_kernel.bmp文件,以及frameworks/base/core/res/assets/images
为去掉USB权限弹出框,修改了frameworks\base\packages\SystemUI\src\com\android\systemui\usb\UsbPermissionActivity.java
ap.mPositiveButtonText = getString(android.R.string.ok);
ap.mNegativeButtonText = getString(android.R.string.cancel);
ap.mPositiveButtonListener = this;
ap.mNegativeButtonListener = this;
// add "always use" checkbox
LayoutInflater inflater = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
ap.mView = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
mAlwaysUse = (CheckBox)ap.mView.findViewById(com.android.internal.R.id.alwaysUse);
if (mDevice == null) {
mAlwaysUse.setText(R.string.always_use_accessory);
} else {
mAlwaysUse.setText(R.string.always_use_device);
}
mAlwaysUse.setOnCheckedChangeListener(this);
mClearDefaultHint = (TextView)ap.mView.findViewById(
com.android.internal.R.id.clearDefaultHint);
mClearDefaultHint.setVisibility(View.GONE);
//------注释掉此行--------
//setupAlert();
mPermissionGranted = true;
finish();
}