最近接觸Firefly aio3399j 開發(fā)板,并使用其開源代碼編譯了固件并燒寫在板子上面,并且嘗試性地修改了部分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
修改內(nèi)容包括:
1.boot開機(jī)logo和android開機(jī)logo的修改
2.桌面權(quán)限直接賦予,不必申請
3.關(guān)機(jī)方法的底層修改,使應(yīng)用層能夠調(diào)用關(guān)機(jī)
4.串口權(quán)限的修改,使應(yīng)用層能夠讀寫串口
5.usb midi連接提示框去掉,改成默認(rèn)進(jìn)行連接
6.錄音回聲消除
aio3399j安卓8.1源碼編譯系統(tǒng)執(zhí)行步驟:
- ./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
復(fù)制解壓包到工作目錄下
執(zhí)行g(shù)it 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行
image.png ./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
- 打包:復(fù)制RKTools/windows/AndroidTool 到windows操作系統(tǒng),解壓rockdev和AndroidTool_Release_v2.41,復(fù)制編譯之后生成的鏡像文件 rockdev/編譯的版本/* 到rockdev/Image,修改rockdev/package-file里面的所有路徑一一對應(yīng)Image里面文件的路徑,修改mkupdate.bat里面的Loader路徑對應(yīng)Image里面的Loader路徑,雙擊mkupdate.bat執(zhí)行打包
- 燒錄:按照官方教程,不再贅述
以下全部基于aio3399j主板以及官方安卓8.1系統(tǒng)源碼
桌面NavBar的電源按鈕事件觸發(fā)流程
在systemui中,frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java中的poweroffClick方法中發(fā)送Intent.ACTION_SYSTEMUI_FIREFLY_POWEROFF廣播
private void poweroffClick(View v) {
Intent intent=new Intent(Intent.ACTION_SYSTEMUI_FIREFLY_POWEROFF);
getContext().sendBroadcast(intent);
}
PhoneWindowManager接收廣播調(diào)用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);
}
}
修改代碼集合
修改攝像頭最大支持?jǐn)?shù)量:
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聲卡,需要在開發(fā)和選項(xiàng)中開啟USB音頻設(shè)備
為強(qiáng)制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行,現(xiàn)由于底部旋轉(zhuǎn)圖標(biāo)消失已改回240
修改前
ro.sf.lcd_density=240
修改后
ro.sf.lcd_density=160
為給到串口權(quán)限,修改了init.rk3399.rc:8行
chmod 0766 /dev/ttysWK3
為修改開機(jī)畫面,修改了kernel文件夾的logo.bmp和logo_kernel.bmp文件,以及frameworks/base/core/res/assets/images
為去掉USB權(quán)限彈出框,修改了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();
}