活动介绍

什么是updata_engine,它是怎么和sau相互交互完成Android ota升级流程的

时间: 2025-08-10 07:00:03 浏览: 18
<think>我们正在讨论Android OTA升级中的update_engine及其与SAU(System Application Update)的交互机制。根据引用内容,update_engine是Android系统中用于处理系统OTA升级的核心服务,它采用A/B分区设计来保证升级安全。 首先,update_engine是什么? - 它是Android系统中的一个后台服务,负责下载、验证和应用OTA更新包。 - 采用A/B分区方案:设备上有两个系统分区(slot A和slot B),当前运行在其中一个分区(如slot A),升级时会将更新应用到另一个空闲分区(slot B),然后通过重启切换到新分区。 - 优势:升级过程在后台进行,即使失败也不会影响当前运行系统,避免设备变砖。 关于update_engine与SAU的交互机制: 1. **SAU的角色**: - SAU(System Application Update)是系统应用更新的管理模块,负责协调应用更新和系统更新的顺序。 - 在系统OTA升级前,SAU会确保所有挂起的应用更新完成,避免兼容性问题。 2. **交互流程**: ```mermaid sequenceDiagram participant SAU as 系统应用更新(SAU) participant UpdateEngine participant BootControl SAU->>UpdateEngine: 1. 检查系统更新 UpdateEngine->>SAU: 返回更新元数据 SAU->>SAU: 2. 暂停应用更新 SAU->>UpdateEngine: 3. 触发系统更新 UpdateEngine->>BootControl: 4. 写入新分区(slot B) UpdateEngine->>SAU: 5. 通知更新完成 SAU->>SAU: 6. 恢复应用更新 ``` 3. **关键步骤详解**: - **步骤1**:SAU通过`UpdateEngine.checkForUpdate()`接口查询可用更新[^2]。 - **步骤2**:SAU暂停应用更新,防止与系统更新冲突。 - **步骤3**:调用`UpdateEngine.applyPayload()`传递更新包元数据(如URL或文件路径)[^3]。 - **步骤4**:update_engine在后台完成: - 下载更新包(若需网络获取) - 验证签名和分区哈希 - 将数据写入非活动分区(slot B) - 更新分区元数据(通过`BootControl.setActiveBootSlot()`标记下次启动分区)[^3] - **步骤5**:update_engine通过回调通知SAU升级结果(成功/失败)。 - **步骤6**:SAU恢复被暂停的应用更新。 4. **安全机制**: - **权限控制**:update_engine需要特定SELinux策略(如引用[4]中的`update_engine.te`规则)访问分区和文件。 - **回滚保护**:通过`libavb`验证启动分区,防止降级攻击。 5. **特殊场景处理**: - **不切换slot的更新**:如引用[3]所示,可通过`--switch_slot=false`参数实现仅更新分区但不切换活动槽位(用于调试或特殊更新)。 - **虚拟A/B分区**:Android 12+引入的虚拟A/B进一步优化空间效率,update_engine通过`snapuserd`处理快照更新[^1]。 > **性能公式**:更新速度受分区写入速度限制,理论时间$T_{update}$满足: > $$T_{update} = \frac{\text{更新包大小}}{\text{存储写入速度}} + T_{verify}$$ > 其中$T_{verify}$为签名验证时间。 --- §§相关问题§§ 1. update_engine如何处理增量OTA包? 2. 在虚拟A/B分区架构下,update_engine的工作流程有何变化? 3. 如何通过update_engine_client调试升级过程? 4. SAU与update_engine交互时可能产生哪些冲突? 5. 回滚保护机制如何防止系统降级?</think>### Android update_engine 及其与 SAU 的交互机制 #### 一、update_engine 的核心作用 update_engine 是 Android 系统实现**无缝 OTA 升级**的核心后台服务,主要功能包括: 1. **安全升级**:通过 A/B 分区设计防止变砖(引用[2]) - 当前运行系统(如 slot A)时,后台更新另一分区(slot B) - 升级失败时自动回退到原系统 2. **增量更新**:仅下载差异部分(BSDiff 算法) 3. **后台操作**:用户无需进入 Recovery 模式(引用[2]) 4. **验证机制**:检查签名、分区哈希和兼容性 #### 二、update_engine 与 SAU 的交互流程 SAU(System Application Update)是系统级更新协调器,两者协作流程如下: ```mermaid sequenceDiagram participant SAU participant update_engine participant BootControl SAU->>update_engine: 1. 通知新OTA包位置 update_engine->>update_engine: 2. 验证签名/metadata update_engine->>BootControl: 3. 获取分区状态 update_engine->>update_engine: 4. 写入非活动分区(slot B) update_engine->>SAU: 5. 返回进度(0-100%) SAU->>BootControl: 6. 切换活动分区(可选) BootControl->>SAU: 7. 确认下次启动分区 ``` ##### 关键交互环节: 1. **元数据传递**(引用[3]) - SAU 通过 `--metadata` 参数传递更新描述文件路径: ```bash update_engine_client --metadata="/data/ota_package/metadata" ``` - 包含:分区布局、版本号、哈希值等 2. **分区切换控制** - 默认自动切换分区:`--switch_slot=true`(引用[3]) - SAU 可控制是否立即切换: ```java // SAU 伪代码逻辑 if (userImmediateReboot) { engineClient.setSwitchSlot(true); // 下次重启生效 } else { engineClient.setSwitchSlot(false); // 延迟切换 } ``` 3. **权限管理**(引用[4]) - update_engine 需要 SELinux 授权: ```te allow update_engine fuse:file { read open }; // 访问OTA包 allow update_engine mnt_user_file:dir { search }; // 扫描分区 ``` - SAU 通过 `Binder` IPC 与 update_engine 通信 #### 三、核心技术实现 1. **A/B 分区操作** - 通过 `libboot_control` 接口操作分区: ```cpp // BootControl HAL 示例 bool setActiveBootSlot(int slot) { // 更新 bootloader 分区标记 } ``` 2. **增量更新算法** - 应用 BSDiff 生成差异包: $$ \Delta = \text{BSDiff}(\text{old\_image}, \text{new\_image}) $$ - 升级时合并:$ \text{new\_image} = \text{old\_image} \oplus \Delta $ 3. **安全验证链** ```mermaid graph LR A[OTA包签名] --> B[分区哈希验证] B --> C[系统兼容性检查] C --> D[写入前二次校验] ``` #### 四、与传统 Recovery 升级对比 | 特性 | update_engine | Recovery 模式 | |---------------------|-----------------------------|------------------------| | **安全性** | 防变砖机制 | 单分区风险高 | | **用户体验** | 后台无感升级 | 需重启进入特殊界面 | | **效率** | 增量更新(节省70%流量) | 全量更新 | | **技术依赖** | 需要 A/B 分区支持 | 所有设备通用 | > **兼容性说明**:Android 8.0+ 强制要求 A/B 分区,但 update_engine 在 Android 5.0 即开始引入(引用[2])。 ---
阅读全文

相关推荐

/******************************************************************************** ** Copyright (C), 2021-2121, Oplus Mobile Comm Corp., Ltd ** All rights reserved. ** ** File: - OplusNewFeaturesDisplayingManager.java ** Description: ** Implementation of new system features displaying manager. ** ** This service is used to: ** 1. display new system features if Android major version upgraded, e.g. R -> S ** 2. display new policies for lite boot reg requirement if OS version upgraded, ** e.g. OS V12.0 -> OS V12.1, OS V12.1 -> OS V13. See feature 3142150. ** ** Therefore, there are totally 4 cases as below: ** 1. Both Android major version and OS version upgraded: show new system features and ** new policies in boot reg. ** 2. Android major version upgraded only: show new system features. E.g. R+12 -> S+12 ** 3. OS version upgraded only: show new policies. ** 4. Neither of them are upgraded: show nothing, i.e. launch home directly. ** ** Version: 2.0 ** Date: 2022-02-24 ** Author: [email protected] ** TAG: OPLUS_FEATURE_NEW_FEATURES_DISPLAYING_MANAGER ** ** ------------------------------- Revision History: ---------------------------- ** <author> <date> <version> <desc> ** ------------------------------------------------------------------------------ ** [email protected] 2021-07-21 1.0 Create this module ** [email protected] 2022-02-24 2.0 Support lite boot reg requirement ********************************************************************************/ package com.android.server.oplus.nfdm; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import static android.server.pm.OplusPackageTransformHelper.PKG_BOOTREG; import android.app.ActivityManager.RunningAppProcessInfo; import android.app.ActivityManager; import com.android.server.am.ProcessRecord; import android.annotation.NonNull; import android.app.WallpaperInfo; import android.app.WallpaperManager; import android.common.OplusFeatureCache; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.ResolveInfoFlags; import android.content.pm.ResolveInfo; import android.database.ContentObserver; import android.os.Binder; import android.os.Build; import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.os.Parcelable; import android.os.Process; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Slog; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; import android.util.Xml; import com.android.internal.util.XmlUtils; import com.android.server.ServiceThread; import com.android.server.content.IOplusFeatureConfigManagerInternal; import com.android.server.pm.IOplusPackageManagerServiceEx; import com.android.server.pm.IOplusPmsSupportedFunctionManager; import com.android.server.pm.PackageManagerService; import com.android.server.OplusBackgroundThread; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import com.google.android.collect.Sets; import com.oplus.ota.OplusSystemUpdateInfo; import org.json.JSONException; import org.json.JSONObject; public class OplusNewFeaturesDisplayingManager implements IOplusNewFeaturesDisplayingManager { private static final String TAG = "OplusNewFeaturesDisplayingManager"; public static final String PROC_MEMINFO_PATH = "/proc/meminfo"; public static final String LABEL_MEMTOTAL = "MemTotal:"; private static final String OTA_SWITCH_RECORD_FILE_PATH = "/data/oplus/os/ota_switch_record.xml"; private static final String PROP_MARK_LAST_UPGRADED_VERSION = "persist.sys.mark_last_upgraded_version"; private static final String EXTRA_OTA_SWITCH_LIST_FROM_SYSTEM = "extra_ota_switch_list_from_system"; private static final String PROP_OTA_VERSION = "ro.build.version.ota"; private static final List<Integer> DEF_RAM_SIZE = Arrays.asList(2, 3, 4, 6, 8, 12, 16, 18, 24); private static final List<Integer> SUPPORTED_OTA_SWITCH_TARGET_SDKS = Arrays.asList( Build.VERSION_CODES.S, Build.VERSION_CODES.TIRAMISU, Build.VERSION_CODES.UPSIDE_DOWN_CAKE ); private static final long MB_IN_KB = 1024L; private static final long GB_IN_KB = MB_IN_KB * 1024L; private static final int EIGHT_GB = 8; private static int sTotalProcMemInfoGB = -1; private static int sTotalProcMemInfoKB = -1; private static final String FEATURE_TABLET = "oplus.hardware.type.tablet"; private static final String FEATURE_SCREEN_FOLDABLE = "oplus.hardware.type.fold"; private static final String FEATURE_FOLD_REMAP_DISPLAY_DISABLED = "oplus.software.fold_remap_display_disabled"; private static final List<Integer> SUPPORTED_TARGET_SDKS = Arrays.asList( Build.VERSION_CODES.S, Build.VERSION_CODES.TIRAMISU, Build.VERSION_CODES.UPSIDE_DOWN_CAKE, Build.VERSION_CODES.VANILLA_ICE_CREAM, Build.VERSION_CODES.BAKLAVA ); private static final List<Integer> SUPPORTED_WALLPAPER_TARGET_SDKS = Arrays.asList( Build.VERSION_CODES.VANILLA_ICE_CREAM ); private static final Set<String> NOT_MARKET_LIVE_WALLPAPER = Sets.newHashSet( "default_live_wp_package_name" ); private static final String PKG_NAME_BOOT_REG = PKG_BOOTREG; private static final String ACTION_WELCOME_PAGE = "com.oplus.bootreg.activity.WelcomePage"; private static final String PKG_NAME_WALLPAPER = "com.oplus.wallpapers"; private static final String ACTION_WALLPAPER_GUIDE_PAGE = "android.intent.action.THEME_INSPIRATION_BOOT"; private static final String PKG_NAME_UPGRADE_GUIDE = "com.oplus.upgradeguide"; private static final String ACTION_UPGRADE_SERVICE = "oplus.intent.upgrade.UNZIP_RESOURCE"; private static final String EXTRA_START_FROM_SYSTEM = "extra_start_from_system"; private static final String PKG_NAME_OPPO_DEFAULT_LAUNCHER = "com.android.launcher"; private static final String LAUNCHER_ACTION = "android.intent.action.MAIN"; private static final String LAUNCHER_CATEGORY = "android.intent.category.HOME"; private static final long THIRD_FLAG = 0x01; private static final int CUSTOM_THEME_FLAG = 0x100; private static final String CLS_NAME_OTA_GUIDE_PAGE = "com.oplus.upgrade.ota.ui.OtaGuidePage"; private static final String PROP_RO_SEPARATE_SOFT = "ro.separate.soft"; /** * @deprecated * Use action intent filter instead, see {@link #getBootRegWelcomePageComponentName()} */ private static final String CLS_NAME_WELCOME_PAGE = PKG_BOOTREG.concat(".settings.activity.WelcomePage"); private static final ComponentName COMPONENT_WELCOME_PAGE = new ComponentName(PKG_NAME_BOOT_REG, CLS_NAME_WELCOME_PAGE); /** * Deprecated for what's new 2.0 requirement. */ private static final String CLS_NAME_NEW_FEATURE_PAGE = PKG_NAME_BOOT_REG.concat(".activity.NewFeaturePage"); private static final ComponentName COMPONENT_NEW_FEATURE_PAGE = new ComponentName( PKG_NAME_BOOT_REG, CLS_NAME_NEW_FEATURE_PAGE); private static final String EXTRA_MAJOR_VERSION_UPGRADED = "extra_major_version_upgraded"; private static final String EXTRA_MAJOR_WALLPAPER_CHANGED = "extra_major_wallpaper_changed"; private static final String PROP_FORCE_TO_DISPLAY_NEW_FEATURES = "persist.sys.force_to_display_new_features"; private static final String PROP_MARK_TO_DISPLAY_NEW_FEATURES = "persist.sys.mark_to_display_new_features"; private static final String EXTRA_OS_VERSION_UPGRADED = "extra_os_version_upgraded"; private static final String PROP_FORCE_TO_DISPLAY_NEW_POLICIES = "persist.sys.force_to_display_new_policies"; private static final String PROP_MARK_TO_DISPLAY_NEW_POLICIES = "persist.sys.mark_to_display_new_policies"; private static final String PROP_FORCE_TO_DISPLAY_BOOTREG = "persist.sys.force_to_display_bootreg"; private static final String PROP_FORCE_TO_CHANGE_WALLPAPER = "persist.sys.force_to_change_wallpaper"; private static final String OS_VERSION_INFO_FILE_PATH = "/data/oplus/os/os_version_info.xml"; private static final String PROP_CUR_OS_VERSION = "ro.build.version.oplusrom"; private static final String PROP_STOCK_TYPE = "ro.oplus.image.my_stock.type"; private static final String PROP_CARRRIER = "ro.oplus.pipeline.carrier"; private static final String PROP_THEME_UUID = "persist.sys.oppo.theme_uuid"; private static final String PROP_COMPANY_TYPE = "ro.oplus.image.my_company.type"; private static final String PROP_CHANNEL = "persist.sys.channel.info"; private static final String DELIMITER = "_"; private static final String KEY_OPLUS_CUSTOMIZE_OTA_GUIDE_STEP = "oplus_upgrade_ota_step"; private static final String TAG_OS_VERSION = "os-version"; private static final String TAG_PREV_OS_VERSION = "prev-os-version"; private static final String ATTR_VALUE = "value"; private static final int S_OS_VERSION_LENGTH = 2; private static final int T_OS_VERSION_LENGTH = 3; private static final int MSG_WSN_WRITEOS = 120; private static final int MSG_WSN_EXCEPTION_NEWFEATURE = 121; private static final int MSG_WSN_STARTHOME = 122; private static final int DELAY_EXCEPTION_NEWFEATURE_SENDING_MSEC = 5000; private static final int MSG_DELAY_TO_CHECK_IF_OTA_GUIDE_ABNORMAL = 123; private static final int MSG_DELAY_TO_CHECK_STATUS_WHEN_OTA_GUIDE_EXIT = 124; private static final int DELAY_EXCEPTION_OTA_GUIDE_MSEC = 30000; private static final int DELAY_CHECK_IF_OTA_GUIDE_NORMAL_EXIT_MSEC = 2000; private static final int VALUE_OTA_GUIDE_DEFAULT = -1; private static final int VALUE_OTA_GUIDE_OVERTIME_WAIT = 0; private static final int VALUE_OTA_GUIDE_ENTER = 1; private static final int VALUE_OTA_GUIDE_EXIT = 2; private static final int TYPE_SAU_UPDATE = 2; private static final String PROP_OPLUS_CLOSE_OTA_GUIDE_PAGE = "persist.sys.oplus_close_ota_guide"; private ComponentName mComponentOtaGuidePage = null; private ContentObserver mOtaGuideContentObserver = null; private ComponentName mComponentNameWelcomePage = null; private ComponentName mComponentNameWallPaperGuidPage = null; private boolean mInitializedSuccessfully; private Context mContext; private PackageManagerService mPms; private Handler mHandler; private RunningAppProcessInfo mWsnInfo = null; private String mStockType; private boolean mIsDomesticBuild; private boolean mIsBrandSupported; private boolean mIsDeviceTablet; private boolean mIsScreenFoldable; private boolean mIsFlipDevice; private boolean mIsFirstBoot; private boolean mOtaUpgraded; private boolean mIsBootFromOTA; private int mPrevSdkVersion; private int mCurSdkVersion; private boolean mMajorVersionUpgraded; private String mProjectNumber; private List<OtaGuideBean> mOtaGuideBeans; private String mPrevOsVersion; private String mCurOsVersion; private boolean mOsVersionUpgraded; private boolean mTopIsWsn; private boolean mTopIsLauncher; private boolean mPictorialAuto; private boolean mKeKeMarketTheme; private boolean mChangeWallPaper; private boolean mIsNeedDisplayWallpaper; private boolean mIsNeedDisplaySwitchPage; private boolean mDebug = SystemProperties.getBoolean("persist.sys.assert.panic", false); private static final class InstanceHolder { private static final OplusNewFeaturesDisplayingManager INSTANCE = new OplusNewFeaturesDisplayingManager(); } public static OplusNewFeaturesDisplayingManager getInstance() { return OplusNewFeaturesDisplayingManager.InstanceHolder.INSTANCE; } private OplusNewFeaturesDisplayingManager() { // hidden constructor } @Override public void init(IOplusPackageManagerServiceEx pmsEx) { if (pmsEx == null || pmsEx.getPackageManagerService() == null) { Slog.e(TAG, "Init failed due to null pms reference"); return; } mContext = pmsEx.getContext(); mPms = pmsEx.getPackageManagerService(); mInitializedSuccessfully = true; mTopIsWsn = false ; mTopIsLauncher = false ; mIsNeedDisplayWallpaper = false; mIsNeedDisplaySwitchPage = false; initBuildTypes(); readPrevOsVersionFromXml(); mCurOsVersion = SystemProperties.get(PROP_CUR_OS_VERSION, ""); Slog.i(TAG, "prevOsVersion=" + mPrevOsVersion + ", curOsVersion=" + mCurOsVersion); HandlerThread thread = new ServiceThread(TAG, Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); thread.start(); mHandler = new Handler(thread.getLooper()) { @Override public void handleMessage(@NonNull Message msg) { switch (msg.what) { case MSG_WSN_WRITEOS: writeOsVersionToXmlSync(); break ; case MSG_WSN_EXCEPTION_NEWFEATURE: if (!mTopIsWsn) { Slog.i(TAG, "upgradeguide can not start so direct go to home"); startHome(); ActivityManager am = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); am.killBackgroundProcesses(PKG_NAME_UPGRADE_GUIDE); } break ; case MSG_WSN_STARTHOME: startHome(); break ; case MSG_DELAY_TO_CHECK_IF_OTA_GUIDE_ABNORMAL: ContentResolver resolver = mContext.getContentResolver(); int otaGuideStatusFlag = Settings.System.getInt(resolver, KEY_OPLUS_CUSTOMIZE_OTA_GUIDE_STEP, VALUE_OTA_GUIDE_DEFAULT); Slog.d(TAG, "ota guide page launch timeout! otaGuideStatusFlag = " + otaGuideStatusFlag); if ((otaGuideStatusFlag == VALUE_OTA_GUIDE_DEFAULT) || (otaGuideStatusFlag == VALUE_OTA_GUIDE_OVERTIME_WAIT)) { dealOtaGuideException(); } break; case MSG_DELAY_TO_CHECK_STATUS_WHEN_OTA_GUIDE_EXIT: Slog.d(TAG, "ota guide exit! "); if (isOtaGuidePageEnable()) { disableOtaGuidePage(); } if (mOtaGuideContentObserver != null) { mContext.getContentResolver().unregisterContentObserver(mOtaGuideContentObserver); } break; default: break ; } } }; } private void initBuildTypes() { mStockType = SystemProperties.get(PROP_STOCK_TYPE); if (isValidStockType(mStockType)) { final String[] typeArr = mStockType.split(DELIMITER); final String region = typeArr[0]; mIsDomesticBuild = "domestic".equalsIgnoreCase(region); final String brand = typeArr[1]; mIsBrandSupported = ("OPPO".equalsIgnoreCase(brand) || "OnePlus".equalsIgnoreCase(brand)); } } private boolean isValidStockType(String type) { final String regex = "^[A-Za-z]+_[A-Za-z]+$"; return (type != null) && (type.matches(regex)); } private void readPrevOsVersionFromXml() { final File file = new File(OS_VERSION_INFO_FILE_PATH); if (!file.exists() || !file.canRead()) { Slog.w(TAG, "Os version info file doesn't exist or can't read"); return; } try (FileInputStream str = new FileInputStream(file)) { final TypedXmlPullParser parser = Xml.resolvePullParser(str); int type; while (((type = parser.next()) != XmlPullParser.START_TAG) && (type != XmlPullParser.END_DOCUMENT)) { ; } if (type != XmlPullParser.START_TAG) { Slog.wtf(TAG, "No start tag found in os version info file"); return; } if (!parser.getName().equals(TAG_OS_VERSION)) { throw new XmlPullParserException("Unexpected start tag in " + file + ": found " + parser.getName() + ", expected 'os_version'"); } int outerDepth = parser.getDepth(); while (((type = parser.next()) != XmlPullParser.END_DOCUMENT) && ((type != XmlPullParser.END_TAG) || (parser.getDepth() > outerDepth))) { if ((type == XmlPullParser.END_TAG) || (type == XmlPullParser.TEXT)) { continue; } String tagName = parser.getName(); if (tagName.equals(TAG_PREV_OS_VERSION)) { mPrevOsVersion = parser.getAttributeValue(null, ATTR_VALUE); } else { Slog.w(TAG, "Unknown element: " + tagName); XmlUtils.skipCurrentTag(parser); } } } catch (IOException | XmlPullParserException e) { Slog.e(TAG, "Error reading os version info file: " + e.toString()); } } private void writeOsVersionToXmlAsync() { Message message = mHandler.obtainMessage(); message.what = MSG_WSN_WRITEOS; mHandler.sendMessage(message); } private void writeOsVersionToXmlSync() { final File file = new File(OS_VERSION_INFO_FILE_PATH); if (file.exists()) { Slog.i(TAG, "Os version info file already exists, replacing..."); file.delete(); } try (FileOutputStream str = new FileOutputStream(file)) { final TypedXmlSerializer serializer = Xml.resolveSerializer(str); serializer.startDocument(null, true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); serializer.startTag(null, TAG_OS_VERSION); // previous os version info serializer.startTag(null, TAG_PREV_OS_VERSION); serializer.attribute(null, ATTR_VALUE, mCurOsVersion); serializer.endTag(null, TAG_PREV_OS_VERSION); serializer.endTag(null, TAG_OS_VERSION); serializer.endDocument(); str.flush(); FileUtils.sync(str); FileUtils.setPermissions(file.toString(), // rw-rw---- FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); } catch (IOException e) { Slog.e(TAG, "Error writing os version info file: " + e.toString()); } } private boolean isOsVersionUpgraded() { String prevOsVersion = mPrevOsVersion; String curOsVersion = mCurOsVersion; if (isValidOsVersion(prevOsVersion) && isValidOsVersion(curOsVersion)) { if (prevOsVersion.indexOf(".") == -1) { prevOsVersion = prevOsVersion.concat(".0"); } if (curOsVersion.indexOf(".") == -1) { curOsVersion = curOsVersion.concat(".0"); } try { prevOsVersion = prevOsVersion.substring(1); curOsVersion = curOsVersion.substring(1); String[] prevOsVersionArr = prevOsVersion.split("\\."); String[] curOsVersionArr = curOsVersion.split("\\."); if (((prevOsVersionArr.length == S_OS_VERSION_LENGTH) || (prevOsVersionArr.length == T_OS_VERSION_LENGTH)) && (curOsVersionArr.length == T_OS_VERSION_LENGTH)) { final int prevOsVersionMajor = Integer.parseInt(prevOsVersionArr[0]); final int curOsVersionMajor = Integer.parseInt(curOsVersionArr[0]); if (curOsVersionMajor > prevOsVersionMajor) { return true; } else if (curOsVersionMajor == prevOsVersionMajor) { final int prevOsVersionMinor = Integer.parseInt(prevOsVersionArr[1]); final int curOsVersionMinor = Integer.parseInt(curOsVersionArr[1]); if (curOsVersionMinor > prevOsVersionMinor) { return true; } } } } catch (Exception e) { Slog.e(TAG, "Error parsing os version: " + e.toString()); return false; } } return false; } private boolean isValidOsVersion(String osVersion) { final String regex = "^V\\d+(\\.\\d+)?$"; final String regexForT = "^V\\d+(\\.\\d+\\.\\d+)?$"; return (osVersion != null) && ((osVersion.matches(regex)) || (osVersion.matches(regexForT))); } @Override public void setValues(boolean isFirstBoot, boolean isUpgrade, boolean isBootFromOTA, int curSdkVersion, int lastSdkVersion) { /* * isUpgrade is true when: 1. Fingerprint changes;2. COTA upgrade;3. OTA upgrade (including sau system upgrade);4. opex-apk upgrade; * isBootFromOTA is true: only when OTA upgrade (including sau system upgrade) */ Slog.d(TAG, String.format("firstBoot=%s, upgrade=%s, isBootFromOTA=%s, curSdkVersion=%s, lastSdkVersion=%s", isFirstBoot, isUpgrade, isBootFromOTA, curSdkVersion, lastSdkVersion)); mIsFirstBoot = isFirstBoot; mOtaUpgraded = isUpgrade; mIsBootFromOTA = isBootFromOTA; mPrevSdkVersion = lastSdkVersion; mCurSdkVersion = curSdkVersion; mMajorVersionUpgraded = isUpgrade && lastSdkVersion < curSdkVersion && SUPPORTED_TARGET_SDKS.contains(curSdkVersion); mOsVersionUpgraded = isUpgrade && isOsVersionUpgraded(); mProjectNumber = SystemProperties.get(PROP_RO_SEPARATE_SOFT, ""); } @Override public void enableBootRegIfNeededForDisplayingNewFeatures() { if (!mInitializedSuccessfully) { Slog.w(TAG, "Failed to initialize, skip to enable boot reg"); return; } mIsDeviceTablet = hasOplusFeature(FEATURE_TABLET); mIsScreenFoldable = hasOplusFeature(FEATURE_SCREEN_FOLDABLE); mIsFlipDevice = hasOplusFeature(FEATURE_FOLD_REMAP_DISPLAY_DISABLED); mComponentNameWelcomePage = getBootRegWelcomePageComponentName(); mComponentNameWallPaperGuidPage = getWallPaperGuidComponentName(); Slog.i(TAG, "welcomePage=" + mComponentNameWelcomePage + " mComponentNameWallPaperPage=" + mComponentNameWallPaperGuidPage); final boolean newFeaturesDisplayingEnabled = mIsDomesticBuild && mIsBrandSupported; final boolean forcedToDisplayNewFeatures = SystemProperties.getBoolean(PROP_FORCE_TO_DISPLAY_NEW_FEATURES, false); final boolean newPoliciesDisplayingEnabled = mIsDomesticBuild; final boolean forcedToDisplayNewPolicies = SystemProperties.getBoolean(PROP_FORCE_TO_DISPLAY_NEW_POLICIES, false); final boolean forcedToDisplayBootReg = SystemProperties.getBoolean(PROP_FORCE_TO_DISPLAY_BOOTREG, false); final boolean doesBootRegWelcomePageExist = mComponentNameWelcomePage != null; Slog.d(TAG, "deviceTablet=" + mIsDeviceTablet + ", screenFoldable=" + mIsScreenFoldable + ", flipDevice=" + mIsFlipDevice + ", newFeaturesDisplayingEnabled=" + newFeaturesDisplayingEnabled + ", majorVersionUpgraded=" + mMajorVersionUpgraded + ", forcedToDisplayNewFeatures=" + forcedToDisplayNewFeatures + ", newPoliciesDisplayingEnabled=" + newPoliciesDisplayingEnabled + ", osVersionUpgraded=" + mOsVersionUpgraded + ", forcedToDisplayNewPolicies=" + forcedToDisplayNewPolicies + ", welcomePageExist=" + doesBootRegWelcomePageExist); final boolean shouldDisplayNewFeatures = forcedToDisplayNewFeatures || (newFeaturesDisplayingEnabled && mMajorVersionUpgraded); final boolean shouldDisplayNewPolicies = forcedToDisplayNewPolicies || (newPoliciesDisplayingEnabled && mOsVersionUpgraded); if ((shouldDisplayNewFeatures || shouldDisplayNewPolicies || forcedToDisplayBootReg) && doesBootRegWelcomePageExist) { int oldState = mContext.getPackageManager().getComponentEnabledSetting(mComponentNameWelcomePage); Slog.d(TAG, "Old state of " + mComponentNameWelcomePage + " is " + parseComponentState(oldState)); //When the user disables the boot wizard, the WSN will not be available, so no longer configured try { boolean isEnabled = mContext.getPackageManager().getPackageInfo(PKG_NAME_BOOT_REG, 0).applicationInfo.enabled; if (!isEnabled) { return; } } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "get bootreg applicationInfo enabled state fail ", e); } if (shouldDisplayNewFeatures) { // Marked that we should display new features later SystemProperties.set(PROP_MARK_TO_DISPLAY_NEW_FEATURES, String.valueOf(true)); } if (shouldDisplayNewPolicies) { // Marked that we should display new policies later SystemProperties.set(PROP_MARK_TO_DISPLAY_NEW_POLICIES, String.valueOf(true)); } if (!((oldState == COMPONENT_ENABLED_STATE_DEFAULT) || (oldState == COMPONENT_ENABLED_STATE_ENABLED))) { Slog.i(TAG, "Enable boot reg again"); mContext.getPackageManager().setComponentEnabledSetting(mComponentNameWelcomePage, COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */); Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_SYSTEM); } } else { displayOtaGuidePageIfNeed(); } final ContentResolver resolver = mContext.getContentResolver(); ContentObserver co = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { final boolean userSystemSetupComplete = Settings.Secure.getIntForUser(resolver, Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_SYSTEM) == 1; Slog.d(TAG, "userSystemSetupComplete=" + userSystemSetupComplete); if (userSystemSetupComplete) { // Reset props if user system setup completed SystemProperties.set(PROP_FORCE_TO_DISPLAY_NEW_FEATURES, String.valueOf(false)); SystemProperties.set(PROP_MARK_TO_DISPLAY_NEW_FEATURES, String.valueOf(false)); SystemProperties.set(PROP_FORCE_TO_DISPLAY_NEW_POLICIES, String.valueOf(false)); SystemProperties.set(PROP_MARK_TO_DISPLAY_NEW_POLICIES, String.valueOf(false)); SystemProperties.set(PROP_FORCE_TO_DISPLAY_BOOTREG, String.valueOf(false)); if ((shouldDisplayNewFeatures || shouldDisplayNewPolicies) && !mTopIsLauncher) { Message message = mHandler.obtainMessage(); message.what = MSG_WSN_EXCEPTION_NEWFEATURE; mHandler.sendMessageDelayed(message,DELAY_EXCEPTION_NEWFEATURE_SENDING_MSEC); } // Write back new os version. writeOsVersionToXmlAsync(); if (mIsBootFromOTA) { String otaVersion = SystemProperties.get(PROP_OTA_VERSION, ""); SystemProperties.set(PROP_MARK_LAST_UPGRADED_VERSION, otaVersion); } } } }; mContext.getContentResolver().registerContentObserver(Settings.Secure .getUriFor( Settings.Secure.USER_SETUP_COMPLETE), false, co, UserHandle.USER_SYSTEM); co.onChange(true); } private boolean isNeedDisplayOtaGuide() { mIsNeedDisplayWallpaper = isNeedDisplayWallpaper(); mIsNeedDisplaySwitchPage = isNeedDisplaySwitchPage(); return mIsNeedDisplayWallpaper || mIsNeedDisplaySwitchPage; } private boolean isNeedDisplaySwitchPage() { if (!SUPPORTED_OTA_SWITCH_TARGET_SDKS.contains(mCurSdkVersion)) { Slog.w(TAG, "isNeedDisplaySwitchPage: current sdk not support ota switch, no need to go on"); return false; } if (!mIsBootFromOTA) { Slog.w(TAG, "isNeedDisplaySwitchPage: current boot is not boot from ota, just normal boot, no need to go on"); return false; } if (mIsDomesticBuild) { Slog.w(TAG, "isNeedDisplaySwitchPage: current boot is domestic build, no need to go on"); return false; } if (isSauSystemUpdate()) { Slog.w(TAG, "isNeedDisplaySwitchPage: current update is SAU system update, no need to go on"); return false; } if (mOsVersionUpgraded || mMajorVersionUpgraded) { Slog.d(TAG, "isNeedDisplaySwitchPage: is osUpgrade or magorUpgrade, no need to go on"); return false; } if (isUpgradeFailed()) { Slog.d(TAG, "isNeedDisplaySwitchPage: is isUpgradeFailed, no need to go on"); return false; } mOtaGuideBeans = OtaLogicManager.getOtaApplications(mContext); if (mOtaGuideBeans == null || mOtaGuideBeans.isEmpty()) { Slog.d(TAG, "no application need start OtaGuidePage."); return false; } return true; } private boolean isNeedDisplayWallpaper() { if (!SUPPORTED_WALLPAPER_TARGET_SDKS.contains(mCurSdkVersion)) { Slog.w(TAG, "isNeedDisplayWallpaper: current sdk not support wallpager change, no need to go on"); return false; } if (!mIsBootFromOTA) { Slog.w(TAG, "isNeedDisplayWallpaper: current boot is not boot from ota, just normal boot, no need to go on"); return false; } if (mIsDeviceTablet || mIsScreenFoldable) { return false; } if (isMemoryForbid()) { Slog.w(TAG, "isNeedDisplayWallpaper: current memInfo is less than 8G, no need to go on"); return false; } if (mComponentNameWallPaperGuidPage == null) { Slog.w(TAG, "isNeedDisplayWallpaper: mComponentNameWallPaperGuidPage is null, no need to go on"); return false; } if (!mMajorVersionUpgraded && SystemProperties.getBoolean(PROP_FORCE_TO_CHANGE_WALLPAPER, true)) { Slog.w(TAG, "isNeedDisplayWallpaper: current boot is not mMajorVersionUpgraded, no need to go on"); return false; } mPictorialAuto = Settings.System.getInt(mContext.getContentResolver(), "oplus_customize_pictorial_auto_play", 0) == 1; boolean isTheme = (mPictorialAuto || isThirdTheme(0) || checkMarketTheme()); boolean needDisplayWallpaper = !(isTheme || isCarrrierOrChannal() || checkCompanyType()); if (!needDisplayWallpaper) { Slog.w(TAG, "isNeedDisplayWallpaper: no needDisplayWallpaper, no need to go on"); return false; } if (mIsDomesticBuild) { Slog.w(TAG, "isNeedDisplayWallpaper: current boot is domestic build, no need to go on"); return false; } if (isSauSystemUpdate()) { Slog.w(TAG, "isNeedDisplayWallpaper: current update is SAU system update, no need to go on"); return false; } return true; } private void displayOtaGuidePageIfNeed () { if (SystemProperties.getBoolean(PROP_OPLUS_CLOSE_OTA_GUIDE_PAGE, false)) { Slog.w(TAG, "otaGuidePage has been closed!!!, no need to go on"); return; } mComponentOtaGuidePage = getOtaGuideComponentName(); if (mComponentOtaGuidePage == null) { Slog.i(TAG, "the component: " + CLS_NAME_OTA_GUIDE_PAGE + " is not exit, do not need to go on, return"); return; } try { boolean isEnabled = mContext.getPackageManager().getPackageInfo(PKG_NAME_UPGRADE_GUIDE, 0).applicationInfo.enabled; if (!isEnabled) { Slog.w(TAG, "get upgradeguide applicationInfo is not enable, return"); disableOtaGuidePage(); return; } } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "get UpgradeGuide applicationInfo enabled state fail name not found,return"); return; } if (isOtaGuidePageEnable()) { Slog.i(TAG, "the component: " + CLS_NAME_OTA_GUIDE_PAGE + " is enable, so disable it first"); disableOtaGuidePage(); } if (!isNeedDisplayOtaGuide()) { return; } enableOtaGuidePage(); } private void enableOtaGuidePage () { Slog.d(TAG, "enableOtaGuidePage now!!!"); final ContentResolver resolver = mContext.getContentResolver(); long id = Binder.clearCallingIdentity(); try { Settings.System.putInt(resolver, KEY_OPLUS_CUSTOMIZE_OTA_GUIDE_STEP, VALUE_OTA_GUIDE_OVERTIME_WAIT); mContext.getPackageManager().setComponentEnabledSetting(mComponentOtaGuidePage, COMPONENT_ENABLED_STATE_ENABLED, 0 /* flags */); } catch (IllegalArgumentException e) { Slog.e(TAG, "get IllegalArgumentException, so return"); return; } finally { Binder.restoreCallingIdentity(id); } mHandler.sendEmptyMessageDelayed(MSG_DELAY_TO_CHECK_IF_OTA_GUIDE_ABNORMAL, DELAY_EXCEPTION_OTA_GUIDE_MSEC); mOtaGuideContentObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { int otaGuideStatusFlag = Settings.System.getInt(resolver, KEY_OPLUS_CUSTOMIZE_OTA_GUIDE_STEP, VALUE_OTA_GUIDE_DEFAULT); if (otaGuideStatusFlag == VALUE_OTA_GUIDE_ENTER) { Slog.i(TAG, "the otaGuide StatusFlag is 1, enter normal"); if (mHandler.hasMessages(MSG_DELAY_TO_CHECK_IF_OTA_GUIDE_ABNORMAL)) { mHandler.removeMessages(MSG_DELAY_TO_CHECK_IF_OTA_GUIDE_ABNORMAL); } } else if (otaGuideStatusFlag == VALUE_OTA_GUIDE_EXIT) { Slog.i(TAG, "the otaGuide StatusFlag is 2, exit normal, so unregister Observer"); mHandler.sendEmptyMessageDelayed(MSG_DELAY_TO_CHECK_STATUS_WHEN_OTA_GUIDE_EXIT, DELAY_CHECK_IF_OTA_GUIDE_NORMAL_EXIT_MSEC); } } }; mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor(KEY_OPLUS_CUSTOMIZE_OTA_GUIDE_STEP), false, mOtaGuideContentObserver, UserHandle.USER_SYSTEM); } private ComponentName getOtaGuideComponentName() { final Intent intent = new Intent(); intent.setClassName(PKG_NAME_UPGRADE_GUIDE, CLS_NAME_OTA_GUIDE_PAGE); final ResolveInfoFlags flags = ResolveInfoFlags.of(PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DISABLED_COMPONENTS); final ResolveInfo ri = mContext.getPackageManager().resolveActivityAsUser(intent, flags, UserHandle.USER_SYSTEM); if ((ri != null) && (ri.activityInfo != null)) { return new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name); } Slog.w(TAG,"get ota GuidePage activity null "); return null; } private boolean isOtaGuidePageEnable() { int componentState = mContext.getPackageManager().getComponentEnabledSetting(getOtaGuideComponentName()); Slog.i(TAG, "componentState state of " + getOtaGuideComponentName() + " is " + parseComponentState(componentState)); return componentState == COMPONENT_ENABLED_STATE_ENABLED; } private void disableOtaGuidePage() { long id = Binder.clearCallingIdentity(); try { Slog.i(TAG, "start to disable mComponentOtaGuidePage"); mContext.getPackageManager().setComponentEnabledSetting(getOtaGuideComponentName(), COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP /* flags */); } catch (IllegalArgumentException e) { Slog.e(TAG, "setComponentEnabledSetting disable mComponentOtaGuidePage get IllegalArgumentException"); } finally { Binder.restoreCallingIdentity(id); } } private void dealOtaGuideException() { Slog.i(TAG, "dealOtaGuideException, disable ota guide and start home."); if (isOtaGuidePageEnable()) { disableOtaGuidePage(); } if (!mTopIsLauncher) { Slog.i(TAG, "current top is not launcher, so start launcher"); startHome(); } if (mOtaGuideContentObserver != null) { mContext.getContentResolver().unregisterContentObserver(mOtaGuideContentObserver); } Settings.System.putInt(mContext.getContentResolver(), KEY_OPLUS_CUSTOMIZE_OTA_GUIDE_STEP, VALUE_OTA_GUIDE_EXIT); } private boolean isSauSystemUpdate() { OplusSystemUpdateInfo oplusSystemUpdateInfo = OplusFeatureCache.get(IOplusPmsSupportedFunctionManager.DEFAULT).getSystemUpdateInfo(); if ((oplusSystemUpdateInfo != null) && oplusSystemUpdateInfo.getUpdateType() == TYPE_SAU_UPDATE) { return true; } else { return false; } } private boolean isUpgradeFailed() { String currOtaVersion = SystemProperties.get(PROP_OTA_VERSION, ""); String lastUpgradedVersion = SystemProperties.get(PROP_MARK_LAST_UPGRADED_VERSION, ""); if (!TextUtils.isEmpty(currOtaVersion) && !TextUtils.isEmpty(lastUpgradedVersion)) { if (currOtaVersion.equals(lastUpgradedVersion)) { return true; } } return false; } @Override public void putExtraIfNeededForDisplayingNewFeatures(String reason, Intent homeIntent, int userId) { if (!mInitializedSuccessfully) { Slog.w(TAG, "Failed to initialize, skip to put extra into intent"); return; } // Start upgrade service if first boot for new features displaying. final boolean newFeaturesDisplayingEnabled = mIsDomesticBuild && mIsBrandSupported; final boolean forcedToDisplayNewFeatures = SystemProperties.getBoolean(PROP_FORCE_TO_DISPLAY_NEW_FEATURES, false); final boolean shouldDisplayNewFeatures = forcedToDisplayNewFeatures || newFeaturesDisplayingEnabled; final boolean doesBootRegWelcomePageExist = mComponentNameWelcomePage != null; if ("systemReady".equals(reason) && shouldDisplayNewFeatures && mIsFirstBoot && doesBootRegWelcomePageExist) { startUpgradeGuide("first boot"); } final boolean markedToDisplayNewFeatures = SystemProperties.getBoolean(PROP_MARK_TO_DISPLAY_NEW_FEATURES, false); final boolean markedToDisplayNewPolicies = SystemProperties.getBoolean(PROP_MARK_TO_DISPLAY_NEW_POLICIES, false); Slog.d(TAG, "markedToDisplayNewFeatures=" + markedToDisplayNewFeatures + ", markedToDisplayNewPolicies=" + markedToDisplayNewPolicies + ", welcomePageExists=" + doesBootRegWelcomePageExist); if ((markedToDisplayNewFeatures || markedToDisplayNewPolicies) && doesBootRegWelcomePageExist) { Slog.d(TAG, String.format("reason=%s, component=%s, user=%s", reason, homeIntent.getComponent(), userId)); mPictorialAuto = Settings.System.getInt(mContext.getContentResolver(), "oplus_customize_pictorial_auto_play", 0) == 1; mChangeWallPaper = !(isMemoryForbid() || mPictorialAuto || isThirdTheme(userId) || isCarrrierOrChannal() || checkMarketTheme() || checkCompanyType()); if (("systemReady".equals(reason) || "noMoreActivities resumeHomeActivity".equals(reason)) && homeIntent.getComponent() != null && PKG_NAME_BOOT_REG.equals(homeIntent.getComponent().getPackageName()) && (userId == UserHandle.USER_SYSTEM)) { if (markedToDisplayNewFeatures) { Slog.i(TAG, "Put extra sdk version '" + mCurSdkVersion + "' into home intent doesChangeWallPaper :" + mChangeWallPaper); if (mComponentNameWallPaperGuidPage != null && SUPPORTED_WALLPAPER_TARGET_SDKS.contains(mCurSdkVersion) && (!(mIsDeviceTablet || mIsScreenFoldable))) { homeIntent.putExtra(EXTRA_MAJOR_WALLPAPER_CHANGED, mChangeWallPaper); } homeIntent.putExtra(EXTRA_MAJOR_VERSION_UPGRADED, mCurSdkVersion); // Start upgrade service if re-launching boot reg. startUpgradeGuide("relaunching boot reg"); } if (markedToDisplayNewPolicies) { homeIntent.putExtra(EXTRA_OS_VERSION_UPGRADED, mCurOsVersion); } } } else if (homeIntent.getComponent() != null && PKG_NAME_UPGRADE_GUIDE.equals(homeIntent.getComponent().getPackageName()) && (userId == UserHandle.USER_SYSTEM)) { if (mIsNeedDisplayWallpaper) { Slog.i(TAG, "Put extra_major_wallpaper_changed into home intent"); homeIntent.putExtra("extra_major_wallpaper_changed", String.valueOf(mCurSdkVersion)); } if (mIsNeedDisplaySwitchPage) { if ((mOtaGuideBeans != null) && (mOtaGuideBeans.size() != 0)) { Slog.i(TAG, "Put extra_ota_switch_list_from_system " + mOtaGuideBeans.toString() + " into home intent"); homeIntent.putParcelableArrayListExtra(EXTRA_OTA_SWITCH_LIST_FROM_SYSTEM, (ArrayList<? extends Parcelable>) mOtaGuideBeans); OtaLogicManager.saveSwitchRecordList(mOtaGuideBeans); } } } else { if (isOtaGuidePageEnable()) { disableOtaGuidePage(); } } } @Override public void handleProcessDied(ProcessRecord app) { final boolean markedToDisplayNewFeatures = SystemProperties.getBoolean(PROP_MARK_TO_DISPLAY_NEW_FEATURES, false); final boolean markedToDisplayNewPolicies = SystemProperties.getBoolean(PROP_MARK_TO_DISPLAY_NEW_POLICIES, false); String pkgName = app.info.packageName; if (markedToDisplayNewFeatures || markedToDisplayNewPolicies) { if (PKG_NAME_UPGRADE_GUIDE.equalsIgnoreCase(pkgName) && mTopIsWsn) { Slog.i(TAG, "upgradeguide crash so direct go to home"); Message message = mHandler.obtainMessage(); message.what = MSG_WSN_STARTHOME; mHandler.sendMessage(message); } } ContentResolver resolver = mContext.getContentResolver(); int otaGuideStatusFlag = Settings.System.getInt(resolver, KEY_OPLUS_CUSTOMIZE_OTA_GUIDE_STEP, VALUE_OTA_GUIDE_DEFAULT); if (PKG_NAME_UPGRADE_GUIDE.equalsIgnoreCase(pkgName) && PKG_NAME_UPGRADE_GUIDE.equalsIgnoreCase(app.info.processName)) { if ((otaGuideStatusFlag == VALUE_OTA_GUIDE_ENTER) || (otaGuideStatusFlag == VALUE_OTA_GUIDE_OVERTIME_WAIT)) { Slog.i(TAG, "handleProcessDied, the otaGuideStatusFlag is " + otaGuideStatusFlag); dealOtaGuideException(); } } } @Override public void notifyActivityResume(String curPkg) { if (PKG_NAME_UPGRADE_GUIDE.equals(curPkg)) { Slog.i(TAG, "notifyActivityResume : " + curPkg + " mTopIsWsn :" + mTopIsWsn); mTopIsWsn = true ; mHandler.removeMessages(MSG_WSN_EXCEPTION_NEWFEATURE); } else if (PKG_NAME_OPPO_DEFAULT_LAUNCHER.equals(curPkg)) { mTopIsLauncher = true ; } } private void startHome() { Intent homeIntent = new Intent(); homeIntent.setAction(LAUNCHER_ACTION); homeIntent.setPackage(PKG_NAME_OPPO_DEFAULT_LAUNCHER); homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); homeIntent.addCategory(LAUNCHER_CATEGORY); mContext.startActivity(homeIntent); } private String parseComponentState(int state) { switch (state) { case COMPONENT_ENABLED_STATE_DEFAULT: return "default"; case COMPONENT_ENABLED_STATE_ENABLED: return "enabled"; case COMPONENT_ENABLED_STATE_DISABLED: return "disabled"; case COMPONENT_ENABLED_STATE_DISABLED_USER: return "disabled-user"; case COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED: return "disabled-until-used"; default: return "unknown"; } } private ComponentName getBootRegWelcomePageComponentName() { final Intent intent = new Intent(ACTION_WELCOME_PAGE); intent.setPackage(PKG_NAME_BOOT_REG); final ResolveInfoFlags flags = ResolveInfoFlags.of(PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DISABLED_COMPONENTS); final ResolveInfo ri = mContext.getPackageManager().resolveActivityAsUser(intent, flags, UserHandle.USER_SYSTEM); if ((ri != null) && (ri.activityInfo != null)) { return new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name); } return null; } private ComponentName getWallPaperGuidComponentName() { try { boolean isEnabled = mContext.getPackageManager().getPackageInfo(PKG_NAME_WALLPAPER, 0).applicationInfo.enabled; if (!isEnabled) { Slog.w(TAG, "get WallPaper applicationInfo is not enable, return"); disableOtaGuidePage(); return null; } } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "get WallPaper applicationInfo enabled state fail name not found,return"); return null; } final Intent intent = new Intent(ACTION_WALLPAPER_GUIDE_PAGE); intent.setPackage(PKG_NAME_WALLPAPER); final ResolveInfoFlags flags = ResolveInfoFlags.of(PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DISABLED_COMPONENTS); final ResolveInfo ri = mContext.getPackageManager().resolveActivityAsUser(intent, flags, UserHandle.USER_SYSTEM); if ((ri != null) && (ri.activityInfo != null)) { return new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name); } return null; } private boolean hasOplusFeature(@NonNull String featureName) { return OplusFeatureCache.getOrCreate(IOplusFeatureConfigManagerInternal.DEFAULT) .hasFeature(featureName); } // Start upgrade guide to unzip some resources. private void startUpgradeGuide(String reason) { Slog.i(TAG, "Start upgrade guide due to " + reason); Intent upgradeServiceIntent = new Intent(ACTION_UPGRADE_SERVICE); upgradeServiceIntent.putExtra(EXTRA_START_FROM_SYSTEM, 1); upgradeServiceIntent.setPackage(PKG_NAME_UPGRADE_GUIDE); try { OplusBackgroundThread.get().getThreadHandler().post(() -> mContext.startServiceAsUser(upgradeServiceIntent, UserHandle.SYSTEM)); } catch (Exception e) { Slog.e(TAG, "Upgrade service " + upgradeServiceIntent + " failed to start!", e); } } /** * @deprecated * Use action intent filter instead, see {@link #getBootRegWelcomePageComponentName()} */ private boolean doesBootRegWelcomePageExist() { ActivityInfo ai = null; try { ai = mContext.getPackageManager().getActivityInfo(COMPONENT_WELCOME_PAGE, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DISABLED_COMPONENTS); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "doesBootRegWelcomePageExist package not found", e); } return ai != null; } private boolean isThirdTheme(int userId) { String key = "persist.sys.themeflag"; if (userId > 0) { key = key + "." + userId; } long themeFlag = android.os.SystemProperties.getLong(key, 0); if (getInstance().mDebug) { Slog.e(TAG, "themeFlag " + themeFlag); } return ((THIRD_FLAG & themeFlag) != 0) || ((CUSTOM_THEME_FLAG & themeFlag) != 0); } private boolean isCarrrierOrChannal() { String isCarrrier = SystemProperties.get(PROP_CARRRIER); String isChannel = SystemProperties.get(PROP_CHANNEL); if (getInstance().mDebug) { Slog.e(TAG, "isCarrrier " + TextUtils.isEmpty(isCarrrier) + " isChannel :" + TextUtils.isEmpty(isChannel)); } return (!TextUtils.isEmpty(isCarrrier) || !TextUtils.isEmpty(isChannel)) && !mIsDomesticBuild; } private boolean checkMarketTheme() { //kekemarket online resource check String isMarketThem = SystemProperties.get(PROP_THEME_UUID); int type = 0; if (!TextUtils.isEmpty(isMarketThem) && !("-1".equals(isMarketThem))) { mKeKeMarketTheme = true; Slog.e(TAG, "is kekemartket source"); return true; } //kekemarket online aod check String aodjson = Settings.Secure.getString(mContext.getContentResolver(), "Setting_AodStyleInfo"); if (!TextUtils.isEmpty(aodjson)) { Slog.e(TAG, "aodjson aod" + aodjson); JSONObject jsonObject = null; try { jsonObject = new JSONObject(aodjson); type = jsonObject.getInt("type"); } catch (JSONException e) { Slog.e(TAG, "Reason parse to jsonObject failed !" + e); } if (type == 1) { Slog.e(TAG, "is kekemartket aod"); mKeKeMarketTheme = true; return true; } } // kekemarket online live paper check String isMarketLivePaper = Settings.System.getString(mContext.getContentResolver(), "persist.sys.oppo.live_wp_uuid"); if (!TextUtils.isEmpty(isMarketLivePaper) && !NOT_MARKET_LIVE_WALLPAPER.contains(isMarketLivePaper)) { Slog.e(TAG, "is kekemartket livepaper"); mKeKeMarketTheme = true; return true; } return false; } private boolean checkCompanyType() { String isCompanyType = SystemProperties.get(PROP_COMPANY_TYPE, ""); if (TextUtils.isEmpty(isCompanyType)) { if (mDebug) { Slog.e(TAG, "checkCompanyType is null"); } return false; } if ("empty".equals(isCompanyType)) { if (mDebug) { Slog.e(TAG, "checkCompanyType true"); } return false; } return true; } /** * Deprecated for what's new 2.0 requirement. */ private boolean doesBootRegNewFeaturePageExist() { ActivityInfo ai = null; try { ai = mContext.getPackageManager().getActivityInfo(COMPONENT_NEW_FEATURE_PAGE, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "doesBootRegNewFeaturePageExist package not found", e); } return ai != null; } private boolean isMemoryForbid() { int currentMem = getTotalProcMemInfoGB(); Slog.i(TAG, "current Mem is " + currentMem); if (currentMem > EIGHT_GB) { return false; } return true; } private static long getProcMemInfoKB(String label) { long[] values = new long[1]; values[0] = -1; String[] labels = new String[] {label}; try { android.os.Process.readProcLines(PROC_MEMINFO_PATH, labels, values); } catch (IllegalArgumentException e) { Slog.e(TAG, "getProcMemInfoKB IllegalArgumentException"); } return values[0]; } public static int getTotalProcMemInfoKB() { if (sTotalProcMemInfoKB == -1) { sTotalProcMemInfoKB = (int) getProcMemInfoKB(LABEL_MEMTOTAL); } return sTotalProcMemInfoKB; } public static int getTotalProcMemInfoGB() { if (sTotalProcMemInfoGB == -1) { double tempValue = (getTotalProcMemInfoKB() * 1.0) / GB_IN_KB; sTotalProcMemInfoGB = DEF_RAM_SIZE.stream() .filter(i -> (i >= tempValue)) .min(Integer::compareTo) .orElse(DEF_RAM_SIZE.get(DEF_RAM_SIZE.size() - 1)); } return sTotalProcMemInfoGB; } @Override public void dump(PrintWriter pw, String[] args) { final boolean newFeaturesDisplayingEnabled = mIsDomesticBuild && mIsBrandSupported; final boolean forcedToDisplayNewFeatures = SystemProperties.getBoolean(PROP_FORCE_TO_DISPLAY_NEW_FEATURES, false); final boolean newPoliciesDisplayingEnabled = mIsDomesticBuild; final boolean forcedToDisplayNewPolicies = SystemProperties.getBoolean(PROP_FORCE_TO_DISPLAY_NEW_POLICIES, false); final boolean forcedToDisplayBootReg = SystemProperties.getBoolean(PROP_FORCE_TO_DISPLAY_BOOTREG, false); pw.println("DUMP OF NFDM:"); pw.println(" firstBoot=" + mIsFirstBoot); pw.println(" otaUpgraded=" + mOtaUpgraded); pw.println(" mIsBootFromOTA=" + mIsBootFromOTA); pw.println(" stockType=" + mStockType); pw.println(" deviceTablet=" + mIsDeviceTablet); pw.println(" screenFoldable=" + mIsScreenFoldable); pw.println(" flipDevice=" + mIsFlipDevice); pw.println(); pw.println(" newFeatures={"); pw.println(" featureEnabled=" + newFeaturesDisplayingEnabled + " ["); pw.println(" domestic=" + mIsDomesticBuild); pw.println(" brandSupported=" + mIsBrandSupported); pw.println(" ]"); pw.println(" forced=" + forcedToDisplayNewFeatures); pw.println(" majorVerUpgraded=" + mMajorVersionUpgraded + " ["); pw.println(" prevSdkVer=" + mPrevSdkVersion); pw.println(" curSdkVer=" + mCurSdkVersion); pw.println(" ]"); pw.println(" }"); pw.println(); pw.println(" newPolicies={"); pw.println(" featureEnabled=" + newPoliciesDisplayingEnabled + " ["); pw.println(" domestic=" + mIsDomesticBuild); pw.println(" ]"); pw.println(" forced=" + forcedToDisplayNewPolicies); pw.println(" forcedBootReg=" + forcedToDisplayBootReg); pw.println(" osVerUpgraded=" + mOsVersionUpgraded + " ["); pw.println(" prevOsVer=" + mPrevOsVersion); pw.println(" curOsVer=" + mCurOsVersion); pw.println(" ]"); pw.println(" wsn variable={"); pw.println(" topIsWsn=" + mTopIsWsn); pw.println(" mTopIsLauncher=" + mTopIsLauncher); pw.println(" mIsNeedDisplayWallpaper=" + mIsNeedDisplayWallpaper); pw.println(" mIsNeedDisplaySwitchPage=" + mIsNeedDisplaySwitchPage); pw.println(" ]"); pw.println(" wallpaper variable={"); pw.println(" mPictorialAuto=" + mPictorialAuto); pw.println(" mKeKeMarketTheme=" + mKeKeMarketTheme); pw.println(" doChangeWallPaper=" + mChangeWallPaper); pw.println(" ]"); pw.println(" }"); } } 结合方法分析为什么会出现ota压测出现进开机向导的情况,两个版本都是16版本

D:\Users\Downloads\Log\youtube\bugreport-RMX5313IN-AP3A.240905.015.A2-2025-06-19-11-34-32\bugreport-RMX5313IN-AP3A.240905.015.A2-2025-06-19-11-34-32.txt (155 hits) Line 15125: WINDOW MANAGER LAST ANR (dumpsys window lastanr) Line 116973: ------ VM TRACES AT LAST ANR (/data/anr/anr_2025-06-19-11-19-10-783: 2025-06-19 11:19:18) ------ Line 116973: ------ VM TRACES AT LAST ANR (/data/anr/anr_2025-06-19-11-19-10-783: 2025-06-19 11:19:18) ------ Line 116986: anr < Line 116996: anr < Line 117006: anr < Line 117016: anr < Line 199851: "anrV33-1" prio=5 tid=16 TimedWaiting Line 201580: at anrp.run(PG:35) Line 201676: at anrp.run(PG:35) Line 201731: at anrp.run(PG:35) Line 201752: at anrp.run(PG:35) Line 221720: ------ ANR FILES (ls -lt /data/anr/) ------ Line 221722: -rw------- 1 system system 4661511 2025-06-19 11:19 anr_2025-06-19-11-19-10-783 Line 221723: -rw------- 1 system system 5125123 2025-06-19 11:18 anr_2025-06-19-11-18-28-676 Line 221724: -rw------- 1 system system 5110113 2025-06-19 11:18 anr_2025-06-19-11-17-59-943 Line 221725: -rw------- 1 system system 5170843 2025-06-19 11:15 anr_2025-06-19-11-15-30-180 Line 221726: -rw------- 1 system system 5211710 2025-06-19 11:15 anr_2025-06-19-11-14-59-431 Line 221727: -rw------- 1 system system 5249604 2025-06-19 11:13 anr_2025-06-19-11-13-33-120 Line 221728: -rw------- 1 system system 2550071 2025-06-18 12:01 anr_2025-06-18-12-01-29-071 Line 221729: -rw------- 1 system system 2661757 2025-06-18 12:01 temp_anr_204762592841438826.txt Line 221730: -rw------- 1 system system 4501038 2025-06-18 12:01 anr_2025-06-18-12-00-54-648 Line 221731: -rw------- 1 system system 2790621 2025-06-18 12:00 temp_anr_6131620412329269920.txt Line 221732: -rw------- 1 system system 4774064 2025-06-18 12:00 anr_2025-06-18-12-00-30-005 Line 221733: -rw------- 1 system system 2962603 2025-06-18 12:00 temp_anr_4436968846206332345.txt Line 221734: -rw------- 1 system system 4909259 2025-06-18 12:00 anr_2025-06-18-12-00-06-676 Line 221735: -rw------- 1 system system 5561152 2025-06-18 11:59 anr_2025-06-18-11-59-15-525 Line 221736: -rw------- 1 system system 2486347 2025-06-18 11:58 anr_2025-06-18-11-58-50-107 Line 221737: -rw------- 1 system system 2513502 2025-06-18 11:58 temp_anr_7627520979123128223.txt Line 221738: -rw------- 1 system system 2547664 2025-06-18 11:58 temp_anr_7306873162887901303.txt Line 221739: -rw------- 1 system system 4468182 2025-06-18 11:58 anr_2025-06-18-11-58-19-450 Line 221740: -rw------- 1 system system 5457289 2025-06-18 11:56 anr_2025-06-18-11-56-37-891 Line 221741: -rw------- 1 system system 1325229 2025-06-18 11:54 anr_2025-06-18-11-53-47-163 Line 221742: -rw------- 1 system system 5504454 2025-06-18 11:52 anr_2025-06-18-11-52-01-409 Line 239615: backstage_power/android.app.gate_fgs_timeout_anr_behavior: READ_ONLY + DISABLED (system), DISABLED (device_config) Line 240829: system_performance/com.android.server.utils.anr_timer_freezer: READ_ONLY + DISABLED (system), DISABLED (device_config) Line 240830: system_performance/com.android.server.utils.anr_timer_service: READ_ONLY + DISABLED (system), DISABLED (device_config) Line 259422: service_start_foreground_anr_delay_ms=10000 Line 259437: short_fgs_anr_extra_wait_duration=10000 Line 288694: ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr) Line 300808: importance=400 pss=0.00 rss=0.00 description=bg anr: Input dispatching timed out (Application does not have a focused window). state=empty trace=/data/system/procexitstore/anr_2025-06-18-11-53-47-163.gz Line 300808: importance=400 pss=0.00 rss=0.00 description=bg anr: Input dispatching timed out (Application does not have a focused window). state=empty trace=/data/system/procexitstore/anr_2025-06-18-11-53-47-163.gz Line 307584: importance=230 pss=0.00 rss=347MB description=user request after error: No response to onStartJob state=empty trace=/data/system/procexitstore/anr_2025-06-19-11-19-10-783.gz Line 307588: importance=230 pss=0.00 rss=483MB description=remove task state=empty trace=/data/system/procexitstore/anr_2025-06-19-11-17-59-943.gz Line 307604: importance=230 pss=0.00 rss=452MB description=user request after error: Input dispatching timed out (8b6aa1e com.google.android.youtube/com.google.android.youtube.app.honeycomb.Shell$HomeActivity (server) is not responding. Waited 5001ms for FocusEvent(hasFocus=true)). state=empty trace=/data/system/procexitstore/anr_2025-06-19-11-15-30-180.gz Line 307608: importance=100 pss=0.00 rss=0.00 description=user request after error: Input dispatching timed out (96080e6 com.google.android.youtube/com.google.android.youtube.app.honeycomb.Shell$HomeActivity (server) is not responding. Waited 5000ms for FocusEvent(hasFocus=true)). state=empty trace=/data/system/procexitstore/anr_2025-06-19-11-14-59-431.gz Line 437707: Job Completions com.coloros.gallery3d/com.oplus.gallery.framework.abilities.scan.manager.GalleryScanService: successful_finish(7x) anr(1x) Line 437719: 11 starts, 1 anrs Line 439978: Job Completions @[email protected]/androidx.work.impl.background.systemjob.SystemJobService: unknown:-1(1x) canceled(14x) successful_finish(24x) anr(1x) Line 439989: 15 starts, 6 anrs Line 441158: Job Completions in.mohalla.sharechat/androidx.work.impl.background.systemjob.SystemJobService: canceled(5x) successful_finish(6x) anr(9x) Line 441159: Job Completions in.mohalla.sharechat/com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService: successful_finish(3x) anr(6x) Line 473593: backstage_power/android.app.gate_fgs_timeout_anr_behavior=false Line 475571: system_performance/com.android.server.utils.anr_timer_freezer=false Line 475572: system_performance/com.android.server.utils.anr_timer_service=false Line 476935: 2025-06-17 11:36:45 system_app_anr (compressed text, 232873 bytes) Line 476936: 2025-06-17 11:37:09 system_app_anr (compressed text, 201571 bytes) Line 476937: 2025-06-17 11:40:22 system_app_anr (compressed text, 222123 bytes) Line 476938: 2025-06-17 11:41:13 system_app_anr (compressed text, 185557 bytes) Line 476939: 2025-06-17 11:41:38 system_app_anr (compressed text, 241609 bytes) Line 476940: 2025-06-17 11:42:13 system_app_anr (compressed text, 248915 bytes) Line 476941: 2025-06-17 11:54:53 system_app_anr (compressed text, 167694 bytes) Line 476942: 2025-06-17 11:55:43 system_app_anr (compressed text, 190039 bytes) Line 476943: 2025-06-17 11:58:39 system_app_anr (compressed text, 245539 bytes) Line 476944: 2025-06-17 12:17:04 system_app_anr (compressed text, 214445 bytes) Line 476945: 2025-06-17 12:22:01 system_app_anr (compressed text, 241492 bytes) Line 476947: 2025-06-18 11:52:20 system_app_anr (compressed text, 260400 bytes) Line 476948: 2025-06-18 11:54:13 system_app_anr (compressed text, 196046 bytes) Line 476949: 2025-06-18 11:57:01 system_app_anr (compressed text, 245540 bytes) Line 476950: 2025-06-18 11:58:36 system_app_anr (compressed text, 256724 bytes) Line 476951: 2025-06-18 11:58:53 system_app_anr (compressed text, 83697 bytes) Line 476952: 2025-06-18 11:59:29 system_app_anr (compressed text, 255379 bytes) Line 476953: 2025-06-18 12:00:19 system_app_anr (compressed text, 248849 bytes) Line 476959: 2025-06-19 11:13:43 system_app_anr (compressed text, 238808 bytes) Line 476960: 2025-06-19 11:15:08 system_app_anr (compressed text, 236177 bytes) Line 476961: 2025-06-19 11:15:37 system_app_anr (compressed text, 220894 bytes) Line 476962: 2025-06-19 11:18:08 system_app_anr (compressed text, 223886 bytes) Line 476963: 2025-06-19 11:18:36 system_app_anr (compressed text, 218263 bytes) Line 476964: 2025-06-19 11:19:19 system_app_anr (compressed text, 236600 bytes) Line 483662: es_u_anr_count=3 Line 483663: es_u_anr_window_ms=21600000 Line 483780: <0>com.google.android.youtube::anr: Line 483792: <0>in.mohalla.sharechat::anr: Line 483836: <0>com.google.android.apps.subscriptions.red::anr: Line 483844: <0>com.google.android.youtube::anr: Line 483852: <0>com.google.android.googlequicksearchbox::anr: Line 483858: <0>com.android.providers.calendar::anr: Line 483868: <0>com.android.providers.downloads::anr: Line 483876: <0>com.google.android.apps.messaging::anr: Line 483884: <0>com.oplus.sau::anr: Line 483892: <0>com.heytap.market::anr: Line 483900: <0>com.google.android.configupdater::anr: Line 483908: <0>com.google.android.providers.media.module::anr: Line 483916: <0>com.google.android.apps.safetyhub::anr: Line 483924: <0>in.mohalla.sharechat::anr: Line 483932: <0>com.android.vending::anr: Line 483942: <0>com.google.android.adservices.api::anr: Line 483950: <0>android::anr: Line 483958: <0>com.android.launcher3::anr: Line 483966: <0>com.instagram.android::anr: Line 483974: <0>com.google.android.deskclock::anr: Line 483982: <0>com.google.android.as::anr: Line 483990: <0>com.google.android.gm::anr: Line 484000: <0>com.google.android.apps.tachyon::anr: Line 484008: <0>com.google.android.permissioncontroller::anr: Line 484014: <0>com.google.android.setupwizard::anr: Line 484022: <0>com.android.providers.settings::anr: Line 484030: <0>com.facebook.services::anr: Line 484038: <0>com.google.android.as.oss::anr: Line 484046: <0>com.google.android.apps.wellbeing::anr: Line 484054: <0>com.google.android.dialer::anr: Line 484062: <0>com.google.android.apps.nbu.files::anr: Line 484070: <0>com.google.android.apps.docs::anr: Line 484078: <0>com.google.android.apps.maps::anr: Line 484086: <0>com.google.android.webview::anr: Line 484094: <0>com.coloros.weather2::anr: Line 484102: <0>com.google.android.networkstack::anr: Line 484110: <0>com.google.android.rkpdapp::anr: Line 484118: <0>com.google.android.contacts::anr: Line 484126: <0>com.android.chrome::anr: Line 484134: <0>com.nearme.gamecenter::anr: Line 484142: <0>com.nearme.statistics.rom::anr: Line 484150: <0>com.google.android.gms::anr: Line 484158: <0>com.google.android.tts::anr: Line 484166: <0>com.google.android.apps.walletnfcrel::anr: Line 484174: <0>com.google.android.partnersetup::anr: Line 484182: <0>com.google.android.videos::anr: Line 484190: <0>com.coloros.lockassistant::anr: Line 484200: <0>com.google.android.apps.photos::anr: Line 484208: <0>com.google.android.calendar::anr: Line 484218: <0>com.facebook.katana::anr: Line 484226: <0>com.coloros.phonemanager::anr: Line 484234: <0>com.android.imsserviceentitlement::anr: Line 484242: <0>com.android.settings::anr: Line 484250: <0>com.fitbit.FitbitMobile::anr: Line 484258: <0>com.grofers.customerapp::anr: Line 484266: <0>com.myntra.android::anr: Line 484274: <0>com.google.android.apps.turbo::anr: Line 484282: <0>com.oplus.lfeh::anr: Line 484288: <0>com.google.android.apps.carrier.carrierwifi::anr: Line 484298: <0>com.oppo.quicksearchbox::anr: Line 484306: <0>com.google.android.apps.youtube.music::anr: Line 484314: <0>com.facebook.appmanager::anr: Line 484322: <0>com.coloros.gallery3d::anr: Line 484330: <0>com.snapchat.android::anr: Line 484340: <0>com.google.android.inputmethod.latin::anr: Line 484348: <0>com.glance.internet::anr: Line 484354: <0>com.google.android.apps.restore::anr: Line 484363: Category{anr}: 3 events in +6h0m0s0ms Line 506990: 4x unknown:-1, 38x canceled, 82x successful_finish, 1x anr Line 544392: com.unisoc.traceur.anrstartdumpperfetto: Line 546673: com.unisoc.traceur.anrsavedumpperfetto: Line 708996: _id:585 name:anr_show_background pkg:com.android.settings value:0 default:0 defaultSystemSet:true Line 709073: _id:275 name:dropbox:data_app_anr pkg:com.google.android.gms value:disabled Line 709643: setting: anr_show_background generation:2

Traceback (most recent call last): File "G:\SAU\upload_video_to_tiktok.py", line 30, in <module> asyncio.run(app.main(), debug=False) ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python313\Lib\asyncio\runners.py", line 194, in run return runner.run(main) ~~~~~~~~~~^^^^^^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python313\Lib\asyncio\runners.py", line 118, in run return self._loop.run_until_complete(task) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python313\Lib\asyncio\base_events.py", line 720, in run_until_complete return future.result() ~~~~~~~~~~~~~^^ File "G:\SAU\uploader\tk_uploader\main_chrome.py", line 298, in main await self.upload(playwright) File "G:\SAU\uploader\tk_uploader\main_chrome.py", line 149, in upload browser = await playwright.chromium.launch(headless=False, executable_path=self.local_executable_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python313\Lib\site-packages\playwright\async_api\_generated.py", line 14451, in launch await self._impl_obj.launch( ...<17 lines>... ) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python313\Lib\site-packages\playwright\_impl\_browser_type.py", line 97, in launch Browser, from_channel(await self._channel.send("launch", params)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python313\Lib\site-packages\playwright\_impl\_connection.py", line 61, in send return await self._connection.wrap_api_call( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...<2 lines>... ) ^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python313\Lib\site-packages\playwright\_impl\_connection.py", line 528, in wrap_api_call raise rewrite_error(error, f"{parsed_st['apiName']}: {error}") from None playwright._impl._errors.Error: BrowserType.launch: Failed to launch: Error: spawn . ENOENT Call log: - <launching> . --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AutoExpandDetailsElement,AvoidUnnecessaryBeforeUnloadCheckSync,CertificateTransparencyComponentUpdater,DeferRendererTasksAfterInput,DestroyProfileOnBrowserClose,DialMediaRouteProvider,ExtensionManifestV2Disabled,GlobalMediaControls,HttpsUpgrades,ImprovedCookieControls,LazyFrameLoading,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --no-sandbox --user-data-dir=C:\Users\Administrator\AppData\Local\Temp\playwright_chromiumdev_profile-UBuVJ1 --remote-debugging-pipe --no-startup-window - [pid=N/A] starting temporary directories cleanup - [pid=N/A] finished temporary directories cleanup

private boolean isOsVersionUpgraded() { 442 String prevOsVersion = mPrevOsVersion; 443 String curOsVersion = mCurOsVersion; 444 445 if (isValidOsVersion(prevOsVersion) && isValidOsVersion(curOsVersion)) { 446 if (prevOsVersion.indexOf(".") == -1) { 447 prevOsVersion = prevOsVersion.concat(".0"); 448 } 449 if (curOsVersion.indexOf(".") == -1) { 450 curOsVersion = curOsVersion.concat(".0"); 451 } 452 453 try { 454 prevOsVersion = prevOsVersion.substring(1); 455 curOsVersion = curOsVersion.substring(1); 456 457 String[] prevOsVersionArr = prevOsVersion.split("\\."); 458 String[] curOsVersionArr = curOsVersion.split("\\."); 459 460 if (((prevOsVersionArr.length == S_OS_VERSION_LENGTH) || (prevOsVersionArr.length == T_OS_VERSION_LENGTH)) && (curOsVersionArr.length == T_OS_VERSION_LENGTH)) { 461 final int prevOsVersionMajor = Integer.parseInt(prevOsVersionArr[0]); 462 final int curOsVersionMajor = Integer.parseInt(curOsVersionArr[0]); 463 if (curOsVersionMajor > prevOsVersionMajor) { 464 return true; 465 } else if (curOsVersionMajor == prevOsVersionMajor) { 466 final int prevOsVersionMinor = Integer.parseInt(prevOsVersionArr[1]); 467 final int curOsVersionMinor = Integer.parseInt(curOsVersionArr[1]); 468 if (curOsVersionMinor > prevOsVersionMinor) { 469 return true; 470 } 471 } 472 } 473 } catch (Exception e) { 474 Slog.e(TAG, "Error parsing os version: " + e.toString()); 475 return false; 476 } 477 } 478 479 return false; 480 } public void setValues(boolean isFirstBoot, boolean isUpgrade, boolean isBootFromOTA, int curSdkVersion, 490 int lastSdkVersion) { 491 /* 492 * isUpgrade is true when: 1. Fingerprint changes;2. COTA upgrade;3. OTA upgrade (including sau system upgrade);4. opex-apk upgrade; 493 * isBootFromOTA is true: only when OTA upgrade (including sau system upgrade) 494 */ 495 Slog.d(TAG, String.format("firstBoot=%s, upgrade=%s, isBootFromOTA=%s, curSdkVersion=%s, lastSdkVersion=%s", 496 isFirstBoot, isUpgrade, isBootFromOTA, curSdkVersion, lastSdkVersion)); 497 mIsFirstBoot = isFirstBoot; 498 mOtaUpgraded = isUpgrade; 499 mIsBootFromOTA = isBootFromOTA; 500 mPrevSdkVersion = lastSdkVersion; 501 mCurSdkVersion = curSdkVersion; 502 mMajorVersionUpgraded = isUpgrade 503 && lastSdkVersion < curSdkVersion 504 && SUPPORTED_TARGET_SDKS.contains(curSdkVersion); 505 mOsVersionUpgraded = isUpgrade && isOsVersionUpgraded(); 506 mProjectNumber = SystemProperties.get(PROP_RO_SEPARATE_SOFT, ""); 507 }

最新推荐

recommend-type

Fortune Teller (霄占)_ A Python-based divination platform that

Fortune Teller (霄占)_ A Python-based divination platform that uses LLMs to provide personalized fortune readings through multiple systems including BaZi, tarot, and zodiac astrology. 基于Python的多系统算命程序,使用LLM(大型语言模型)进行解读。.zip
recommend-type

一个基于qwen-max-latest(LLM) + paraformer-realtime-v2(ASR)的一个实时语

一个基于qwen-max-latest(LLM) + paraformer-realtime-v2(ASR)的一个实时语音AI面试助手.zip
recommend-type

破解dex2jar: Android应用反编译与分析指南

标题中的“dex2jar”指的是一个用于将Android应用程序中的DEX文件(Dalvik可执行文件)转换成Java JAR文件的工具。这个过程被称为“DEX转JAR”,是一个逆向工程的过程,它允许开发者查看和分析Android应用程序的原始Java代码,这通常用于学习、测试和安全分析目的。破解一词在此上下文中可能用于描述不正当手段获取程序的源代码以进行修改或绕过安全机制等行为,但请注意,任何未经授权的修改和使用都可能违反法律和版权。 描述部分提供了使用dex2jar工具的基本步骤。dex2jar通常是一个批处理文件(dex2jar.bat),用于在Windows环境下执行操作。它将DEX文件(classes.dex)作为输入,并生成对应的JAR文件。这个过程需要用户已经下载并解压了dex2jar的压缩包,并将其中的dex2jar.bat文件放在一个可以访问的目录中。然后,用户需要将目标Android应用程序中的classes.dex文件复制到该目录下,并在命令行界面中运行以下命令: dex2jar.bat classes.dex 执行完毕后,会在同一目录下生成名为classes.dex.dex2jar.jar的文件。这个JAR文件实质上是将DEX文件中的类转换成了Java的.class文件,并打包成了JAR格式,供后续的分析或修改使用。 【标签】中的“Android 破解”可能被误解为破解Android应用程序的安全机制,实际上,这个标签更准确的意义是分析和理解Android应用程序的工作原理。而“jar dex”则是指JAR文件与DEX文件之间的转换关系。 【压缩包子文件的文件名称列表】中列举了几个文件名,其中“使用说明.txt”很可能是该工具的官方使用指南,提供更详细的使用说明、安装步骤和常见问题的解答。“dex2jar最新版下载dex2jar下载 2.0官方版_ - pc6下载站.url”则是一个指向PC6下载站上dex2jar工具下载页面的网页链接。“dex2jar-2.0”可能是指特定版本号的dex2jar工具压缩包。 总结以上信息,dex2jar是一个专门用于Android应用安全分析和逆向工程的工具,它将DEX文件转换成Java的JAR文件以便进行代码的查看和分析。尽管这个过程在安全研究和教育目的下是合法且有价值的,但任何使用这一工具的非法破解、侵犯版权或进行恶意行为都是不可接受的。
recommend-type

共享内存与共识算法详解

### 共享内存与共识算法详解 在分布式系统中,共享内存和共识算法是两个核心的概念。共享内存涉及到多个进程对同一数据的读写操作,而共识算法则帮助多个进程在可能存在故障的情况下达成一致的决策。下面将详细介绍这两个方面的相关知识。 #### 共享内存 共享内存的寄存器规范由Lamport在多篇论文中引入,同时定义了安全、规则和原子三种语义。 - **安全寄存器**:在三种寄存器语义中,安全寄存器提供的保证最弱。当读操作与写操作并发时,安全寄存器可能返回任意值,甚至可能是从未被写入或尝试写入的值。在多处理器机器中,进程可能并发访问实现寄存器抽象的底层硬件位置,从而导致返回任意值。在任意故障模型中
recommend-type

计算机专业本科生和研究生就业薪资待遇

<think>好的,我需要回答用户关于计算机专业本科和研究生就业薪资对比的问题。首先,我得先看看用户提供的引用资料,看看里面有没有相关的数据。 引用[4]提到,2019届计算机类本科毕业生的平均月收入是6858元,而高职是4883元。这应该可以作为本科生的参考数据。至于研究生,引用[1]指出重庆大学的计算机和软件硕士就业情况良好,薪资高于行业平均水平,但没有具体数字。不过引用[3]提到,前20名的高校多为985/211,尤其是理工类院校的毕业生薪资更高。这里可能需要结合其他信息来推断研究生的薪资水平。 另外,引用[2]提到计算机专业毕业生薪资一般在万元以上,但不确定这是否特指研究生还是包括
recommend-type

eWebEditor 10.3最新版特性与安全升级指南

从提供的信息来看,我们需要深入了解和探讨的内容主要集中在“eWebEditor最新版”这一主题上。eWebEditor是一款流行的在线HTML编辑器,它支持ASP和ASP.NET环境,并广泛用于Web内容管理。通过给出的标题和描述,以及标签和文件名称列表,我们可以推导出一系列相关的知识点。 ### 标题知识点解析 #### eWebEditor的定义与功能 “eWebEditor最新版”中提到的“eWebEditor”指的是在线HTML编辑器产品,它被广泛应用于需要在线编辑和发布网页内容的场合。编辑器通常包含许多功能,比如文本格式化、图像插入、链接管理等,提供用户友好和接近桌面程序的编辑体验。eWebEditor产品以ASP和ASP.NET作为其主要的技术平台。 #### “最新版”更新内容 “最新版”表明我们正在讨论的是eWebEditor的最新版本更新,该版本很可能是为了增加新功能、提升性能、修复已知问题或改善安全性能。一般来说,软件的更新也可能会引入对新操作系统或浏览器的兼容性,以及对现有API或开发环境的新支持。 ### 描述知识点解析 #### “亲测可用”的含义 从“亲测 可用”的描述中我们可以推断出,发布者可能已经对“eWebEditor最新版”进行了测试,并验证了其在实际使用中的性能和稳定性。该短语传递出一个积极的信号,即该版本值得信赖,用户可以期待它将正常工作,无需担心兼容性或功能缺失的问题。 ### 标签知识点解析 #### eWebEditor的版本标识 “eWebEditor ASPX 10.3 最新版”中的标签指出我们讨论的版本号为10.3,这是一个具体的产品版本,意味着它可能包含了一些特定的更新或新增特性。通过版本号,我们可以推断产品已经经过了多次迭代和改进。 #### ASPX技术框架 在标签中提到的“ASPX”,这表明eWebEditor最新版支持ASP.NET Web Forms技术,ASPX是ASP.NET网页的标准文件扩展名。这一信息指出编辑器适合使用.NET框架的网站开发环境。 ### 文件名称列表知识点解析 #### “升级说明.txt”文件 “升级说明.txt”是一个文本文件,它可能包含了eWebEditor从上一版本升级到最新版本时的变化说明,例如新增功能、改进的地方以及需要注意的变更。开发者或维护人员在升级时应该仔细阅读这些说明,以便于平滑过渡到新版本,并最大化地利用新功能。 #### “安全说明.txt”文件 “安全说明.txt”文件通常提供了关于软件安全性的相关信息,这可能包括了针对最新版的安全补丁、修复的安全漏洞列表以及安全最佳实践的建议。特别是对于在线编辑器这类直接参与网页内容生成的工具,安全尤为重要,因此,安全说明文件对于确保编辑器和整个网站的安全运行至关重要。 #### “ewebeditor”文件夹或组件 “ewebeditor”可能是实际包含eWebEditor编辑器文件的文件夹名称。通常,这类文件夹内会包含用于前端的JavaScript文件、用于后端处理的服务器端代码(ASP.NET或ASP代码),以及相关的样式文件和资源文件。对于开发者来说,了解这些文件和组件的组织结构对于集成和配置编辑器至关重要。 综合以上信息,我们可以了解到eWebEditor的最新版本更新了很多内容,可能包含性能和安全性的提升,并可能对特定的技术平台如ASP.NET提供了更好的支持。用户应该参考升级和安全说明文件,以便正确理解和应用这些更新。对于开发者而言,掌握如何在项目中部署和配置eWebEditor编辑器也是一个重要的技能点。
recommend-type

分布式系统中的时间抽象与故障处理

### 分布式系统中的时间抽象与故障处理 #### 1. 故障检测概述 在分布式系统中,存在三种不同的系统假设:异步系统假设、同步系统假设和部分同步系统假设。异步系统不包含任何时间假设,我们的进程和链路抽象直接体现了这一点。然而,这些抽象不足以定义同步和部分同步系统。 为了添加时间假设,一种方法是用时间保证来扩展进程和链路抽象,但这会导致规范过于复杂。因此,我们引入了故障检测器的抽象概念,它能提供关于哪些进程崩溃、哪些进程正常的信息,不过这些信息不一定准确。 故障检测器抽象相较于直接对进程和链路做时间假设具有以下两个优势: - 减轻了用时间假设扩展进程和链路抽象的需求,保留了这些抽象的简
recommend-type

我发一份参考课程设计目录

<think>好的,用户之前问过关于高校实验室安排系统的数据库课程设计,现在他需要一份参考的课程设计目录。首先,我需要回顾之前的对话,确保目录结构和他之前的问题相关,并且覆盖他提到的核心需求、ER模型、表结构、业务逻辑等内容。 用户现在要目录,可能是在进行课程设计的结构规划,需要明确的章节安排。我需要考虑课程设计通常包含的部分,比如需求分析、系统设计、数据库设计、实现、测试等。同时,结合之前给出的内容,比如ER图、表结构、冲突检测算法等,确保这些部分在目录中有体现。 还要注意用户可能希望目录足够详细,包含各个关键部分,比如摘要、需求分析、数据库设计(包括概念结构、逻辑结构、物理结构)、系统
recommend-type

惠普AMTBrand深度解析与技术特点

标题和描述中提到的“惠普AMTBrand”,可能是指惠普(Hewlett-Packard,简称HP)公司旗下的AMTBrand相关产品或技术。然而,由于给出的信息非常有限,我们可以先从惠普公司以及AMT(Active Management Technology,主动管理技术)两个方面进行展开。惠普是全球知名的IT企业,提供多种计算机硬件、软件、云服务和解决方案,而AMT是英特尔(Intel)研发的一种硬件级别的远程管理技术。 首先,我们来了解惠普公司: 惠普(Hewlett-Packard Enterprise,简称HPE),是全球领先的信息技术解决方案提供商。成立于1939年,由Bill Hewlett和David Packard在一间车库里创立,如今已经成为全球范围内提供广泛IT产品与服务的企业。惠普的产品和服务包括但不限于个人计算机(PC)、打印设备、工作站、服务器、网络设备、存储解决方案以及软件和服务。 惠普在IT服务管理、云计算、大数据和分析等领域均有涉猎,并为各种规模的企业提供从基础架构到应用管理的全方位解决方案。随着数字化转型的不断深入,惠普也在不断地通过研发新技术和收购相关企业来拓展其产品和服务的范围。 接着,我们探索AMT技术: AMT是英特尔推出的一种基于硬件的管理解决方案,它允许IT部门远程管理企业中的个人计算机和其他设备。AMT是一种集成在商用英特尔处理器中的技术,能够在个人电脑关机或者操作系统失效的情况下,提供网络访问以及硬件级别的远程管理功能。这项技术最初由英特尔在2006年发布,历经数代更新,为IT运维人员提供了众多功能,如远程开机、远程维护、软件部署、系统监控等。 AMT的优势主要体现在以下几个方面: 1. 远程访问:即使目标设备没有开机或操作系统出现故障,AMT也可以实现远程访问和管理。 2. 安全性:它提供比传统软件解决方案更为深入的硬件级别安全机制,确保数据传输的安全。 3. 节约成本:通过减少现场支持的需要,AMT能够帮助公司节约维护成本。 4. 提高效率:快速远程解决问题,从而提高IT部门的工作效率和响应速度。 然而,由于AMT技术基于特定的硬件和软件,这意味着用户需要购买带有AMT功能的英特尔处理器和相应的支持软件,同时可能需要来自惠普或其他OEM厂商的相应硬件。 最后,提到“压缩包子文件的文件名称列表”中的“AMTBrand”,这可能意味着提供或关联惠普AMTBrand技术的文件压缩包。考虑到文件名称的单一性和没有其他文件描述提供进一步信息,不能确定这个压缩包内具体包含哪些内容。不过,可以推测该压缩包内可能包含了介绍惠普AMTBrand技术的文档、演示、驱动程序、更新或管理工具等。 综合来看,文件中提到的“惠普AMTBrand”可能是指惠普公司与英特尔AMT技术结合后形成的产品或服务品牌,旨在为用户提供更为高效和安全的远程管理解决方案。考虑到惠普公司自身在IT领域的深厚积累和AMT技术的先进性,惠普AMTBrand很可能为企业级客户提供了重要价值。
recommend-type

分布式编程抽象:概念、应用与挑战

# 分布式编程抽象:概念、应用与挑战 ## 1. 引言 分布式编程抽象旨在解决分布式系统中多进程合作的难题,为分布式程序开发提供模块化策略。通过特定的应用程序编程接口(API),可以利用这些抽象来简化开发过程。 ## 2. 分布式计算的动机 ### 2.1 分布式系统的特点 分布式计算涉及一组寻求合作的进程。部分进程可能会因崩溃或断开连接而停止运行,这就是分布式系统的部分故障特性。正如Leslie Lamport所说:“分布式系统中,一台你甚至不知道存在的计算机故障,可能会使你自己的计算机无法使用。” ### 2.2 合作的挑战 当部分进程失败或断开连接时,仍在运行的进程需要以一致的方式