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

1
2
3
4
5
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"

1
2
3
4
5
6
7
8
9
10
<!-- 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

1
android:excludeFromRecents="true"  

在 Android 系统中,如果我们不想某个 Activity 出现在 “Recent screens” 中,可以设置这条属性:

2.3.packages\apps\Settings\src\com\android\settings\HomeSettings.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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.客户应用

  

  

  

  

  

posted @   CrushGirl  阅读(819)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示