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.settings.notification; 18 19 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS; 20 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS; 21 import static android.app.admin.DevicePolicyResources.Strings.Settings.LOCK_SCREEN_HIDE_WORK_NOTIFICATION_CONTENT; 22 import static android.app.admin.DevicePolicyResources.Strings.Settings.LOCK_SCREEN_SHOW_WORK_NOTIFICATION_CONTENT; 23 import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS; 24 import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS; 25 26 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 27 28 import android.app.admin.DevicePolicyManager; 29 import android.app.settings.SettingsEnums; 30 import android.content.Context; 31 import android.content.Intent; 32 import android.os.Bundle; 33 import android.os.UserManager; 34 import android.provider.Settings; 35 import android.view.LayoutInflater; 36 import android.view.View; 37 import android.view.ViewGroup; 38 import android.widget.RadioButton; 39 import android.widget.RadioGroup; 40 import android.widget.TextView; 41 42 import com.android.settings.R; 43 import com.android.settings.RestrictedRadioButton; 44 import com.android.settings.SettingsActivity; 45 import com.android.settings.SettingsPreferenceFragment; 46 import com.android.settings.SetupRedactionInterstitial; 47 import com.android.settings.SetupWizardUtils; 48 import com.android.settings.Utils; 49 import com.android.settingslib.RestrictedLockUtilsInternal; 50 51 import com.google.android.setupcompat.template.FooterBarMixin; 52 import com.google.android.setupcompat.template.FooterButton; 53 import com.google.android.setupcompat.util.WizardManagerHelper; 54 import com.google.android.setupdesign.GlifLayout; 55 import com.google.android.setupdesign.util.ThemeHelper; 56 57 public class RedactionInterstitial extends SettingsActivity { 58 59 @Override getIntent()60 public Intent getIntent() { 61 Intent modIntent = new Intent(super.getIntent()); 62 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, RedactionInterstitialFragment.class.getName()); 63 return modIntent; 64 } 65 66 @Override isValidFragment(String fragmentName)67 protected boolean isValidFragment(String fragmentName) { 68 return RedactionInterstitialFragment.class.getName().equals(fragmentName); 69 } 70 71 @Override onCreate(Bundle savedInstance)72 protected void onCreate(Bundle savedInstance) { 73 ThemeHelper.trySetSuwTheme(this); 74 super.onCreate(savedInstance); 75 findViewById(R.id.content_parent).setFitsSystemWindows(false); 76 } 77 78 @Override isToolbarEnabled()79 protected boolean isToolbarEnabled() { 80 return false; 81 } 82 83 /** 84 * Create an intent for launching RedactionInterstitial. 85 * 86 * @return An intent to launch the activity is if is available, @null if the activity is not 87 * available to be launched. 88 */ createStartIntent(Context ctx, int userId)89 public static Intent createStartIntent(Context ctx, int userId) { 90 return new Intent(ctx, RedactionInterstitial.class) 91 .putExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, 92 UserManager.get(ctx).isManagedProfile(userId) 93 ? R.string.lock_screen_notifications_interstitial_title_profile 94 : R.string.lock_screen_notifications_interstitial_title) 95 .putExtra(Intent.EXTRA_USER_ID, userId); 96 } 97 98 public static class RedactionInterstitialFragment extends SettingsPreferenceFragment 99 implements RadioGroup.OnCheckedChangeListener { 100 101 private RadioGroup mRadioGroup; 102 private RestrictedRadioButton mShowAllButton; 103 private RestrictedRadioButton mRedactSensitiveButton; 104 private int mUserId; 105 106 @Override getMetricsCategory()107 public int getMetricsCategory() { 108 return SettingsEnums.NOTIFICATION_REDACTION; 109 } 110 111 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)112 public View onCreateView(LayoutInflater inflater, ViewGroup container, 113 Bundle savedInstanceState) { 114 super.onCreateView(inflater, container, savedInstanceState); 115 return inflater.inflate(R.layout.redaction_interstitial, container, false); 116 } 117 118 @Override onViewCreated(View view, Bundle savedInstanceState)119 public void onViewCreated(View view, Bundle savedInstanceState) { 120 super.onViewCreated(view, savedInstanceState); 121 DevicePolicyManager devicePolicyManager = getSystemService(DevicePolicyManager.class); 122 mRadioGroup = (RadioGroup) view.findViewById(R.id.radio_group); 123 mShowAllButton = (RestrictedRadioButton) view.findViewById(R.id.show_all); 124 mRedactSensitiveButton = 125 (RestrictedRadioButton) view.findViewById(R.id.redact_sensitive); 126 127 mRadioGroup.setOnCheckedChangeListener(this); 128 mUserId = Utils.getUserIdFromBundle( 129 getContext(), getActivity().getIntent().getExtras()); 130 if (UserManager.get(getContext()).isManagedProfile(mUserId)) { 131 ((TextView) view.findViewById(R.id.sud_layout_description)) 132 .setText(R.string.lock_screen_notifications_interstitial_message_profile); 133 mShowAllButton.setText(devicePolicyManager 134 .getResources().getString(LOCK_SCREEN_SHOW_WORK_NOTIFICATION_CONTENT, 135 () -> getString( 136 R.string.lock_screen_notifications_summary_show_profile))); 137 mRedactSensitiveButton 138 .setText(devicePolicyManager.getResources().getString( 139 LOCK_SCREEN_HIDE_WORK_NOTIFICATION_CONTENT, 140 () -> getString( 141 R.string.lock_screen_notifications_summary_hide_profile))); 142 143 ((RadioButton) view.findViewById(R.id.hide_all)).setVisibility(View.GONE); 144 } 145 146 final GlifLayout layout = view.findViewById(R.id.setup_wizard_layout); 147 final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class); 148 mixin.setPrimaryButton( 149 new FooterButton.Builder(getContext()) 150 .setText(R.string.app_notifications_dialog_done) 151 .setListener(this::onDoneButtonClicked) 152 .setButtonType(FooterButton.ButtonType.NEXT) 153 .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary) 154 .build() 155 ); 156 } 157 onDoneButtonClicked(View view)158 private void onDoneButtonClicked(View view) { 159 // If the activity starts by Setup Wizard, then skip disable component which avoids the 160 // framework force closing all activities on the same task when the system is busy. 161 if (!WizardManagerHelper.isAnySetupWizard(getIntent())) { 162 SetupRedactionInterstitial.setEnabled(getContext(), false); 163 } 164 final RedactionInterstitial activity = (RedactionInterstitial) getActivity(); 165 if (activity != null) { 166 activity.setResult(RESULT_CANCELED, null); 167 finish(); 168 } 169 } 170 171 @Override onResume()172 public void onResume() { 173 super.onResume(); 174 // Disable buttons according to policy. 175 176 checkNotificationFeaturesAndSetDisabled(mShowAllButton, 177 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | 178 KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); 179 checkNotificationFeaturesAndSetDisabled(mRedactSensitiveButton, 180 KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); 181 loadFromSettings(); 182 } 183 checkNotificationFeaturesAndSetDisabled(RestrictedRadioButton button, int keyguardNotifications)184 private void checkNotificationFeaturesAndSetDisabled(RestrictedRadioButton button, 185 int keyguardNotifications) { 186 EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled( 187 getActivity(), keyguardNotifications, mUserId); 188 button.setDisabledByAdmin(admin); 189 } 190 loadFromSettings()191 private void loadFromSettings() { 192 final boolean showUnRedactedDefault = getContext().getResources().getBoolean( 193 R.bool.default_allow_sensitive_lockscreen_content); 194 final boolean managedProfile = UserManager.get(getContext()).isManagedProfile(mUserId); 195 // Hiding all notifications is device-wide setting, managed profiles can only set 196 // whether their notifications are show in full or redacted. 197 final boolean showNotifications = managedProfile || Settings.Secure.getIntForUser( 198 getContentResolver(), LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, mUserId) != 0; 199 final boolean showUnredacted = Settings.Secure.getIntForUser( 200 getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 201 showUnRedactedDefault ? 1 : 0, mUserId) != 0; 202 203 int checkedButtonId = R.id.hide_all; 204 if (showNotifications) { 205 if (showUnredacted && !mShowAllButton.isDisabledByAdmin()) { 206 checkedButtonId = R.id.show_all; 207 } else if (!mRedactSensitiveButton.isDisabledByAdmin()) { 208 checkedButtonId = R.id.redact_sensitive; 209 } 210 } 211 212 mRadioGroup.check(checkedButtonId); 213 } 214 215 @Override onCheckedChanged(RadioGroup group, int checkedId)216 public void onCheckedChanged(RadioGroup group, int checkedId) { 217 final boolean show = (checkedId == R.id.show_all); 218 final boolean enabled = (checkedId != R.id.hide_all); 219 220 Settings.Secure.putIntForUser(getContentResolver(), 221 LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0, mUserId); 222 Settings.Secure.putIntForUser(getContentResolver(), 223 LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0, mUserId); 224 225 } 226 } 227 } 228