1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui.statusbar.phone; 16 17 import android.app.StatusBarManager; 18 import android.content.Context; 19 import android.content.pm.UserInfo; 20 import android.os.UserHandle; 21 import android.os.UserManager; 22 23 import androidx.annotation.NonNull; 24 25 import com.android.systemui.dagger.SysUISingleton; 26 import com.android.systemui.dagger.qualifiers.Main; 27 import com.android.systemui.settings.UserTracker; 28 29 import java.util.ArrayList; 30 import java.util.LinkedList; 31 import java.util.List; 32 import java.util.concurrent.Executor; 33 34 import javax.inject.Inject; 35 36 @SysUISingleton 37 public class ManagedProfileControllerImpl implements ManagedProfileController { 38 39 private final List<Callback> mCallbacks = new ArrayList<>(); 40 private final UserTrackerCallback mUserTrackerCallback = new UserTrackerCallback(); 41 private final Context mContext; 42 private final Executor mMainExecutor; 43 private final UserManager mUserManager; 44 private final UserTracker mUserTracker; 45 private final LinkedList<UserInfo> mProfiles; 46 47 private boolean mListening; 48 private int mCurrentUser; 49 50 @Inject ManagedProfileControllerImpl(Context context, @Main Executor mainExecutor, UserTracker userTracker, UserManager userManager)51 public ManagedProfileControllerImpl(Context context, @Main Executor mainExecutor, 52 UserTracker userTracker, UserManager userManager) { 53 mContext = context; 54 mMainExecutor = mainExecutor; 55 mUserManager = userManager; 56 mUserTracker = userTracker; 57 mProfiles = new LinkedList<>(); 58 } 59 60 @Override addCallback(@onNull Callback callback)61 public void addCallback(@NonNull Callback callback) { 62 mCallbacks.add(callback); 63 if (mCallbacks.size() == 1) { 64 setListening(true); 65 } 66 callback.onManagedProfileChanged(); 67 } 68 69 @Override removeCallback(@onNull Callback callback)70 public void removeCallback(@NonNull Callback callback) { 71 if (mCallbacks.remove(callback) && mCallbacks.size() == 0) { 72 setListening(false); 73 } 74 } 75 setWorkModeEnabled(boolean enableWorkMode)76 public void setWorkModeEnabled(boolean enableWorkMode) { 77 synchronized (mProfiles) { 78 for (UserInfo ui : mProfiles) { 79 if (!mUserManager.requestQuietModeEnabled(!enableWorkMode, UserHandle.of(ui.id))) { 80 StatusBarManager statusBarManager = (StatusBarManager) mContext 81 .getSystemService(android.app.Service.STATUS_BAR_SERVICE); 82 statusBarManager.collapsePanels(); 83 } 84 } 85 } 86 } 87 reloadManagedProfiles()88 private void reloadManagedProfiles() { 89 synchronized (mProfiles) { 90 boolean hadProfile = mProfiles.size() > 0; 91 int user = mUserTracker.getUserId(); 92 mProfiles.clear(); 93 94 for (UserInfo ui : mUserManager.getEnabledProfiles(user)) { 95 if (ui.isManagedProfile()) { 96 mProfiles.add(ui); 97 } 98 } 99 if (mProfiles.size() == 0 && hadProfile && (user == mCurrentUser)) { 100 mMainExecutor.execute(this::notifyManagedProfileRemoved); 101 } 102 mCurrentUser = user; 103 } 104 } 105 notifyManagedProfileRemoved()106 private void notifyManagedProfileRemoved() { 107 for (Callback callback : mCallbacks) { 108 callback.onManagedProfileRemoved(); 109 } 110 } 111 hasActiveProfile()112 public boolean hasActiveProfile() { 113 if (!mListening || mUserTracker.getUserId() != mCurrentUser) { 114 reloadManagedProfiles(); 115 } 116 synchronized (mProfiles) { 117 return mProfiles.size() > 0; 118 } 119 } 120 isWorkModeEnabled()121 public boolean isWorkModeEnabled() { 122 if (!mListening) reloadManagedProfiles(); 123 synchronized (mProfiles) { 124 for (UserInfo ui : mProfiles) { 125 if (ui.isQuietModeEnabled()) { 126 return false; 127 } 128 } 129 return true; 130 } 131 } 132 setListening(boolean listening)133 private void setListening(boolean listening) { 134 if (mListening == listening) { 135 return; 136 } 137 mListening = listening; 138 if (listening) { 139 reloadManagedProfiles(); 140 mUserTracker.addCallback(mUserTrackerCallback, mMainExecutor); 141 } else { 142 mUserTracker.removeCallback(mUserTrackerCallback); 143 } 144 } 145 146 private final class UserTrackerCallback implements UserTracker.Callback { 147 148 @Override onUserChanged(int newUser, @NonNull Context userContext)149 public void onUserChanged(int newUser, @NonNull Context userContext) { 150 reloadManagedProfiles(); 151 for (Callback callback : mCallbacks) { 152 callback.onManagedProfileChanged(); 153 } 154 } 155 156 @Override onProfilesChanged(@onNull List<UserInfo> profiles)157 public void onProfilesChanged(@NonNull List<UserInfo> profiles) { 158 reloadManagedProfiles(); 159 for (Callback callback : mCallbacks) { 160 callback.onManagedProfileChanged(); 161 } 162 } 163 } 164 } 165