A bug of user switch funtion in Android5 and its fix in Android7

In Android 5, user switching function is implemented by AMS.

In frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

20367    public boolean switchUser(final int userId) {
20368        // fosmod_multiple_users begin
20369        return switchUser(userId, true);
20370    }
20371
20372    public boolean switchUser(final int userId, final boolean showKeyguard) {
20373        mShowKeyguard = showKeyguard;
20374        // fosmod_multiple_users end
20375        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20376        String userName;
20383        synchronized (this) {
20384            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
20385            if (userInfo == null) {
20386                Slog.w(TAG, "No user info for user #" + userId);
20387                return false;
20388            }
20389            if (userInfo.isManagedProfile()) {
20390                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
20391                return false;
20392            }
20393            userName = userInfo.name;
20394            mTargetUserId = userId;
20395        }
20396        mHandler.removeMessages(START_USER_SWITCH_MSG);
20397        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
20398        return true;
20399    }

1825            case START_USER_SWITCH_MSG: {
1826                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1827                break;
1828            }

20401    private void showUserSwitchDialog(int userId, String userName) {
20408            Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
20409                    true /* above system */);
20410            d.show();
20413    }

It create an Alert dialog (showUserSwitchDialog) and show it. The dialog is to indicate that system is switching user.
In frameworks/base/services/core/java/com/android/server/am/UserSwitchingDialog.java

68    @Override
69    public void show() {
70        // Slog.v(TAG, "show called");
71        super.show();     // show dialog
72        final View decorView = getWindow().getDecorView();
73        if (decorView != null) {
74            decorView.getViewTreeObserver().addOnWindowShownListener(this);      // register listener, so onWindowShown will be called if dialog is shown on the screen.
75        }
76    }
77
78    @Override
79    public void onWindowShown() {
80        // Slog.v(TAG, "onWindowShown called");
81        mService.startUserInForeground(mUserId, this);    // In the callback function, it will call AMS.startUserInForeground
82        final View decorView = getWindow().getDecorView();
83        if (decorView != null) {
84            decorView.getViewTreeObserver().removeOnWindowShownListener(this);
85        }
86    }

In frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
20324    boolean startUserInForeground(final int userId, Dialog dlg) {
20325        boolean result = startUser(userId, /* foreground */ true);       // do user switching operations.
20326        dlg.dismiss();      // dismiss the dialog
20327        return result;
20328    }

But onWindowShown method will no be called if screen is off. So there may be a special case that user click "user switching" button first, and quickly click power key.
In this case UserSwitchingDialog will be shown, but onWindowShown method will not be called. So system will not switch user, and the dialog will not be dismissed.
And user can do nothing on the screen because the dialog is on the top of all window. Its window type is WindowManager.LayoutParams.TYPE_SYSTEM_ERROR.

In Android N, there is a fix for this issue.
commit 5e5cb463b6e2540a7ef6c261ba5fed074be536e1
Author: Amith Yamasani <yamasani@google.com>
Date:   Mon Feb 9 15:45:26 2015 -0800

    Timeout to ensure user-switching dialog is closed
    
    In the event of user-switch invoked by a remote device admin call,
    the window manager does not make window-shown callbacks when the
    screen is off. Add a timeout to continue the user switch in case
    the callback doesn't come through.
    
    This fixes a stuck "Switching to user.." dialog when a profile
    owner requests a user wipe.
    
    Bug: 19275716
    Change-Id: I3a51bbaaf3d9ac6c006464360f1146b2499d205b



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值