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