RK:主屏幕
Platform: RK3288
OS: Android 7.1
Kernel: 4.4.143
Android7.0 DirectBoot阻塞开机分析 宇落无痕 https://blog.csdn.net/fu_kevin0606/article/details/65437594
一.需求: 仿Android5.1 Settings.apk 上的 设置 主屏幕
问题点:a.动态显示 一级设置列表 主屏幕
b.二级设置列表 home 属性的list
二.Android 7.1 Setttings home识别个数异常
2.1.home属性的apk 有两个 Settings.apk Launcher.apk
private int getHomeActivitiesCount() {
final ArrayList<ResolveInfo> homeApps = new ArrayList<ResolveInfo>();
getPackageManager().getHomeActivities(homeApps);
return homeApps.size();
}
2.2.launcher启动流程增加了settings--->FallbackHome--->launcher
在启动Launcher之前会先启动一个FallbackHome,之后才会启动Launcher,而FallbackHome属于Settings中的一个透明的activity,
Settings的android:directBootAware=true,并且FallbackHome在category中配置了Home属性,而Launcher的
android:directBootAware=false,所以只有FallbackHome可以在direct boot模式下启动
补:Direct Boot模式下app是无法运行的要运行的话需要在AndroidManinfest.xml中设置 android:directBootAware="true"
<!-- Triggered when user-selected home app isn't encryption aware -->
<activity android:name=".system.FallbackHome"
android:excludeFromRecents="true"
android:theme="@style/FallbackHome">
<intent-filter android:priority="-1000">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
其中包括home属性,这样影响后续识别home属性的应用,这里介绍一个过滤的办法:
https://www.cnblogs.com/crushgirl/p/13437967.html
android:excludeFromRecents="true"
在 Android 系统中,如果我们不想某个 Activity 出现在 “Recent screens” 中,可以设置这条属性:
2.3.packages\apps\Settings\src\com\android\settings\HomeSettings.java
private void buildHomeActivitiesList() {
ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities);
Context context = getPrefContext();
mCurrentHome = null;
mPrefGroup.removeAll();
mPrefs = new ArrayList<HomeAppPreference>();
mHomeComponentSet = new ComponentName[homeActivities.size()];
int prefIndex = 0;
boolean supportManagedProfilesExtra =
getActivity().getIntent().getBooleanExtra(EXTRA_SUPPORT_MANAGED_PROFILES, false);
boolean mustSupportManagedProfile = hasManagedProfile()
|| supportManagedProfilesExtra;
for (int i = 0; i < homeActivities.size(); i++) {
final ResolveInfo candidate = homeActivities.get(i);
final ActivityInfo info = candidate.activityInfo;
ComponentName activityName = new ComponentName(info.packageName, info.name);
mHomeComponentSet[i] = activityName;
try {
Drawable icon = info.loadIcon(mPm);
CharSequence name = info.loadLabel(mPm);
HomeAppPreference pref;
if (mustSupportManagedProfile && !launcherHasManagedProfilesFeature(candidate)) {
pref = new HomeAppPreference(context, activityName, prefIndex,
icon, name, this, info, false /* not enabled */,
getResources().getString(R.string.home_work_profile_not_supported));
} else {
pref = new HomeAppPreference(context, activityName, prefIndex,
icon, name, this, info, true /* enabled */, null);
}
//FLAG_EXCLUDE_FROM_RECENTS这里对应上述的属性 android:excludeFromRecents
if ((info.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) == 0){
mPrefs.add(pref);
mPrefGroup.addPreference(pref);
}
if (activityName.equals(currentDefaultHome)) {
mCurrentHome = pref;
}
prefIndex++;
} catch (Exception e) {
Log.v(TAG, "Problem dealing with activity " + activityName, e);
}
}
if (mCurrentHome != null) {
if (mCurrentHome.isEnabled()) {
getActivity().setResult(Activity.RESULT_OK);
}
new Handler().post(new Runnable() {
public void run() {
mCurrentHome.setChecked(true);
}
});
}
}
三.Android5.1 设置主launcher
3.1.frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
private void setDefaultLauncher() {
String packageName = SystemProperties.get("persist.app.pkgName","com.android.launcher3");
String className = SystemProperties.get("persist.app.className","com.android.launcher3.Launcher");
Slog.i(TAG, "defautl packageName = " + packageName + ", default className = " + className);
if ((packageName != null && packageName.trim().length() > 1) && (className != null && className.trim().length() > 0)) {
IPackageManager pm = ActivityThread.getPackageManager();
ArrayList<IntentFilter> intentList = new ArrayList<IntentFilter>();
ArrayList<ComponentName> cnList = new ArrayList<ComponentName>();
mContext.getPackageManager().getPreferredActivities(intentList, cnList, null);
IntentFilter dhIF;
for(int i = 0; i < cnList.size(); i++)
{
dhIF = intentList.get(i);
if(dhIF.hasAction(Intent.ACTION_MAIN) &&
dhIF.hasCategory(Intent.CATEGORY_HOME))
{
mContext.getPackageManager().clearPackagePreferredActivities(cnList.get(i).getPackageName());
}
}
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> list = new ArrayList<ResolveInfo>();
try
{
list = pm.queryIntentActivities(intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
PackageManager.MATCH_DEFAULT_ONLY,UserHandle.getCallingUserId());
}catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);
final int N = list.size();
ComponentName[] set = new ComponentName[N];
int bestMatch = 0;
for (int i = 0; i < N; i++)
{
ResolveInfo r = list.get(i);
set[i] = new ComponentName(r.activityInfo.packageName,r.activityInfo.name);
if (r.match > bestMatch) bestMatch = r.match;
}
ComponentName launcher = new ComponentName(packageName, className);
try
{
pm.addPreferredActivity(filter, bestMatch, set, launcher,UserHandle.getCallingUserId());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
}
}
3.2.setDefaultLauncher();
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
setDefaultLauncher();
Intent intent = getHomeIntent();
ActivityInfo aInfo =
resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
}
}
return true;
}
3.3.客户应用
罒.应用在category中配置了Home属性
<category android:name="android.intent.category.HOME" />
罒.设置属性
3.3.1
setProperty("persist.app.pkgName", "com.android.launcher3");// 包名
setProperty("persist.app.className", "com.android.launcher3.Launcher");// 类名
RootCommand("reboot");// 重启生效
3.3.2.
@SuppressWarnings("finally")
public String getProperty(String key) {
String value = "unknown";
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class, String.class);
value = (String) (get.invoke(c, key, "unknown"));
} catch (Exception e) {
e.printStackTrace();
} finally {
return value;
}
}
public void setProperty(String key, String value) {
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method set = c.getMethod("set", String.class, String.class);
set.invoke(c, key, value);
} catch (Exception e) {
e.printStackTrace();
}
}
public void RootCommand(String cmd) {
Process process = null;
DataOutputStream os = null;
DataInputStream is = null;
try {
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(cmd + "\n");
os.writeBytes("exit\n");
os.flush();
int aa = process.waitFor();
is = new DataInputStream(process.getInputStream());
byte[] buffer = new byte[is.available()];
is.read(buffer);
String out = new String(buffer);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
process.destroy();
} catch (Exception e) {
}
}
}
}

浙公网安备 33010602011771号