Android L使用adb命令获取FocusedApp 包名错误(原生bug)

一、命令如下

adb shell dumpsys window windows | grep -E "mCurrentFocus | mFocusedApp" | egrep "ActivityRecord.*" | cut -d " " -f7 | cut -d "/" -f1

通过adb shell dumpsys window windows命令可以得知以上命令获取的是什么内容:

  mCurConfiguration={1.0 ?mcc?mnc en_US ?layoutDir sw320dp w320dp h544dp 240dpi nrml long port finger -keyb/v/h -nav/h s.5}
  mHasPermanentDpad=false
  mCurrentFocus=Window{343a0a2c u0 com.tct.launcher/com.tct.launcher.Launcher}
  mFocusedApp=AppWindowToken{158efe19 token=Token{1f33d960 ActivityRecord{3ad78963 u0 com.tct.launcher/.Launcher t56}}}

二、步骤

  1. root@aclgcl-ubnt:~# 桌面执行命令  
  2. root@aclgcl-ubnt:~# adb shell dumpsys window windows | grep -E "mCurrentFocus | mFocusedApp" | egrep "ActivityRecord.*" | cut -d " " -f7 | cut -d "/" -f1  
  3. com.tct.launcher  
  4. root@aclgcl-ubnt:~#   
  5. root@aclgcl-ubnt:~# 下面点击mms后执行命令  
  6. root@aclgcl-ubnt:~# adb shell dumpsys window windows | grep -E "mCurrentFocus | mFocusedApp" | egrep "ActivityRecord.*" | cut -d " " -f7 | cut -d "/" -f1  
  7. com.android.mms  
  8. root@aclgcl-ubnt:~#   
  9. root@aclgcl-ubnt:~# 按Home键回到桌面执行命令  
  10. root@aclgcl-ubnt:~# adb shell dumpsys window windows | grep -E "mCurrentFocus | mFocusedApp" | egrep "ActivityRecord.*" | cut -d " " -f7 | cut -d "/" -f1  
  11. com.android.mms  
  12.    
root@aclgcl-ubnt:~# 桌面执行命令
root@aclgcl-ubnt:~# adb shell dumpsys window windows | grep -E "mCurrentFocus | mFocusedApp" | egrep "ActivityRecord.*" | cut -d " " -f7 | cut -d "/" -f1
com.tct.launcher
root@aclgcl-ubnt:~# 
root@aclgcl-ubnt:~# 下面点击mms后执行命令
root@aclgcl-ubnt:~# adb shell dumpsys window windows | grep -E "mCurrentFocus | mFocusedApp" | egrep "ActivityRecord.*" | cut -d " " -f7 | cut -d "/" -f1
com.android.mms
root@aclgcl-ubnt:~# 
root@aclgcl-ubnt:~# 按Home键回到桌面执行命令
root@aclgcl-ubnt:~# adb shell dumpsys window windows | grep -E "mCurrentFocus | mFocusedApp" | egrep "ActivityRecord.*" | cut -d " " -f7 | cut -d "/" -f1
com.android.mms
 

 返回桌面后执行命令得到的结果不正确。 
 

三、分析

从adb shell dumpsys window windows结果来看,即为mFocusedApp获取错误,mFocusedApp的设置在WMS中:

  1. @Override  
  2. public void setFocusedApp(IBinder token, boolean moveFocusNow) {  
  3.     if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,  
  4.             "setFocusedApp()")) {  
  5.         throw new SecurityException("Requires MANAGE_APP_TOKENS permission");  
  6.     }  
  7.   
  8.     synchronized(mWindowMap) {  
  9.         final AppWindowToken newFocus;  
  10.         if (token == null) {  
  11.             if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);  
  12.             newFocus = null;  
  13.         } else {  
  14.             newFocus = findAppWindowToken(token);  
  15.             if (newFocus == null) {  
  16.                 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);  
  17.             }  
  18.             if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus  
  19.                     + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);  
  20.         }  
  21.   
  22.         final boolean changed = mFocusedApp != newFocus;  
  23.         if (changed) {  
  24.             mFocusedApp = newFocus;  
  25.             mInputMonitor.setFocusedAppLw(newFocus);  
  26.         }  
  27.   
  28.         if (moveFocusNow && changed) {  
  29.             final long origId = Binder.clearCallingIdentity();  
  30.             updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);  
  31.             Binder.restoreCallingIdentity(origId);  
  32.         }  
  33.     }  
  34. }  
    @Override
    public void setFocusedApp(IBinder token, boolean moveFocusNow) {
        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                "setFocusedApp()")) {
            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
        }

        synchronized(mWindowMap) {
            final AppWindowToken newFocus;
            if (token == null) {
                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
                newFocus = null;
            } else {
                newFocus = findAppWindowToken(token);
                if (newFocus == null) {
                    Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
                }
                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus
                        + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
            }

            final boolean changed = mFocusedApp != newFocus;
            if (changed) {
                mFocusedApp = newFocus;
                mInputMonitor.setFocusedAppLw(newFocus);
            }

            if (moveFocusNow && changed) {
                final long origId = Binder.clearCallingIdentity();
                updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
                Binder.restoreCallingIdentity(origId);
            }
        }
    }

setFocusedApp在AMS中调用:

  1. final void setFocusedActivityLocked(ActivityRecord r, String reason) {  
  2.     if (mFocusedActivity != r) {  
  3.         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);  
  4.         mFocusedActivity = r;  
  5.         if (r.task != null && r.task.voiceInteractor != null) {  
  6.             startRunningVoiceLocked();  
  7.         } else {  
  8.             finishRunningVoiceLocked();  
  9.         }  
  10.         mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");  
  11.         if (r != null) {  
  12.             <span style="color:#FF0000;"><strong>mWindowManager.setFocusedApp(r.appToken, true);</strong></span>  
  13.         }  
  14.         applyUpdateLockStateLocked(r);  
  15.     }  
  16.     EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,  
  17.             mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);  
  18. }  
    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
        if (mFocusedActivity != r) {
            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
            mFocusedActivity = r;
            if (r.task != null && r.task.voiceInteractor != null) {
                startRunningVoiceLocked();
            } else {
                finishRunningVoiceLocked();
            }
            mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
            if (r != null) {
                mWindowManager.setFocusedApp(r.appToken, true);
            }
            applyUpdateLockStateLocked(r);
        }
        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
    }

继续追踪setFocusedActivityLocked的几处调用,分别打log跟踪,发现当从mms按home键回到桌面的时候setFocusedActivityLocked方法没有被调用到,,,随后翻阅ActivityStack.java中的adjustFocusedActivityLocked方法所调用setFocusedActivityLocked的逻辑,

  1. private void adjustFocusedActivityLocked(ActivityRecord r, String reason) {  
  2.     <span style="color:#FF0000;"><strong>if (mStackSupervisor.isFrontStack(this) && mService.mFocusedActivity == r) {</strong></span>  
  3.         ActivityRecord next = topRunningActivityLocked(null);  
  4.         if (next != r) {  
  5.             final TaskRecord task = r.task;  
  6.             if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {  
  7.                 mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(),  
  8.                         reason + " adjustFocus");  
  9.             }  
  10.         }  
  11.         ActivityRecord top = mStackSupervisor.topRunningActivityLocked();  
  12.         if (top != null) {  
  13.             <span style="color:#FF0000;"><strong>mService.setFocusedActivityLocked(top, reason + " adjustTopFocus");</strong></span>  
  14.         }  
  15.     }  
  16. }  
    private void adjustFocusedActivityLocked(ActivityRecord r, String reason) {
        if (mStackSupervisor.isFrontStack(this) && mService.mFocusedActivity == r) {
            ActivityRecord next = topRunningActivityLocked(null);
            if (next != r) {
                final TaskRecord task = r.task;
                if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
                    mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(),
                            reason + " adjustFocus");
                }
            }
            ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
            if (top != null) {
                mService.setFocusedActivityLocked(top, reason + " adjustTopFocus");
            }
        }
    }
  1. final void stopActivityLocked(ActivityRecord r) {  
  2.     if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);  
  3.     if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0  
  4.             || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {  
  5.         if (!r.finishing) {  
  6.             if (!mService.isSleeping()) {  
  7.                 if (DEBUG_STATES) {  
  8.                     Slog.d(TAG, "no-history finish of " + r);  
  9.                 }  
  10.                 requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,  
  11.                         "no-history"false);  
  12.             } else {  
  13.                 if (DEBUG_STATES) Slog.d(TAG, "Not finishing noHistory " + r  
  14.                         + " on stop because we're just sleeping");  
  15.             }  
  16.         }  
  17.     }  
  18.   
  19.     if (r.app != null && r.app.thread != null) {  
  20.         <span style="color:#FF0000;"><strong>adjustFocusedActivityLocked(r, "stopActivity");</strong></span>  
  21.         r.resumeKeyDispatchingLocked();  
    final void stopActivityLocked(ActivityRecord r) {
        if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);
        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
            if (!r.finishing) {
                if (!mService.isSleeping()) {
                    if (DEBUG_STATES) {
                        Slog.d(TAG, "no-history finish of " + r);
                    }
                    requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "no-history", false);
                } else {
                    if (DEBUG_STATES) Slog.d(TAG, "Not finishing noHistory " + r
                            + " on stop because we're just sleeping");
                }
            }
        }

        if (r.app != null && r.app.thread != null) {
            adjustFocusedActivityLocked(r, "stopActivity");
            r.resumeKeyDispatchingLocked();

在从mms回到launcher的时候,mms的activity被stop,所以应当是从adjustFocusedActivityLocked调用的setFocusedActivityLocked,所以是上面加红加粗的条件没有走进去,继续跟踪,查看isFrontStack()方法,

  1. boolean isFrontStack(ActivityStack stack) {  
  2.     final ActivityRecord parent = stack.mActivityContainer.mParentActivity;  
  3.     if (parent != null) {  
  4.         stack = parent.task.stack;  
  5.     }  
  6.     ArrayList<ActivityStack> stacks = stack.mStacks;  
  7.     if (stacks != null && !stacks.isEmpty()) {  
  8.         return stack == stacks.get(stacks.size() - 1);  
  9.     }  
  10.     return false;  
  11. }  
    boolean isFrontStack(ActivityStack stack) {
        final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
        if (parent != null) {
            stack = parent.task.stack;
        }
        ArrayList<ActivityStack> stacks = stack.mStacks;
        if (stacks != null && !stacks.isEmpty()) {
            return stack == stacks.get(stacks.size() - 1);
        }
        return false;
    }

通过log发现mStackSupervisor.isFrontStack(this)总是不成立,this是切换之前的stack,即MMS所在的stack,继续查看Android M中的代码,发现moveTaskToFrontLocked方法中也调用了mService.setFocusedActivityLocked(r, reason);,

  1.     final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, Bundle options,  
  2.             AppTimeTracker timeTracker, String reason) {  
  3.         System.out.println("ran.zhou-AS-L3721-moveTaskToFrontLocked");  
  4.         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);  
  5.   
  6.         final int numTasks = mTaskHistory.size();  
  7.         final int index = mTaskHistory.indexOf(tr);  
  8. 。。。  
  9. 。。。  
  10.         // Shift all activities with this task up to the top  
  11.         // of the stack, keeping them in the same internal order.  
  12.         insertTaskAtTop(tr, null);  
  13.   
  14.         // Set focus to the top running activity of this stack.  
  15.         ActivityRecord r = topRunningActivityLocked(null);  
  16.         <span style="color:#FF0000;"><strong>mService.setFocusedActivityLocked(r, reason);</strong></span>  
  17.   
  18.         if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);  
  19.         if (noAnimation) {  
  20.             mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);  
  21.             if (r != null) {  
  22.                 mNoAnimActivities.add(r);  
  23.             }  
  24.             ActivityOptions.abort(options);  
  25.         } else {  
  26.             updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);  
  27.         }  
    final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, Bundle options,
            AppTimeTracker timeTracker, String reason) {
        System.out.println("ran.zhou-AS-L3721-moveTaskToFrontLocked");
        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);

        final int numTasks = mTaskHistory.size();
        final int index = mTaskHistory.indexOf(tr);
。。。
。。。
        // Shift all activities with this task up to the top
        // of the stack, keeping them in the same internal order.
        insertTaskAtTop(tr, null);

        // Set focus to the top running activity of this stack.
        ActivityRecord r = topRunningActivityLocked(null);
        mService.setFocusedActivityLocked(r, reason);

        if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
        if (noAnimation) {
            mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
            if (r != null) {
                mNoAnimActivities.add(r);
            }
            ActivityOptions.abort(options);
        } else {
            updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
        }

此处调用setFocusedActivityLocked方法走的不是stopActivity那条路了,而是ActivityStackSupervisor.java中的startActivityUncheckedLocked方法中,

  1.     final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,  
  2.             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,  
  3.             boolean doResume, Bundle options, TaskRecord inTask) {  
  4.         final Intent intent = r.intent;  
  5.         final int callingUid = r.launchedFromUid;  
  6. 。。。。。。。  
  7. 。。。。。。。  
  8.                             targetStack.<span style="color:#FF0000;"><strong>moveTaskToFrontLocked</strong></span>(intentActivity.task, noAnimation,  
  9.                                     options, r.appTimeTracker, "bringingFoundTaskToFront");  
    final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
            boolean doResume, Bundle options, TaskRecord inTask) {
        final Intent intent = r.intent;
        final int callingUid = r.launchedFromUid;
。。。。。。。
。。。。。。。
                            targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation,
                                    options, r.appTimeTracker, "bringingFoundTaskToFront");

所以M中的处理是在moveTaskToFrontLocked加一个调用setFocusedActivityLocked。

android M中对stopActivity的逻辑也是和Android L中一样,那个if条件走不进去,个人认为这里依然是Google的代码缺陷。


四、解决方案

仿照M中的处理,在moveTaskToFrontLocked加一个调用setFocusedActivityLocked。

  1. //Added by xxx for PR-1150738 Begin  
  2. // Set focus to the top running activity of this stack.  
  3. ActivityRecord r = topRunningActivityLocked(null);  
  4. mService.setFocusedActivityLocked(r, reason);  
  5. //Added by xxx for PR-1150738 End  
        //Added by xxx for PR-1150738 Begin
        // Set focus to the top running activity of this stack.
        ActivityRecord r = topRunningActivityLocked(null);
        mService.setFocusedActivityLocked(r, reason);
        //Added by xxx for PR-1150738 End




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值