1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.settings.users;
18 
19 import android.app.ActivityManager;
20 import android.app.Service;
21 import android.app.UserSwitchObserver;
22 import android.content.BroadcastReceiver;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.content.SharedPreferences;
28 import android.content.pm.PackageManager;
29 import android.os.IBinder;
30 import android.os.RemoteException;
31 import android.os.UserHandle;
32 import android.os.UserManager;
33 import android.util.Log;
34 
35 import com.android.internal.widget.LockPatternUtils;
36 
37 public class UserSwitchListenerService extends Service {
38 
39     private static final boolean DEBUG = false;
40     private static final String TAG = "RestrictedProfile";
41 
42     private static final String RESTRICTED_PROFILE_LAUNCHER_ENTRY_ACTIVITY =
43             "com.android.tv.settings.users.RestrictedProfileActivityLauncherEntry";
44     private static final String SHARED_PREFERENCES_NAME = "RestrictedProfileSharedPreferences";
45     private static final String
46             ON_BOOT_USER_ID_PREFERENCE = "UserSwitchOnBootBroadcastReceiver.userId";
47 
48     public static class BootReceiver extends BroadcastReceiver {
49         @Override
onReceive(final Context context, Intent intent)50         public void onReceive(final Context context, Intent intent) {
51 
52             boolean isSystemUser = UserManager.get(context).isSystemUser();
53 
54             if (isSystemUser) {
55                 context.startService(new Intent(context, UserSwitchListenerService.class));
56                 if (DEBUG) {
57                     Log.d(TAG, "boot completed, user is " + UserHandle.myUserId()
58                             + " boot user id: " + getBootUser(context));
59                 }
60             }
61         }
62     }
63 
64     private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
65         @Override
66         public void onReceive(Context context, Intent intent) {
67             switchToLastUserIfUnlocked();
68         }
69     };
70 
updateLaunchPoint(Context context, boolean enableLaunchPoint)71     public static void updateLaunchPoint(Context context, boolean enableLaunchPoint) {
72         if (DEBUG) {
73             Log.d(TAG, "updating launch point: " + enableLaunchPoint);
74         }
75 
76         PackageManager pm = context.getPackageManager();
77         ComponentName compName = new ComponentName(context,
78                 RESTRICTED_PROFILE_LAUNCHER_ENTRY_ACTIVITY);
79         pm.setComponentEnabledSetting(compName,
80                 enableLaunchPoint ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
81                         : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
82                 PackageManager.DONT_KILL_APP);
83     }
84 
setBootUser(Context context, int userId)85     static void setBootUser(Context context, int userId) {
86         SharedPreferences.Editor editor = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
87                 Context.MODE_PRIVATE).edit();
88         editor.putInt(ON_BOOT_USER_ID_PREFERENCE, userId);
89         editor.apply();
90     }
91 
getBootUser(Context context)92     static int getBootUser(Context context) {
93         SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
94                 Context.MODE_PRIVATE);
95         return prefs.getInt(ON_BOOT_USER_ID_PREFERENCE, UserHandle.USER_SYSTEM);
96     }
97 
switchUserNow(int userId)98     private static void switchUserNow(int userId) {
99         try {
100             ActivityManager.getService().switchUser(userId);
101         } catch (RemoteException re) {
102             Log.e(TAG, "Caught exception while switching user! ", re);
103         }
104     }
105 
106     @Override
onCreate()107     public void onCreate() {
108         super.onCreate();
109         try {
110             ActivityManager.getService().registerUserSwitchObserver(
111                     new UserSwitchObserver() {
112                         @Override
113                         public void onUserSwitchComplete(int newUserId) throws RemoteException {
114                             if (DEBUG) {
115                                 Log.d(TAG, "user has been foregrounded: " + newUserId);
116                             }
117                             setBootUser(UserSwitchListenerService.this, newUserId);
118                         }
119                     }, UserSwitchListenerService.class.getName());
120         } catch (RemoteException e) {
121         }
122 
123         registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
124         switchToLastUserIfUnlocked();
125     }
126 
127     @Override
onDestroy()128     public void onDestroy() {
129         super.onDestroy();
130         unregisterReceiver(mUserUnlockedReceiver);
131     }
132 
133     @Override
onStartCommand(Intent intent, int flags, int startId)134     public int onStartCommand(Intent intent, int flags, int startId) {
135         return START_STICKY;
136     }
137 
138     @Override
onBind(Intent intent)139     public IBinder onBind(Intent intent) {
140         return null;
141     }
142 
switchToLastUserIfUnlocked()143     private void switchToLastUserIfUnlocked() {
144         if (!UserManager.get(this).isUserUnlocked()) return;
145 
146         boolean isFbeEnabled = LockPatternUtils.isFileEncryptionEnabled();
147         boolean hasLockscreenSecurity = new LockPatternUtils(this).isSecure(getUserId());
148 
149         // If the device is FBE-enabled and has a lockscreen password, the user is asked
150         // to enter the PIN on boot so there is no need to switch back to the last user.
151         if (!isFbeEnabled || !hasLockscreenSecurity) {
152             int bootUserId = getBootUser(this);
153             if (UserHandle.myUserId() != bootUserId) {
154                 switchUserNow(bootUserId);
155             }
156         }
157 
158         updateLaunchPoint(this, new RestrictedProfileModel(this).getUser() != null);
159     }
160 }
161