1 /* 2 * Copyright (C) 2021 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.enterprise; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.content.pm.UserInfo; 26 import android.content.res.Resources; 27 import android.net.ConnectivityManager; 28 import android.net.VpnManager; 29 import android.os.UserHandle; 30 import android.os.UserManager; 31 import android.provider.Settings; 32 import android.text.SpannableStringBuilder; 33 import android.text.style.ClickableSpan; 34 import android.view.View; 35 36 import com.android.tv.settings.R; 37 38 import java.util.Date; 39 import java.util.List; 40 41 public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFeatureProvider { 42 43 public static final String ACTION_PARENTAL_CONTROLS = "android.settings.SHOW_PARENTAL_CONTROLS"; 44 45 private final Context mContext; 46 private final DevicePolicyManager mDpm; 47 private final PackageManager mPm; 48 private final UserManager mUm; 49 private final ConnectivityManager mCm; 50 private final VpnManager mVm; 51 private final Resources mResources; 52 53 private static final int MY_USER_ID = UserHandle.myUserId(); 54 EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManager dpm, PackageManager pm, UserManager um, ConnectivityManager cm, VpnManager vm, Resources resources)55 public EnterprisePrivacyFeatureProviderImpl(Context context, DevicePolicyManager dpm, 56 PackageManager pm, UserManager um, ConnectivityManager cm, VpnManager vm, 57 Resources resources) { 58 mContext = context.getApplicationContext(); 59 mDpm = dpm; 60 mPm = pm; 61 mUm = um; 62 mCm = cm; 63 mVm = vm; 64 mResources = resources; 65 } 66 67 @Override hasDeviceOwner()68 public boolean hasDeviceOwner() { 69 return getDeviceOwnerComponent() != null; 70 } 71 72 @Override isInCompMode()73 public boolean isInCompMode() { 74 return hasDeviceOwner() && getManagedProfileUserId() != UserHandle.USER_NULL; 75 } 76 77 @Override getDeviceOwnerOrganizationName()78 public String getDeviceOwnerOrganizationName() { 79 final CharSequence organizationName = mDpm.getDeviceOwnerOrganizationName(); 80 if (organizationName == null) { 81 return null; 82 } else { 83 return organizationName.toString(); 84 } 85 } 86 87 @Override getDeviceOwnerDisclosure()88 public CharSequence getDeviceOwnerDisclosure() { 89 if (!hasDeviceOwner()) { 90 return null; 91 } 92 93 final SpannableStringBuilder disclosure = new SpannableStringBuilder(); 94 final CharSequence organizationName = mDpm.getDeviceOwnerOrganizationName(); 95 if (organizationName != null) { 96 disclosure.append(mResources.getString(R.string.do_disclosure_with_name, 97 organizationName)); 98 } else { 99 disclosure.append(mResources.getString(R.string.do_disclosure_generic)); 100 } 101 disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator)); 102 disclosure.append(mResources.getString(R.string.learn_more), 103 new EnterprisePrivacySpan(mContext), 0); 104 return disclosure; 105 } 106 107 @Override getLastSecurityLogRetrievalTime()108 public Date getLastSecurityLogRetrievalTime() { 109 final long timestamp = mDpm.getLastSecurityLogRetrievalTime(); 110 return timestamp < 0 ? null : new Date(timestamp); 111 } 112 113 @Override getLastBugReportRequestTime()114 public Date getLastBugReportRequestTime() { 115 final long timestamp = mDpm.getLastBugReportRequestTime(); 116 return timestamp < 0 ? null : new Date(timestamp); 117 } 118 119 @Override getLastNetworkLogRetrievalTime()120 public Date getLastNetworkLogRetrievalTime() { 121 final long timestamp = mDpm.getLastNetworkLogRetrievalTime(); 122 return timestamp < 0 ? null : new Date(timestamp); 123 } 124 125 @Override isSecurityLoggingEnabled()126 public boolean isSecurityLoggingEnabled() { 127 return mDpm.isSecurityLoggingEnabled(null); 128 } 129 130 @Override isNetworkLoggingEnabled()131 public boolean isNetworkLoggingEnabled() { 132 return mDpm.isNetworkLoggingEnabled(null); 133 } 134 135 @Override isAlwaysOnVpnSetInCurrentUser()136 public boolean isAlwaysOnVpnSetInCurrentUser() { 137 return mVm.getAlwaysOnVpnPackageForUser(MY_USER_ID) != null; 138 } 139 140 @Override isAlwaysOnVpnSetInManagedProfile()141 public boolean isAlwaysOnVpnSetInManagedProfile() { 142 final int managedProfileUserId = getManagedProfileUserId(); 143 return managedProfileUserId != UserHandle.USER_NULL && (mVm.getAlwaysOnVpnPackageForUser( 144 managedProfileUserId) != null); 145 } 146 147 @Override getMaximumFailedPasswordsBeforeWipeInCurrentUser()148 public int getMaximumFailedPasswordsBeforeWipeInCurrentUser() { 149 ComponentName owner = mDpm.getDeviceOwnerComponentOnCallingUser(); 150 if (owner == null) { 151 owner = mDpm.getProfileOwnerAsUser(MY_USER_ID); 152 } 153 if (owner == null) { 154 return 0; 155 } 156 return mDpm.getMaximumFailedPasswordsForWipe(owner, MY_USER_ID); 157 } 158 159 @Override getMaximumFailedPasswordsBeforeWipeInManagedProfile()160 public int getMaximumFailedPasswordsBeforeWipeInManagedProfile() { 161 final int userId = getManagedProfileUserId(); 162 if (userId == UserHandle.USER_NULL) { 163 return 0; 164 } 165 final ComponentName profileOwner = mDpm.getProfileOwnerAsUser(userId); 166 if (profileOwner == null) { 167 return 0; 168 } 169 return mDpm.getMaximumFailedPasswordsForWipe(profileOwner, userId); 170 } 171 172 @Override getImeLabelIfOwnerSet()173 public String getImeLabelIfOwnerSet() { 174 if (!mDpm.isCurrentInputMethodSetByOwner()) { 175 return null; 176 } 177 final String packageName = Settings.Secure.getStringForUser(mContext.getContentResolver(), 178 Settings.Secure.DEFAULT_INPUT_METHOD, MY_USER_ID); 179 if (packageName == null) { 180 return null; 181 } 182 try { 183 return mPm.getApplicationInfoAsUser(packageName, 0 /* flags */, MY_USER_ID) 184 .loadLabel(mPm).toString(); 185 } catch (PackageManager.NameNotFoundException e) { 186 return null; 187 } 188 } 189 190 @Override getNumberOfOwnerInstalledCaCertsForCurrentUser()191 public int getNumberOfOwnerInstalledCaCertsForCurrentUser() { 192 final List<String> certs = mDpm.getOwnerInstalledCaCerts(new UserHandle(MY_USER_ID)); 193 if (certs == null) { 194 return 0; 195 } 196 return certs.size(); 197 } 198 199 @Override getNumberOfOwnerInstalledCaCertsForManagedProfile()200 public int getNumberOfOwnerInstalledCaCertsForManagedProfile() { 201 final int userId = getManagedProfileUserId(); 202 if (userId == UserHandle.USER_NULL) { 203 return 0; 204 } 205 final List<String> certs = mDpm.getOwnerInstalledCaCerts(new UserHandle(userId)); 206 if (certs == null) { 207 return 0; 208 } 209 return certs.size(); 210 } 211 212 @Override getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile()213 public int getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile() { 214 int activeAdmins = 0; 215 for (final UserInfo userInfo : mUm.getProfiles(MY_USER_ID)) { 216 final List<ComponentName> activeAdminsForUser = mDpm.getActiveAdminsAsUser(userInfo.id); 217 if (activeAdminsForUser != null) { 218 activeAdmins += activeAdminsForUser.size(); 219 } 220 } 221 return activeAdmins; 222 } 223 224 @Override hasWorkPolicyInfo()225 public boolean hasWorkPolicyInfo() { 226 return (getWorkPolicyInfoIntentDO() != null) || (getWorkPolicyInfoIntentPO() != null); 227 } 228 229 @Override showWorkPolicyInfo()230 public boolean showWorkPolicyInfo() { 231 Intent intent = getWorkPolicyInfoIntentDO(); 232 if (intent != null) { 233 mContext.startActivity(intent); 234 return true; 235 } 236 237 intent = getWorkPolicyInfoIntentPO(); 238 final UserInfo userInfo = getManagedProfileUserInfo(); 239 if (intent != null && userInfo != null) { 240 mContext.startActivityAsUser(intent, userInfo.getUserHandle()); 241 return true; 242 } 243 244 return false; 245 } 246 247 @Override showParentalControls()248 public boolean showParentalControls() { 249 Intent intent = getParentalControlsIntent(); 250 if (intent != null) { 251 mContext.startActivity(intent); 252 return true; 253 } 254 255 return false; 256 } 257 getParentalControlsIntent()258 private Intent getParentalControlsIntent() { 259 final ComponentName componentName = 260 mDpm.getProfileOwnerOrDeviceOwnerSupervisionComponent(new UserHandle(MY_USER_ID)); 261 if (componentName == null) { 262 return null; 263 } 264 265 final Intent intent = new Intent(ACTION_PARENTAL_CONTROLS) 266 .setPackage(componentName.getPackageName()) 267 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 268 final List<ResolveInfo> activities = mPm.queryIntentActivitiesAsUser(intent, 0, MY_USER_ID); 269 if (activities.size() != 0) { 270 return intent; 271 } 272 return null; 273 } 274 getDeviceOwnerComponent()275 private ComponentName getDeviceOwnerComponent() { 276 if (!mPm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) { 277 return null; 278 } 279 return mDpm.getDeviceOwnerComponentOnAnyUser(); 280 } 281 getManagedProfileUserInfo()282 private UserInfo getManagedProfileUserInfo() { 283 for (final UserInfo userInfo : mUm.getProfiles(MY_USER_ID)) { 284 if (userInfo.isManagedProfile()) { 285 return userInfo; 286 } 287 } 288 return null; 289 } 290 getManagedProfileUserId()291 private int getManagedProfileUserId() { 292 final UserInfo userInfo = getManagedProfileUserInfo(); 293 if (userInfo != null) { 294 return userInfo.id; 295 } 296 return UserHandle.USER_NULL; 297 } 298 getWorkPolicyInfoIntentDO()299 private Intent getWorkPolicyInfoIntentDO() { 300 final ComponentName ownerComponent = getDeviceOwnerComponent(); 301 if (ownerComponent == null) { 302 return null; 303 } 304 305 // Only search for the required action in the Device Owner's package 306 final Intent intent = 307 new Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO) 308 .setPackage(ownerComponent.getPackageName()) 309 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 310 final List<ResolveInfo> activities = mPm.queryIntentActivities(intent, 0); 311 if (activities.size() != 0) { 312 return intent; 313 } 314 315 return null; 316 } 317 getWorkPolicyInfoIntentPO()318 private Intent getWorkPolicyInfoIntentPO() { 319 final int userId = getManagedProfileUserId(); 320 if (userId == UserHandle.USER_NULL) { 321 return null; 322 } 323 324 final ComponentName ownerComponent = mDpm.getProfileOwnerAsUser(userId); 325 if (ownerComponent == null) { 326 return null; 327 } 328 329 // Only search for the required action in the Profile Owner's package 330 final Intent intent = 331 new Intent(Settings.ACTION_SHOW_WORK_POLICY_INFO) 332 .setPackage(ownerComponent.getPackageName()) 333 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 334 final List<ResolveInfo> activities = mPm.queryIntentActivitiesAsUser(intent, 0, userId); 335 if (activities.size() != 0) { 336 return intent; 337 } 338 339 return null; 340 } 341 342 protected static class EnterprisePrivacySpan extends ClickableSpan { 343 private final Context mContext; 344 EnterprisePrivacySpan(Context context)345 public EnterprisePrivacySpan(Context context) { 346 mContext = context; 347 } 348 349 @Override onClick(View widget)350 public void onClick(View widget) { 351 mContext.startActivity(new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS) 352 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 353 } 354 355 @Override equals(Object object)356 public boolean equals(Object object) { 357 return object instanceof EnterprisePrivacySpan 358 && ((EnterprisePrivacySpan) object).mContext == mContext; 359 } 360 } 361 } 362