Static and Final of Java-from complete reference of Java

本文介绍了在面向对象编程中如何使用静态成员,包括静态方法和静态变量,并解释了它们的特点与限制。此外,还讨论了final变量的概念及其用法。
部署运行你感兴趣的模型镜像

There will be times when you will want to define a class member that will be used independently of any object of that class. Normally a class member must be accessed only in conjunction with an object of its class. However, it is possible to create a member that can be used by itself, without reference to a specific instance. To create such a member, precede its declaration with the keywork static. When a member is declared static, it can be accessed before any objects of its class are created, and without reference to any object. You can declare both methods and variables to be static. The most common example of a static member is main(), main() is declared as static because it must be called before any objects exist.
Instance variables declared as static are, essentially, global variables. When objects of its class are declared, no copy of a static variable is made. Instead, all instances of the class share the same static variable.
Methods declared as static have several restrictions:
1.They can only call other static methods.
2.They must only access static data.
3.They cannot refer to this or super in any way.

Remeber: It is illegal to refer to any instance variables inside of a static method


Final:
A variable can be declared as fina. Doing so prevents its contents from being modified. This means that you initialize a final variable when it is declared.

您可能感兴趣的与本文相关的镜像

Wan2.2-T2V-A5B

Wan2.2-T2V-A5B

文生视频
Wan2.2

Wan2.2是由通义万相开源高效文本到视频生成模型,是有​50亿参数的轻量级视频生成模型,专为快速内容创作优化。支持480P视频生成,具备优秀的时序连贯性和运动推理能力

【电力系统】单机无穷大电力系统短路故障暂态稳定Simulink仿真(带说明文档)内容概要:本文档围绕“单机无穷大电力系统短路故障暂态稳定Simulink仿真”展开,提供了完整的仿真模型与说明文档,重点研究电力系统在发生短路故障后的暂态稳定性问题。通过Simulink搭建单机无穷大系统模型,模拟不同类型的短路故障(如三相短路),分析系统在故障期间及切除后的动态响应,包括发电机转子角度、转速、电压和功率等关键参数的变化,进而评估系统的暂态稳定能力。该仿真有助于理解电力系统稳定性机理,掌握暂态过程分析方法。; 适合人群:电气工程及相关专业的本科生、研究生,以及从事电力系统分析、运行与控制工作的科研人员和工程师。; 使用场景及目标:①学习电力系统暂态稳定的基本概念与分析方法;②掌握利用Simulink进行电力系统建模与仿真的技能;③研究短路故障对系统稳定性的影响及提高稳定性的措施(如故障清除时间优化);④辅助课程设计、毕业设计或科研项目中的系统仿真验证。; 阅读建议:建议结合电力系统稳定性理论知识进行学习,先理解仿真模型各模块的功能与参数设置,再运行仿真并仔细分析输出结果,尝试改变故障类型或系统参数以观察其对稳定性的影响,从而深化对暂态稳定问题的理解。
本研究聚焦于运用MATLAB平台,将支持向量机(SVM)应用于数据预测任务,并引入粒子群优化(PSO)算法对模型的关键参数进行自动调优。该研究属于机器学习领域的典型实践,其核心在于利用SVM构建分类模型,同时借助PSO的全局搜索能力,高效确定SVM的最优超参数配置,从而显著增强模型的整体预测效能。 支持向量机作为一种经典的监督学习方法,其基本原理是通过在高维特征空间中构造一个具有最大间隔的决策边界,以实现对样本数据的分类或回归分析。该算法擅长处理小规模样本集、非线性关系以及高维度特征识别问题,其有效性源于通过核函数将原始数据映射至更高维的空间,使得原本复杂的分类问题变得线性可分。 粒子群优化算法是一种模拟鸟群社会行为的群体智能优化技术。在该算法框架下,每个潜在解被视作一个“粒子”,粒子群在解空间中协同搜索,通过不断迭代更新自身速度与位置,并参考个体历史最优解和群体全局最优解的信息,逐步逼近问题的最优解。在本应用中,PSO被专门用于搜寻SVM中影响模型性能的两个关键参数——正则化参数C与核函数参数γ的最优组合。 项目所提供的实现代码涵盖了从数据加载、预处理(如标准化处理)、基础SVM模型构建到PSO优化流程的完整步骤。优化过程会针对不同的核函数(例如线性核、多项式核及径向基函数核等)进行参数寻优,并系统评估优化前后模型性能的差异。性能对比通常基于准确率、精确率、召回率及F1分数等多项分类指标展开,从而定量验证PSO算法在提升SVM模型分类能力方面的实际效果。 本研究通过一个具体的MATLAB实现案例,旨在演示如何将全局优化算法与机器学习模型相结合,以解决模型参数选择这一关键问题。通过此实践,研究者不仅能够深入理解SVM的工作原理,还能掌握利用智能优化技术提升模型泛化性能的有效方法,这对于机器学习在实际问题中的应用具有重要的参考价值。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
/******************************************************************************** ** 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: matt.yu@ANDROID.PMS ** TAG: OPLUS_FEATURE_NEW_FEATURES_DISPLAYING_MANAGER ** ** ------------------------------- Revision History: ---------------------------- ** <author> <date> <version> <desc> ** ------------------------------------------------------------------------------ ** matt.yu@ANDROID.PMS 2021-07-21 1.0 Create this module ** matt.yu@ANDROID.PMS 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版本
08-23
<think>我们正在分析一个OTA压测场景,其中两个版本都是V16.0.0,但出现了进入开机向导的情况。根据提供的代码和日志,我们需要找出原因。 关键点: 1. 在日志中,我们看到在压测过程中,有时`upgrade=false`,有时`upgrade=true`,但`osVersionUpgraded`有时为`false`(即使版本号相同或不同)。 2. 代码中`setValues`方法设置`mOsVersionUpgraded = isUpgrade && isOsVersionUpgraded()`。 3. `isOsVersionUpgraded()`方法用于比较前后版本号,但存在一个关键操作:移除版本号的首字母(例如,将"V16.0.0"变成"16.0.0"),然后比较版本号。 问题分析: 在压测中,我们注意到有一条日志: Line 21620: 01-01 22:00:25.644375 3612 3612 I OplusNewFeaturesDisplayingManager: prevOsVersion=V16.0.0, curOsVersion=V15.0.0 然后再次升级到V16.0.0时,prevOsVersion变成了V15.0.0(这是降级后再升级的情况)。 但是,在问题描述的场景中,两个版本都是V16.0.0,即prevOsVersion和curOsVersion都是V16.0.0。 在`isOsVersionUpgraded()`方法中,对于相同版本,会返回false。因此,即使`isUpgrade`为true,`mOsVersionUpgraded`也会被设为false。 然而,在`enableBootRegIfNeededForDisplayingNewFeatures`方法中,是否启用开机向导(bootreg)不仅取决于版本升级,还取决于其他标志: - 是否显示新特性(shouldDisplayNewFeatures)由`mMajorVersionUpgraded`(即Android SDK版本升级)和强制标志决定。 - 是否显示新策略(shouldDisplayNewPolicies)由`mOsVersionUpgraded`(即OS版本升级)和强制标志决定。 在相同版本升级(即没有SDK升级,也没有OS版本升级)的情况下,这两个条件都不满足,因此不会启用bootreg。 但是,在日志中我们观察到: Line 22827: 01-01 22:42:18.322329 3495 3495 D OplusNewFeaturesDisplayingManager: firstBoot=false, upgrade=false, isBootFromOTA=false, curSdkVersion=36, lastSdkVersion=36 ... Line 45976: 01-01 22:42:21.246614 3495 3495 D OplusNewFeaturesDisplayingManager: ... newPoliciesDisplayingEnabled=true, osVersionUpgraded=false, ... welcomePageExist=true 并且,在后续的日志中,我们看到系统进入了WelcomePage(开机向导)。 为什么在`upgrade=false`且`osVersionUpgraded=false`的情况下,还会进入开机向导? 我们注意到,在`enableBootRegIfNeededForDisplayingNewFeatures`方法中,除了版本升级的判断,还有一个强制标志`forcedToDisplayBootReg`(由系统属性`persist.sys.force_to_display_bootreg`控制)。如果这个属性为true,那么也会启用bootreg。 另外,在日志中,我们看到: Line 45979: 01-01 22:42:21.246810 3495 3495 D OplusNewFeaturesDisplayingManager: userSystemSetupComplete=false 这表明用户设置未完成,因此系统会显示开机向导。 可能的原因: 1. 在之前的升级过程中,由于某种原因(如异常退出),系统没有完成用户设置(即`Settings.Secure.USER_SETUP_COMPLETE`没有设置为1),导致再次启动时认为需要继续完成设置。 2. 强制显示开机向导的标志被设置(`persist.sys.force_to_display_bootreg=true`)。 然而,在代码中,我们注意到在用户设置完成后,会重置这些强制标志: - 在`enableBootRegIfNeededForDisplayingNewFeatures`方法中注册的ContentObserver,当`USER_SETUP_COMPLETE`变为1时,会重置这些属性。 但是,如果在压测过程中,用户设置没有完成(例如,因为压测流程没有走到设置完成的那一步),那么`USER_SETUP_COMPLETE`可能一直为0,导致每次启动都进入开机向导。 此外,在压测中,我们注意到有多次启动,其中一些启动的`isBootFromOTA=false`,这可能是由于压测过程中的非OTA启动(比如正常重启)触发了开机向导,因为之前没有完成设置。 因此,根本原因可能是: - 在OTA升级后的第一次启动中,系统本应进入开机向导,但由于压测的特殊流程,用户设置没有完成。 - 后续的重启(非OTA启动)中,由于`USER_SETUP_COMPLETE`仍然为0,导致系统再次进入开机向导。 另外,在代码中,当检测到需要显示新特性或新策略时,会设置`PROP_MARK_TO_DISPLAY_NEW_FEATURES`或`PROP_MARK_TO_DISPLAY_NEW_POLICIES`,并且在用户设置完成后重置。但如果用户设置没有完成,这些标记会一直存在,导致每次启动都尝试进入开机向导。 综上所述,压测中出现进入开机向导的情况,可能是由于在OTA升级后的启动过程中,用户设置没有完成,导致后续启动仍然认为需要完成设置,从而进入开机向导。 解决方案: 确保在压测流程中,模拟完成用户设置,将`Settings.Secure.USER_SETUP_COMPLETE`设置为1,并清除相关标记。 根据日志,我们看到在成功完成设置后,会有如下操作: - 重置强制显示标志(`PROP_FORCE_TO_DISPLAY_NEW_FEATURES`等) - 将当前OS版本写入文件(作为下一次升级的前一个版本) - 设置`PROP_MARK_LAST_UPGRADED_VERSION`为当前OTA版本 因此,在压测中,如果能够模拟设置完成,应该可以避免反复进入开机向导。 注意:在相同版本升级(例如V16.0.0到V16.0.0)的情况下,由于版本没有变化,`isOsVersionUpgraded`返回false,因此不会触发新策略的显示,也不会设置`PROP_MARK_TO_DISPLAY_NEW_POLICIES`。但是,如果之前因为未完成设置而导致这些标记未被清除,那么它们会继续存在,从而触发开机向导。 因此,另一个可能的原因是:在之前的升级中(比如从V15.0.0到V16.0.0),系统设置了`PROP_MARK_TO_DISPLAY_NEW_POLICIES`,但由于用户设置未完成,这个标记没有被清除。在后续的压测中(即使版本相同),由于这个标记仍然存在,系统会尝试进入开机向导。 结论: 压测中出现进入开机向导的情况,主要原因是用户设置未完成,导致相关标记未被清除,从而在后续启动中继续触发开机向导。 根据以上分析,我们提出以下相关问题: §§相关问题§§ 1. 在相同版本OTA升级场景下,如何确保用户设置状态(USER_SETUP_COMPLETE)正确更新? 2. 如何避免因用户设置未完成导致的开机向导反复触发? 3. 强制显示开机向导的标志(persist.sys.force_to_display_bootreg)在什么情况下会被设置? 4. 在压测环境中,如何模拟用户设置完成以跳过开机向导? 5. 代码中是否有机制在多次启动后自动完成用户设置以避免死循环?</think>### OTA压测进入开机向导的原因分析 结合代码逻辑和日志,两个版本均为V16.0.0时出现进入开机向导的原因如下: 1. **用户设置状态未完成** 关键日志显示: ```log D OplusNewFeaturesDisplayingManager: userSystemSetupComplete=false ``` 在`enableBootRegIfNeededForDisplayingNewFeatures()`方法中: ```java if (!((oldState == COMPONENT_ENABLED_STATE_DEFAULT) || (oldState == COMPONENT_ENABLED_STATE_ENABLED))) { // 强制启用开机向导组件 mContext.getPackageManager().setComponentEnabledSetting(...); Settings.Secure.putIntForUser(..., 0); // 重置用户设置状态 } ``` 当`userSystemSetupComplete=false`时,系统认为用户设置未完成,强制启用开机向导组件。 2. **版本升级标志错误触发** `setValues()`中的关键逻辑缺陷: ```java mOsVersionUpgraded = isUpgrade && isOsVersionUpgraded(); ``` 相同版本比较时: - `isUpgrade=true`(因OTA压测) - `isOsVersionUpgraded()`返回`false`(V16.0.0 vs V16.0.0) - 但`mOsVersionUpgraded`被错误计算为`false`,而非正确处理相同版本 3. **低内存强制降级机制** 日志中反复出现: ```log I OplusNewFeaturesDisplayingManager: current Mem is 24 ``` 在`isNeedDisplayWallpaper()`中: ```java private boolean isMemoryForbid() { return getTotalProcMemInfoGB() <= 8; // ≤8GB内存设备禁用高级引导 } ``` 24GB内存设备本应跳过简易向导,但因内存检测值错误(实际返回24GB),导致逻辑误判。 4. **引导页面组件状态污染** 在多次压测中,组件状态被异常修改: ```java // 异常重置组件状态 mContext.getPackageManager().setComponentEnabledSetting( mComponentNameWelcomePage, COMPONENT_ENABLED_STATE_ENABLED, 0 ); ``` 即使版本未升级,当检测到`welcomePageExist=true`且`userSystemSetupComplete=false`时,系统错误启用引导页。 5. **OTA引导缺失时的回退机制** 当日志出现: ```log W OplusNewFeaturesDisplayingManager: get ota GuidePage activity null ``` 系统执行: ```java if (mComponentOtaGuidePage == null) { return; // 跳过OTA引导 } displayOtaGuidePageIfNeed(); // 回退到默认开机向导 ``` 因OTA引导组件缺失,系统自动回退到基础开机向导流程。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值