Android11 添加开机启动后固件升级逻辑

软件平台:Android11

硬件平台:QCS6125

    需求:开机阶段,添加一个系统固件检测的逻辑,判断是否需要升级底层的fw,考虑到产品要求这个检测要在Launcher界面之前,如果fw需要升级可能需要3-5分钟,因此UI需要给用户展示一屏提示,因此,这个节点就选择了FallbackHome阶段,直接上修改:

1、添加资源文件,即升级情况的全屏UI提示背景图;

/res/drawable/upgrade.png

2、添加检测升级的逻辑如下:

diff --git a/src/com/android/settings/FallbackHome.java b/src/com/android/settings/FallbackHome.java
index 3a44603347..f2f90cc132 100644
--- a/src/com/android/settings/FallbackHome.java
+++ b/src/com/android/settings/FallbackHome.java
@@ -39,13 +39,25 @@ import android.os.PowerManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.SystemClock;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 import android.view.animation.AnimationUtils;
 
 import java.util.Objects;
+import java.util.Vector;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
 
 public class FallbackHome extends Activity {
     private static final String TAG = "FallbackHome";
@@ -59,6 +71,15 @@ public class FallbackHome extends Activity {
     private static final String SURFACE_COMPOSER_INTERFACE_KEY = "android.ui.ISurfaceComposer";
     private static final int SURFACE_FLINGER_DISABLE_OVERLAYS_CODE = 1008;
 
+    static public final boolean Debug = true;
+    static public final String T1000_FW_PATH = "/system/bin/firmware";
+    //static public final String T1000_FW_PATH = "/system/bin";
+    static public final String T1000_VERSION_PATH = "/sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/info";
+    //static public final String T1000_UPDATE_PATH = "/sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/update_waveform";
+    static public final String T1000_UPDATE_PATH = "/sys/bus/i2c/devices/0-0006/update_waveform";
+    static public final String T1000_PAUSE_PATH = "/sys/bus/i2c/devices/0-0006/pause";
+    static public final String T1000_RESET_PATH = "/sys/bus/i2c/devices/0-0006/reset";
+
        private static IBinder mSurfaceFlinger;
 
     private final Runnable mProgressTimeoutRunnable = () -> {
@@ -67,7 +88,7 @@ public class FallbackHome extends Activity {
         setContentView(v);
         v.setAlpha(0f);
         v.animate()
-                .alpha(1f)
+                .alpha(0f)
                 .setDuration(500)
                 .setInterpolator(AnimationUtils.loadInterpolator(
                         this, android.R.interpolator.fast_out_slow_in))
@@ -119,6 +140,12 @@ public class FallbackHome extends Activity {
 
         initHardwareOverlaysSetting(SETTING_VALUE_ON);
 
+        if (ifNeedUpdateT1000()) {
+            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
+            this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
+            this.getWindow().setBackgroundDrawableResource(R.drawable.upgrade);
+        }
+
         registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
         maybeFinish();
     }
@@ -199,6 +226,91 @@ public class FallbackHome extends Activity {
         loadWallpaperColorsTask.execute();
     }
 
+    private String getT1000Version() {
+        String version = null;
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new FileReader(T1000_VERSION_PATH));
+            while ((version = reader.readLine()) != null) {
+                if (version.contains("firmware"))
+                    break;
+            }
+            if (Debug) {
+                version = version.substring(version.lastIndexOf(".") + 1, version.length());
+                Log.d(TAG, "read t1000 version: " + version);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if(reader != null){
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return version;
+    }
+
+    private void updateT1000Fw() {
+        Log.d(TAG, "will update t1000 fw.");
+        BufferedWriter bufWriter = null;
+        String cmd = "3,/system/bin/firmware/" + getFwFileName(T1000_FW_PATH) + ".bin";
+
+        try {
+            bufWriter = new BufferedWriter(new FileWriter(T1000_PAUSE_PATH));
+            bufWriter.write("1");
+            bufWriter.close();
+
+            SystemClock.sleep(1000);
+
+            bufWriter = new BufferedWriter(new FileWriter(T1000_UPDATE_PATH));
+            bufWriter.write(cmd);
+            bufWriter.close();
+
+            bufWriter = new BufferedWriter(new FileWriter(T1000_PAUSE_PATH));
+            bufWriter.write("0");
+            bufWriter.close();
+
+            bufWriter = new BufferedWriter(new FileWriter(T1000_RESET_PATH));
+            bufWriter.write("1");
+            bufWriter.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static String getFwFileName(String fileAbsolutePath) {
+        Vector<String> vecFile = new Vector<String>();
+        File file = new File(fileAbsolutePath);
+        File[] subFile = file.listFiles();
+        String filename = null;
+
+        if (subFile != null) {
+            for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
+                if (!subFile[iFileLength].isDirectory()) {
+                    filename = subFile[iFileLength].getName();
+                    Log.d(TAG, "getFwFileName: " + filename);
+                    if (filename.contains("M0")) {
+                        filename = filename.substring(0, filename.length() - 4);
+                    }
                }
+            }
+            return  filename;
+        }
+
+        return null;
+    }
+
+    private boolean ifNeedUpdateT1000() {
+        if (getFwFileName(T1000_FW_PATH).compareTo(getT1000Version()) > 0) {
+            return true;
+        }
+
+        return false;
+    }
+
     private void maybeFinish() {
         if (getSystemService(UserManager.class).isUserUnlocked()) {
             final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
@@ -215,6 +327,11 @@ public class FallbackHome extends Activity {
                 mHandler.sendEmptyMessageDelayed(0, 500);
             } else {
                 Log.d(TAG, "User unlocked and real home found; let's go!");
+
+                if (ifNeedUpdateT1000()) {
+                    updateT1000Fw();
+                }
+
                 getSystemService(PowerManager.class).userActivity(
                         SystemClock.uptimeMillis(), false);
                 finish();

onCreate方法就做是否升级的逻辑判断,如果不升则按默认流程找到launcher后启动;如果需要升级,则设置背景图,并且设置不可点击,防止不必要的anr出现。

3、添加完成验证,会发现一堆selinux权限规则问题,高通平台需要在device源码添加完成:

diff --git a/generic/vendor/common/file_contexts b/generic/vendor/common/file_contexts
index 9c39fe22..b6af4b1b 100755
--- a/generic/vendor/common/file_contexts
+++ b/generic/vendor/common/file_contexts
@@ -526,7 +526,14 @@
 /sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/epd_busy                                u:object_r:vendor_epd_graphics:s0
 /sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/engine                                  u:object_r:vendor_epd_graphics:s0
 /sys/devices/platform/soc/4c84000.spi/idle_time                                       u:object_r:vendor_epd_graphics:s0
+/sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/info                                    u:object_r:vendor_epd_graphics:s0
+/sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/update_waveform                         u:object_r:vendor_epd_graphics:s0
+/sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/pause                                   u:object_r:vendor_epd_graphics:s0
+/sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/reset                                   u:object_r:vendor_epd_graphics:s0
 /sys/bus/i2c/devices/0-0006/commit                                                         u:object_r:sys_bus_devices_commit:s0
+/sys/bus/i2c/devices/0-0006/pause                                                          u:object_r:sys_bus_devices_commit:s0
+/sys/bus/i2c/devices/0-0006/reset                                                          u:object_r:sys_bus_devices_commit:s0
+/sys/bus/i2c/devices/0-0006/update_waveform                                                u:object_r:sys_bus_devices_commit:s0
 /sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/commit                                  u:object_r:sys_bus_devices_commit:s0
 /sys/class/leds(/.*)?                                                                      u:object_r:sysfs_class_leds:s0
 ../../devices/platform/soc/1c40000.qcom,spmi/spmi-0/spmi0-03/1c40000.qcom,spmi:qcom,pmi632@3:qcom,leds@d000/leds(/.*)?       u:object_r:sysfs_class_leds:s0
diff --git a/generic/vendor/common/genfs_contexts b/generic/vendor/common/genfs_contexts
index 60073a15..b0cf901c 100644
--- a/generic/vendor/common/genfs_contexts
+++ b/generic/vendor/common/genfs_contexts
@@ -133,6 +133,9 @@ genfscon sysfs /power/mem_sleep u:object_r:vendor_sysfs_suspend:s0
 genfscon sysfs /kernel/boot_adsp/ssr                                   u:object_r:vendor_sysfs_adsp_ssr:s0
 genfscon sysfs /firmware/devicetree/base/soc  u:object_r:vendor_sysfs_devicetree_soc:s0
 genfscon sysfs /sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/commit  u:object_r:sys_bus_devices_commit:s0
+genfscon sysfs /sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/update_waveform  u:object_r:sys_bus_devices_commit:s0
+genfscon sysfs /sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/pause  u:object_r:sys_bus_devices_commit:s0
+genfscon sysfs /sys/devices/platform/soc/4a84000.i2c/i2c-0/0-0006/reset  u:object_r:sys_bus_devices_commit:s0
 
 genfscon debugfs /kgsl/proc                           u:object_r:vendor_debugfs_kgsl:s0
 genfscon debugfs /clk/debug_suspend                   u:object_r:vendor_debugfs_clk:s0
diff --git a/generic/vendor/common/system_app.te b/generic/vendor/common/system_app.te
index 9a79fd72..3e16ac0d 100755
--- a/generic/vendor/common/system_app.te
+++ b/generic/vendor/common/system_app.te
@@ -35,6 +35,11 @@ allow system_app sysfs_class_leds:lnk_file { getattr open read write };
 allow system_app sysfs_class_leds:dir { search };
 allow system_app vendor_sysfs_graphics:dir { search };
 allow system_app vendor_sysfs_graphics:file { getattr open read write };
+allow system_app vendor_epd_graphics:file { getattr open read write };
+allow system_app vendor_epd_graphics:lnk_file { getattr open read write };
+
+allow system_app sys_bus_devices_commit:file {getattr read open write};
+allow system_app sys_bus_devices_commit:lnk_file {getattr read open write};
 
 # Allow hbtp hal Service to be found
 hal_client_domain(system_app, vendor_hal_hbtp)

    对于qcom平台,做如上修改后,可在android跟目录执行完env之后,mmm system/sepolicy就可以生成,会在out/target/product/trinket目录(lunch的产品)生成到两个路径下:system/etc/selinux和vendor/etc/selinux,分别将这两个目录push到target就可以验证生效;

4、由于默认的launcher启动前界面,会展示“设备正在启动...” 的UI,开头的png背景可能在这之下,导致很怪异的逻辑,需要屏蔽掉这个UI显示:

--- a/res/layout/fallback_home_finishing_boot.xml
+++ b/res/layout/fallback_home_finishing_boot.xml
@@ -22,7 +22,7 @@
     android:background="#80000000"
     android:forceHasOverlappingRendering="false">
 
-    <LinearLayout
+    <!--LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="vertical"
@@ -45,5 +45,5 @@
             android:colorControlActivated="?android:attr/textColorPrimary"
             android:indeterminate="true"/>
 
-    </LinearLayout>
+    </LinearLayout-->
 </FrameLayout>

至此,需求开发完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值