您的位置:首页 > 移动开发 > Android开发

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

2017-04-05 20:32 579 查看
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    }

[code]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
[code]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
[/code]
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐