MTK android 12 NVRAM实现数据备份

在做项目过程中客户提了定制化需求:即保存一段数据,即使在设备恢复出厂的情况下,数据亦不能删除。

参考了一些资料,由于大版本不同,在之前的版本上做了对应的修改。

  • 添加 nvram lib数据结构定义
    vendor/mediatek/proprietary/custom/myproject/cgen/cfgfileinc/CFG_Custom1_File.h
+typedef struct
+{
+    unsigned char Array[1024];
+}File_My_Custom1_Struct;
+ 
+#define CFG_MY_CUSTOM1_REC_SIZE    sizeof(File_MY_CUSTOM1_Struct)
+#define CFG_MY_CUSTOM1_REC_TOTAL   1
  • 添加nvram lib默认值定义
    vendor/mediatek/proprietary/custom/myproject/cgen/cfgdefault/CFG_Custom1_Default.h
+File_My_Custom1_Struct stMyCustom1Default =
+{
+
+    0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
+};
  • 添加nvram lib id定义
    vendor/mediatek/proprietary/custom/myproject/cgen/inc/Custom_NvRam_LID.h
	AP_CFG_RDCL_FILE_AUDIO_BT_GAIN_CUSTOM_LID,
	AP_CFG_RDCL_FILE_AUDIO_FUNC_SWITCH_PARAM_LID,
	AP_CFG_CUSTOM_FILE_FUEL_GAUGE_LID,
+   AP_CFG_CUSTOM_FILE_MY_CUSTOM1_LID,
	AP_CFG_CUSTOM_FILE_MAX_LID,
 } CUSTOM_CFG_FILE_LID;
 
+#define AP_CFG_CUSTOM_FILE_MY_CUSTOM1_LID_VERNO              "000"
  • 添加nvram lib id的数据结构
    vendor/mediatek/proprietary/custom/myproject/cgen/inc/Custom_NvRam_data_item.h
+LID_BIT VER_LID(AP_CFG_CUSTOM_FILE_MY_CUSTOM1_LID)
+File_My_Custom1_Struct *CFG_MY_CUSTOM1_REC_TOTAL
+{
+
+};
  • nvram lib数据加入到nvram数组中(切记加到数组末尾)
    vendor/mediatek/proprietary/custom/myproject/cgen/inc/CFG_file_info_custom.h
const TCFG_FILE g_akCFG_File_Custom[]=
{
...
+	{ "/mnt/vendor/protect_f/MY_CUSTOM1",  VER(AP_CFG_CUSTOM_FILE_MY_CUSTOM1_LID),  CFG_MY_CUSTOM1_REC_SIZE,
+      CFG_MY_CUSTOM1_REC_TOTAL, SIGNLE_DEFUALT_REC,   (char *)&stMyCustom1Default, DataReset , NULL
+   },
};

目前nvram lib id添加已基本完成,下一步需要对nvram数据进行读写操作。现在做法是对读写进行类封装,做成jar包供应用调用。
vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\mediatek\settings\test\MyCustom1Manager.java

package com.mediatek.settings.test;

import static android.net.wifi.ScanResult.InformationElement;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder ;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.util.HexDump;

import java.lang.InterruptedException;
import java.lang.Thread;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.StringTokenizer;

import vendor.mediatek.hardware.nvram.V1_0.INvram;

public class MyCustom1Manager {

    private static final String TAG = "MyCustom1Manager";

    private static final int MY_CUSTOM1_SIZE = 18;

    ///backup/APCFG/APRDEB/MY_CUSTOMS1
    ///mnt/vendor/nvdata/APCFG/APRDEB/
    ///vendor/nvdata/APCFG/APRDEB
    ///data/nvram/APCFG/APRDEB
    ///vendor/nvdata/md/NVRAM/
    ///mnt/vendor/protect_f/
    private static final String MY_CUSTOM1_FILENAME = "/mnt/vendor/protect_f/MY_CUSTOM1";

    public String getMyCustom1FromNvram() {
        try {
            int i = 0;
            String buff = null;
            INvram agent = null;
            try {
                agent = INvram.getService();
            } catch (NoSuchElementException ne) {
                ne.printStackTrace();
            }
            if (agent == null) {
                Log.e(TAG, "NvRAMAgent is null");
                try {
                    Thread.sleep(100);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                //try get agent
                agent = INvram.getService();
            }
            if (agent == null) {
                Log.e(TAG, "No support My Custom1 writing due to NVRAM");
                Log.e(TAG, "NvRAMAgent is null");
                return "";
            }
            try {
                buff = agent.readFileByName(
                        MY_CUSTOM1_FILENAME, MY_CUSTOM1_SIZE);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
            Log.i(TAG, "Raw data:" + buff);
            return hexToString(buff).trim();
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "getMyCustom1FromNvram exception:" + e.getMessage());
            return "";
        }
    }
    
    public String hexToString(String hex) {
        StringBuilder sb = new StringBuilder();
        
        for (int i = 0; i < hex.length() - 1; i += 2) {
            int decimalValue = Integer.parseInt(hex.substring(i, i + 2), 16);
            
            // 添加到结果字符串中
            sb.append((char) decimalValue);
        }
        
        return sb.toString();
    }
    
    public byte[] hexStringToByteArray(String hexString) {
        if (hexString == null || hexString.length() == 0) return new byte[0];
        int len = hexString.length();
        byte[] byteArray = new byte[len / 2];
        for ( int start = 0; start < len - 1; start += 2 )
        {
            String thisByte = hexString.substring(start, start+2);
            byteArray[start/2] = Byte.parseByte(thisByte, 16);
        }
        return byteArray;
    }

    public boolean updateMyCustom1(String data) {
        try {
            INvram agent = null;
            try {
                agent = INvram.getService();
            } catch (NoSuchElementException ne) {
                ne.printStackTrace();
            }
            if (agent == null) {
                Log.e(TAG, "NvRAMAgent is null");
                try {
                    Thread.sleep(100);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                //try get agent
                agent = INvram.getService();
            }
            
            if (agent == null) {
                Log.e(TAG, "No support My Custom1 writing due to NVRAM");
                Log.e(TAG, "NvRAMAgent is null");
                return false;
            }

            String buff = null;
            try {
                buff = agent.readFileByName(
                        MY_CUSTOM1_FILENAME, MY_CUSTOM1_SIZE);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }

            if (buff.equals(data)) return true;
            //byte[] buffArr = HexDump.hexStringToByteArray(buff.substring(0, buff.length() - 1));
            byte[] buffArr = hexStringToByteArray(buff);
            byte[] dataArr = data.getBytes();
            int i = 0,j = 0;
            int len = dataArr.length;
            Log.e(TAG, "dataArr length:" + len);

            ArrayList<Byte> dataArray = new ArrayList<Byte>(
                                MY_CUSTOM1_SIZE);

            for (i = 0, j = 0; i < MY_CUSTOM1_SIZE; i++) {
                if (MY_CUSTOM1_SIZE - i > len) {
                    if (i < buffArr.length) {
                        dataArray.add(buffArr[i]);
                    } else {
                        dataArray.add((byte)0x00);
                    }
                } else {
                    dataArray.add(dataArr[j]);
                    if (j < len) {
                        j++;
                    }
                }
            }

            int flag = 0;
            try {
                Log.e(TAG, "writeFileByNamevec dataArray:" + dataArray.toString());
                flag = agent.writeFileByNamevec(MY_CUSTOM1_FILENAME,
                        MY_CUSTOM1_SIZE, dataArray);
            } catch (Exception e) {
                Log.e(TAG, "writeFileByNamevec error:" + e.getMessage());
                return false;
            }
        } catch (Exception e) {
            Log.e(TAG, "updateMyCustom1 error:" + e.getMessage());
        }
        return true;
    }
}

因为 import vendor.mediatek.hardware.nvram.V1_0.INvram; 在应用中无法导入,怎么生成jar包呢,… ,可以借助系统模块编译生成(灵光一现),下面是jar包生成方法

vendor\mediatek\proprietary\packages\apps\MtkSettings\MyCustom1.mf

Main-Class: com.mediatek.settings.test.MyCustom1Manager

vendor/mediatek/proprietary/packages/apps/MtkSettings/Android.bp

+java_library {
+    name: "MyCustom1Manager",
+    srcs: ["src/com/mediatek/settings/test/MyCustom1Manager.java",],
+    manifest: "MyCustom1.mf",
+    platform_apis: true,

+    static_libs: [
+        "vendor.mediatek.hardware.nvram-V1.0-java"
+    ],

+    libs: [
+        "framework",
+    ]
}

android_library {
	name: "MtkSettings-core",
	...
	static_libs: [
		...
		"android.hardware.dumpstate-V1.1-java",
		"lottie",
+       "vendor.mediatek.hardware.nvram-V1.0-java"
     ],
     ...
}

编译类和编译资源已添加完成,然后使用如下指令进行编译:
mmma vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/mediatek/settings/test/

编译完成后jar包会生成在out目录下,路径为:
out\soong.intermediates\vendor\mediatek\proprietary\packages\apps\MtkSettings\MyCustom1Manager\android_common\combined\MyCustom1Manager.jar

生成后添加到项目中直接实例化调用即可。

最后,使用时可能会遇到selinux权限问题,可以尝试进行如下添加:

+allow mtk_hal_nvramagent protect_f_data_file:dir {search write add_name};
+allow mtk_hal_nvramagent protect_f_data_file:file {create open read write getattr setattr};
+allow mtk_hal_nvramagent sysfs_dt_firmware_android:dir {search};
+allow mtk_hal_nvramagent sysfs_dt_firmware_android:file {read getattr open write};

以上就是nvram数据保存的全部修改,如有不对欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值