软件平台: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>
至此,需求开发完成。