Firefly aio3399j 安卓8.1源碼編譯

最近接觸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í)行步驟:

  1. ./FFTools/make.sh -d rk3399-firefly-aio -j8 -l rk3399_firefly_aio_mid-userdebug
  2. mkimage.sh
  3. device.mk
  4. full_base.mk
  5. generic_no_telephony.mk
  6. core.mk

編譯安卓8.1源碼步驟:

  1. 拷貝源碼解壓包到linux

  2. 復(fù)制解壓包到工作目錄下

  3. 執(zhí)行g(shù)it reset --hard檢出代碼

  4. git remote add gitlab https://gitlab.com/TeeFirefly/firenow-oreo-rk3399.git

  5. git pull gitlab firefly-rk3399:firefly-rk3399

  6. 修改prebuilts/sdk/tools/jack-admin,在JACK_SERVER_VM_ARGUMENTS的后面添加-Xmx4096M,26行和451行


    image.png
  7. ./prebuilts/sdk/tools/jack-admin kill-server
    ./prebuilts/sdk/tools/jack-admin start-server

  8. 編譯 ./FFTools/make.sh -d rk3399-firefly-aio -j2 -l rk3399_firefly_aio_mid-userdebug

./FFTools/mkupdate/mkupdate.sh -l rk3399_firefly_aio_mid-userdebug

  1. 打包:復(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í)行打包
  2. 燒錄:按照官方教程,不再贅述

以下全部基于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();

    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容