Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/23726247 Change-Id: I71f428e90b132c4282827b698623ee1d43c0f7c1 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
192 lines
6.9 KiB
Java
192 lines
6.9 KiB
Java
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
|
|
package com.android.settings.notification;
|
|
|
|
import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_APPS_CANNOT_ACCESS_NOTIFICATION_SETTINGS;
|
|
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
|
|
|
|
import static com.android.internal.notification.NotificationAccessConfirmationActivityContract.EXTRA_COMPONENT_NAME;
|
|
import static com.android.internal.notification.NotificationAccessConfirmationActivityContract.EXTRA_USER_ID;
|
|
|
|
import android.Manifest;
|
|
import android.annotation.Nullable;
|
|
import android.app.Activity;
|
|
import android.app.NotificationManager;
|
|
import android.app.admin.DevicePolicyManager;
|
|
import android.content.ComponentName;
|
|
import android.content.Context;
|
|
import android.content.DialogInterface;
|
|
import android.content.pm.ApplicationInfo;
|
|
import android.content.pm.PackageItemInfo;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.pm.ServiceInfo;
|
|
import android.os.Bundle;
|
|
import android.os.UserHandle;
|
|
import android.os.UserManager;
|
|
import android.text.TextUtils;
|
|
import android.util.Slog;
|
|
import android.view.WindowManager;
|
|
import android.view.accessibility.AccessibilityEvent;
|
|
import android.widget.Toast;
|
|
|
|
import com.android.internal.app.AlertActivity;
|
|
import com.android.internal.app.AlertController;
|
|
import com.android.settings.R;
|
|
|
|
/** @hide */
|
|
public class NotificationAccessConfirmationActivity extends Activity
|
|
implements DialogInterface {
|
|
|
|
private static final boolean DEBUG = false;
|
|
private static final String LOG_TAG = "NotificationAccessConfirmationActivity";
|
|
|
|
private int mUserId;
|
|
private ComponentName mComponentName;
|
|
private NotificationManager mNm;
|
|
|
|
private DevicePolicyManager mDpm;
|
|
private UserManager mUm;
|
|
|
|
@Override
|
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
|
|
getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
|
|
|
mUm = getSystemService(UserManager.class);
|
|
mDpm = getSystemService(DevicePolicyManager.class);
|
|
|
|
if (mUm.isManagedProfile()) {
|
|
Slog.w(LOG_TAG, "Apps in the work profile do not support notification listeners");
|
|
Toast.makeText(this,
|
|
mDpm.getResources().getString(WORK_APPS_CANNOT_ACCESS_NOTIFICATION_SETTINGS,
|
|
() -> getString(R.string.notification_settings_work_profile)),
|
|
Toast.LENGTH_SHORT).show();
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
mNm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
|
|
|
mComponentName = getIntent().getParcelableExtra(EXTRA_COMPONENT_NAME);
|
|
mUserId = getIntent().getIntExtra(EXTRA_USER_ID, UserHandle.USER_NULL);
|
|
CharSequence mAppLabel;
|
|
|
|
if (mComponentName == null || mComponentName.getPackageName() == null
|
|
|| mComponentName.flattenToString().length()
|
|
> NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
ApplicationInfo applicationInfo = getPackageManager().getApplicationInfo(
|
|
mComponentName.getPackageName(), 0);
|
|
mAppLabel = applicationInfo.loadSafeLabel(getPackageManager(),
|
|
PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
|
|
PackageItemInfo.SAFE_LABEL_FLAG_TRIM
|
|
| PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE);
|
|
} catch (PackageManager.NameNotFoundException e) {
|
|
Slog.e(LOG_TAG, "Couldn't find app with package name for " + mComponentName, e);
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
if (TextUtils.isEmpty(mAppLabel)) {
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
AlertController.AlertParams p = new AlertController.AlertParams(this);
|
|
p.mTitle = getString(
|
|
R.string.notification_listener_security_warning_title,
|
|
mAppLabel);
|
|
p.mMessage = getString(
|
|
R.string.notification_listener_security_warning_summary,
|
|
mAppLabel);
|
|
p.mPositiveButtonText = getString(R.string.allow);
|
|
p.mPositiveButtonListener = (a, b) -> onAllow();
|
|
p.mNegativeButtonText = getString(R.string.deny);
|
|
p.mNegativeButtonListener = (a, b) -> cancel();
|
|
AlertController
|
|
.create(this, this, getWindow())
|
|
.installContent(p);
|
|
// Consistent with the permission dialog
|
|
// Used instead of p.mCancelable as that is only honored for AlertDialog
|
|
getWindow().setCloseOnTouchOutside(false);
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
getWindow().addFlags(
|
|
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
getWindow().clearFlags(
|
|
WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
|
|
super.onPause();
|
|
}
|
|
|
|
private void onAllow() {
|
|
String requiredPermission = Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE;
|
|
try {
|
|
ServiceInfo serviceInfo = getPackageManager().getServiceInfo(mComponentName, 0);
|
|
if (!requiredPermission.equals(serviceInfo.permission)) {
|
|
Slog.e(LOG_TAG,
|
|
"Service " + mComponentName + " lacks permission " + requiredPermission);
|
|
return;
|
|
}
|
|
} catch (PackageManager.NameNotFoundException e) {
|
|
Slog.e(LOG_TAG, "Failed to get service info for " + mComponentName, e);
|
|
return;
|
|
}
|
|
|
|
mNm.setNotificationListenerAccessGranted(mComponentName, true);
|
|
|
|
finish();
|
|
}
|
|
|
|
@Override
|
|
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
|
|
return AlertActivity.dispatchPopulateAccessibilityEvent(this, event);
|
|
}
|
|
|
|
@Override
|
|
public void onBackPressed() {
|
|
// Suppress finishing the activity on back button press,
|
|
// consistently with the permission dialog behavior
|
|
}
|
|
|
|
@Override
|
|
public void cancel() {
|
|
finish();
|
|
}
|
|
|
|
@Override
|
|
public void dismiss() {
|
|
// This is called after the click, since we finish when handling the
|
|
// click, don't do that again here.
|
|
if (!isFinishing()) {
|
|
finish();
|
|
}
|
|
}
|
|
}
|