Merge "[CDM][NLS] Check if the NLS service has an intent-filter" into main

This commit is contained in:
Treehugger Robot
2024-10-04 18:24:30 +00:00
committed by Android (Google) Code Review
2 changed files with 33 additions and 26 deletions

View File

@@ -30,13 +30,15 @@ import android.app.admin.DevicePolicyManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo; import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo; import android.content.pm.ResolveInfo;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.service.notification.NotificationListenerService;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Slog; import android.util.Slog;
import android.view.WindowManager; import android.view.WindowManager;
@@ -49,6 +51,8 @@ import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController; import com.android.internal.app.AlertController;
import com.android.settings.R; import com.android.settings.R;
import java.util.List;
/** @hide */ /** @hide */
public class NotificationAccessConfirmationActivity extends Activity public class NotificationAccessConfirmationActivity extends Activity
implements DialogInterface { implements DialogInterface {
@@ -113,6 +117,31 @@ public class NotificationAccessConfirmationActivity extends Activity
return; return;
} }
// Check NLS service info.
String requiredPermission = Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE;
Intent NLSIntent = new Intent(NotificationListenerService.SERVICE_INTERFACE);
List<ResolveInfo> matchedServiceList = getPackageManager().queryIntentServicesAsUser(
NLSIntent, /* flags */ 0, mUserId);
boolean hasNLSIntentFilter = false;
for (ResolveInfo service : matchedServiceList) {
if (service.serviceInfo.packageName.equals(mComponentName.getPackageName())) {
if (!requiredPermission.equals(service.serviceInfo.permission)) {
Slog.e(LOG_TAG, "Service " + mComponentName + " lacks permission "
+ requiredPermission);
finish();
return;
}
hasNLSIntentFilter = true;
break;
}
}
if (!hasNLSIntentFilter) {
Slog.e(LOG_TAG, "Service " + mComponentName + " lacks an intent-filter action "
+ "for android.service.notification.NotificationListenerService.");
finish();
return;
}
AlertController.AlertParams p = new AlertController.AlertParams(this); AlertController.AlertParams p = new AlertController.AlertParams(this);
p.mTitle = getString( p.mTitle = getString(
R.string.notification_listener_security_warning_title, R.string.notification_listener_security_warning_title,
@@ -147,19 +176,6 @@ public class NotificationAccessConfirmationActivity extends Activity
} }
private void onAllow() { 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); mNm.setNotificationListenerAccessGranted(mComponentName, true);
finish(); finish();
@@ -170,12 +186,6 @@ public class NotificationAccessConfirmationActivity extends Activity
return AlertActivity.dispatchPopulateAccessibilityEvent(this, 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 @Override
public void cancel() { public void cancel() {
finish(); finish();

View File

@@ -31,8 +31,6 @@ import android.widget.TextView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.android.settings.R;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import org.junit.Test; import org.junit.Test;
@@ -45,15 +43,14 @@ import org.robolectric.RuntimeEnvironment;
public class NotificationAccessConfirmationActivityTest { public class NotificationAccessConfirmationActivityTest {
@Test @Test
public void start_showsDialog() { public void start_withMissingIntentFilter_finishes() {
ComponentName cn = new ComponentName("com.example", "com.example.SomeService"); ComponentName cn = new ComponentName("com.example", "com.example.SomeService");
installPackage(cn.getPackageName(), "X"); installPackage(cn.getPackageName(), "X");
NotificationAccessConfirmationActivity activity = startActivityWithIntent(cn); NotificationAccessConfirmationActivity activity = startActivityWithIntent(cn);
assertThat(activity.isFinishing()).isFalse(); assertThat(getDialogText(activity)).isNull();
assertThat(getDialogText(activity)).isEqualTo( assertThat(activity.isFinishing()).isTrue();
activity.getString(R.string.notification_listener_security_warning_summary, "X"));
} }
@Test @Test