Firefly aio3399j 安卓8.1源码编译

最近接触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源码编译系统执行步骤:

  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. 复制解压包到工作目录下

  3. 执行git 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. 打包:复制RKTools/windows/AndroidTool 到windows操作系统,解压rockdev和AndroidTool_Release_v2.41,复制编译之后生成的镜像文件 rockdev/编译的版本/* 到rockdev/Image,修改rockdev/package-file里面的所有路径一一对应Image里面文件的路径,修改mkupdate.bat里面的Loader路径对应Image里面的Loader路径,双击mkupdate.bat执行打包
  2. 烧录:按照官方教程,不再赘述

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

    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容