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.systemui.car.systemdialogs; 18 19 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; 20 import static android.view.WindowInsets.Type.statusBars; 21 22 import android.app.AlertDialog; 23 import android.content.Context; 24 import android.content.DialogInterface; 25 import android.content.Intent; 26 import android.provider.Settings; 27 import android.view.LayoutInflater; 28 import android.view.View; 29 import android.view.Window; 30 import android.view.WindowManager; 31 import android.widget.TextView; 32 33 import androidx.annotation.Nullable; 34 35 import com.android.systemui.R; 36 import com.android.systemui.dagger.SysUISingleton; 37 import com.android.systemui.settings.UserTracker; 38 import com.android.systemui.statusbar.policy.SecurityController; 39 40 import javax.inject.Inject; 41 42 /** 43 * A controller that can create and control the visibility of various system dialogs. 44 */ 45 @SysUISingleton 46 public class SystemDialogsViewController { 47 private final Context mContext; 48 private final SecurityController mSecurityController; 49 private final AlertDialog.OnClickListener mOnDeviceMonitoringDialogClickListener; 50 51 @Inject SystemDialogsViewController( Context context, SecurityController securityController, UserTracker userTracker)52 public SystemDialogsViewController( 53 Context context, 54 SecurityController securityController, 55 UserTracker userTracker) { 56 mContext = context; 57 mSecurityController = securityController; 58 mOnDeviceMonitoringDialogClickListener = (dialog, which) -> { 59 dialog.dismiss(); 60 if (which == DialogInterface.BUTTON_NEUTRAL) { 61 Intent intent = new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS); 62 mContext.startActivityAsUser(intent, userTracker.getUserHandle()); 63 } 64 }; 65 } 66 showDeviceMonitoringDialog()67 protected void showDeviceMonitoringDialog() { 68 AlertDialog dialog = new AlertDialog.Builder(mContext, 69 com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert) 70 .setView(createDialogView()) 71 .setPositiveButton(R.string.ok, mOnDeviceMonitoringDialogClickListener) 72 .setNeutralButton(R.string.monitoring_button_view_policies, 73 mOnDeviceMonitoringDialogClickListener) 74 .create(); 75 76 applyCarSysUIDialogFlags(dialog); 77 dialog.show(); 78 } 79 createDialogView()80 private View createDialogView() { 81 View dialogView = LayoutInflater.from(mContext) 82 .inflate(R.layout.device_management_dialog, null, false); 83 84 CharSequence deviceOwnerOrganization = mSecurityController.getDeviceOwnerOrganizationName(); 85 boolean isDeviceManaged = mSecurityController.isDeviceManaged(); 86 87 // device management section 88 TextView deviceManagementSubtitle = 89 dialogView.requireViewById(R.id.device_management_subtitle); 90 deviceManagementSubtitle.setText(getDeviceMonitoringTitle(deviceOwnerOrganization)); 91 92 CharSequence managementMessage = getDeviceMonitoringMessage(deviceOwnerOrganization); 93 if (managementMessage == null) { 94 dialogView.requireViewById(R.id.device_management_disclosures).setVisibility(View.GONE); 95 } else { 96 dialogView.requireViewById(R.id.device_management_disclosures) 97 .setVisibility(View.VISIBLE); 98 TextView deviceManagementWarning = 99 dialogView.requireViewById(R.id.device_management_warning); 100 deviceManagementWarning.setText(managementMessage); 101 } 102 103 // CA certificate section 104 CharSequence caCertsMessage = getCaCertsMessage(isDeviceManaged); 105 if (caCertsMessage == null) { 106 dialogView.requireViewById(R.id.ca_certs_disclosures).setVisibility(View.GONE); 107 } else { 108 dialogView.requireViewById(R.id.ca_certs_disclosures).setVisibility(View.VISIBLE); 109 TextView caCertsWarning = dialogView.requireViewById(R.id.ca_certs_warning); 110 caCertsWarning.setText(caCertsMessage); 111 } 112 113 // network logging section 114 CharSequence networkLoggingMessage = getNetworkLoggingMessage(isDeviceManaged); 115 if (networkLoggingMessage == null) { 116 dialogView.requireViewById(R.id.network_logging_disclosures).setVisibility(View.GONE); 117 } else { 118 dialogView.requireViewById(R.id.network_logging_disclosures) 119 .setVisibility(View.VISIBLE); 120 TextView networkLoggingWarning = 121 dialogView.requireViewById(R.id.network_logging_warning); 122 networkLoggingWarning.setText(networkLoggingMessage); 123 } 124 125 // VPN section 126 CharSequence vpnMessage = getVpnMessage(isDeviceManaged); 127 if (vpnMessage == null) { 128 dialogView.requireViewById(R.id.vpn_disclosures).setVisibility(View.GONE); 129 } else { 130 dialogView.requireViewById(R.id.vpn_disclosures).setVisibility(View.VISIBLE); 131 TextView vpnWarning = dialogView.requireViewById(R.id.vpn_warning); 132 vpnWarning.setText(vpnMessage); 133 } 134 135 return dialogView; 136 } 137 getDeviceMonitoringTitle(CharSequence deviceOwnerOrganization)138 private CharSequence getDeviceMonitoringTitle(CharSequence deviceOwnerOrganization) { 139 if (deviceOwnerOrganization != null && isFinancedDevice()) { 140 return mContext.getString(R.string.monitoring_title_financed_device, 141 deviceOwnerOrganization); 142 } else { 143 return mContext.getString(R.string.monitoring_title_device_owned); 144 } 145 } 146 getDeviceMonitoringMessage(CharSequence deviceOwnerOrganization)147 private CharSequence getDeviceMonitoringMessage(CharSequence deviceOwnerOrganization) { 148 if (deviceOwnerOrganization != null) { 149 if (isFinancedDevice()) { 150 return mContext.getString(R.string.monitoring_financed_description_named_management, 151 deviceOwnerOrganization, deviceOwnerOrganization); 152 } else { 153 return mContext.getString( 154 R.string.monitoring_description_named_management, deviceOwnerOrganization); 155 } 156 } 157 return mContext.getString(R.string.monitoring_description_management); 158 } 159 160 @Nullable getCaCertsMessage(boolean isDeviceManaged)161 private CharSequence getCaCertsMessage(boolean isDeviceManaged) { 162 boolean hasCACerts = mSecurityController.hasCACertInCurrentUser(); 163 boolean hasCACertsInWorkProfile = mSecurityController.hasCACertInWorkProfile(); 164 if (!(hasCACerts || hasCACertsInWorkProfile)) return null; 165 if (isDeviceManaged) { 166 return mContext.getString(R.string.monitoring_description_management_ca_certificate); 167 } 168 if (hasCACertsInWorkProfile) { 169 return mContext.getString( 170 R.string.monitoring_description_managed_profile_ca_certificate); 171 } 172 return mContext.getString(R.string.monitoring_description_ca_certificate); 173 } 174 175 @Nullable getNetworkLoggingMessage(boolean isDeviceManaged)176 private CharSequence getNetworkLoggingMessage(boolean isDeviceManaged) { 177 boolean isNetworkLoggingEnabled = mSecurityController.isNetworkLoggingEnabled(); 178 if (!isNetworkLoggingEnabled) return null; 179 if (isDeviceManaged) { 180 return mContext.getString(R.string.monitoring_description_management_network_logging); 181 } else { 182 return mContext.getString( 183 R.string.monitoring_description_managed_profile_network_logging); 184 } 185 } 186 187 @Nullable getVpnMessage(boolean isDeviceManaged)188 private CharSequence getVpnMessage(boolean isDeviceManaged) { 189 boolean hasWorkProfile = mSecurityController.hasWorkProfile(); 190 String vpnName = mSecurityController.getPrimaryVpnName(); 191 String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName(); 192 if (vpnName == null && vpnNameWorkProfile == null) return null; 193 if (isDeviceManaged) { 194 if (vpnName != null && vpnNameWorkProfile != null) { 195 return mContext.getString(R.string.monitoring_description_two_named_vpns, 196 vpnName, vpnNameWorkProfile); 197 } else { 198 return mContext.getString(R.string.monitoring_description_managed_device_named_vpn, 199 vpnName != null ? vpnName : vpnNameWorkProfile); 200 } 201 } else { 202 if (vpnName != null && vpnNameWorkProfile != null) { 203 return mContext.getString(R.string.monitoring_description_two_named_vpns, 204 vpnName, vpnNameWorkProfile); 205 } else if (vpnNameWorkProfile != null) { 206 return mContext.getString(R.string.monitoring_description_managed_profile_named_vpn, 207 vpnNameWorkProfile); 208 } else if (hasWorkProfile) { 209 return mContext.getString( 210 R.string.monitoring_description_personal_profile_named_vpn, vpnName); 211 } else { 212 return mContext.getString(R.string.monitoring_description_named_vpn, vpnName); 213 } 214 } 215 } 216 isFinancedDevice()217 private boolean isFinancedDevice() { 218 return mSecurityController.isDeviceManaged() 219 && mSecurityController.getDeviceOwnerType( 220 mSecurityController.getDeviceOwnerComponentOnAnyUser()) 221 == DEVICE_OWNER_TYPE_FINANCED; 222 } 223 applyCarSysUIDialogFlags(AlertDialog dialog)224 private void applyCarSysUIDialogFlags(AlertDialog dialog) { 225 Window window = dialog.getWindow(); 226 window.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); 227 window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 228 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); 229 window.getAttributes().setFitInsetsTypes( 230 window.getAttributes().getFitInsetsTypes() & ~statusBars()); 231 } 232 } 233