1 /* 2 * Copyright (C) 2017 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 18 package com.android.settings.notification; 19 20 import static com.android.internal.notification.NotificationAccessConfirmationActivityContract 21 .EXTRA_COMPONENT_NAME; 22 import static com.android.internal.notification.NotificationAccessConfirmationActivityContract 23 .EXTRA_PACKAGE_TITLE; 24 import static com.android.internal.notification.NotificationAccessConfirmationActivityContract 25 .EXTRA_USER_ID; 26 27 import android.Manifest; 28 import android.annotation.Nullable; 29 import android.app.Activity; 30 import android.content.ComponentName; 31 import android.content.DialogInterface; 32 import android.content.pm.PackageManager; 33 import android.content.pm.ServiceInfo; 34 import android.os.Bundle; 35 import android.os.UserHandle; 36 import android.provider.Settings; 37 import android.provider.SettingsStringUtil; 38 import android.util.Slog; 39 import android.view.accessibility.AccessibilityEvent; 40 41 import com.android.internal.app.AlertActivity; 42 import com.android.internal.app.AlertController; 43 import com.android.settings.R; 44 import com.android.settings.core.TouchOverlayManager; 45 46 /** @hide */ 47 public class NotificationAccessConfirmationActivity extends Activity 48 implements DialogInterface { 49 50 private static final boolean DEBUG = false; 51 private static final String LOG_TAG = "NotificationAccessConfirmationActivity"; 52 53 private int mUserId; 54 private ComponentName mComponentName; 55 private TouchOverlayManager mTouchOverlayManager; 56 57 @Override onCreate(@ullable Bundle savedInstanceState)58 protected void onCreate(@Nullable Bundle savedInstanceState) { 59 super.onCreate(savedInstanceState); 60 61 mTouchOverlayManager = new TouchOverlayManager(this); 62 63 mComponentName = getIntent().getParcelableExtra(EXTRA_COMPONENT_NAME); 64 mUserId = getIntent().getIntExtra(EXTRA_USER_ID, UserHandle.USER_NULL); 65 String pkgTitle = getIntent().getStringExtra(EXTRA_PACKAGE_TITLE); 66 67 AlertController.AlertParams p = new AlertController.AlertParams(this); 68 p.mTitle = getString( 69 R.string.notification_listener_security_warning_title, 70 pkgTitle); 71 p.mMessage = getString( 72 R.string.notification_listener_security_warning_summary, 73 pkgTitle); 74 p.mPositiveButtonText = getString(R.string.allow); 75 p.mPositiveButtonListener = (a, b) -> onAllow(); 76 p.mNegativeButtonText = getString(R.string.deny); 77 p.mNegativeButtonListener = (a, b) -> cancel(); 78 AlertController 79 .create(this, this, getWindow()) 80 .installContent(p); 81 } 82 onAllow()83 private void onAllow() { 84 String requiredPermission = Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE; 85 try { 86 ServiceInfo serviceInfo = getPackageManager().getServiceInfo(mComponentName, 0); 87 if (!requiredPermission.equals(serviceInfo.permission)) { 88 Slog.e(LOG_TAG, 89 "Service " + mComponentName + " lacks permission " + requiredPermission); 90 return; 91 } 92 } catch (PackageManager.NameNotFoundException e) { 93 Slog.e(LOG_TAG, "Failed to get service info for " + mComponentName, e); 94 return; 95 } 96 97 final SettingsStringUtil.SettingStringHelper setting = 98 new SettingsStringUtil.SettingStringHelper( 99 getContentResolver(), 100 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, 101 mUserId); 102 setting.write(SettingsStringUtil.ComponentNameSet.add(setting.read(), mComponentName)); 103 104 finish(); 105 } 106 107 @Override dispatchPopulateAccessibilityEvent(AccessibilityEvent event)108 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 109 return AlertActivity.dispatchPopulateAccessibilityEvent(this, event); 110 } 111 112 @Override cancel()113 public void cancel() { 114 finish(); 115 } 116 117 @Override dismiss()118 public void dismiss() { 119 // This is called after the click, since we finish when handling the 120 // click, don't do that again here. 121 if (!isFinishing()) { 122 finish(); 123 } 124 } 125 126 @Override onResume()127 protected void onResume() { 128 super.onResume(); 129 mTouchOverlayManager.setOverlayAllowed(false); 130 } 131 132 @Override onPause()133 protected void onPause() { 134 super.onPause(); 135 mTouchOverlayManager.setOverlayAllowed(true); 136 } 137 } 138