Merge "Adjust testapis/permissions for CTS tests" into qt-dev am: a2c50b1da8
am: a36ab826fb
Change-Id: I93495e9871675d0f2eb8f432c5041a68ca20d20f
This commit is contained in:
@@ -328,8 +328,14 @@ package android.app {
|
||||
}
|
||||
|
||||
public class NotificationManager {
|
||||
method public void allowAssistantCapability(String);
|
||||
method public void disallowAssistantCapability(String);
|
||||
method @NonNull public java.util.List<java.lang.String> getAllowedAssistantCapabilities();
|
||||
method @Nullable public android.content.ComponentName getAllowedNotificationAssistant();
|
||||
method public android.content.ComponentName getEffectsSuppressor();
|
||||
method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName);
|
||||
method public boolean matchesCallFilter(android.os.Bundle);
|
||||
method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean);
|
||||
}
|
||||
|
||||
public final class PictureInPictureParams implements android.os.Parcelable {
|
||||
@@ -2454,10 +2460,49 @@ package android.service.contentcapture {
|
||||
|
||||
package android.service.notification {
|
||||
|
||||
public final class Adjustment implements android.os.Parcelable {
|
||||
ctor public Adjustment(String, String, android.os.Bundle, CharSequence, int);
|
||||
ctor public Adjustment(@NonNull String, @NonNull String, @NonNull android.os.Bundle, @NonNull CharSequence, @NonNull android.os.UserHandle);
|
||||
method public int describeContents();
|
||||
method @NonNull public CharSequence getExplanation();
|
||||
method @NonNull public String getKey();
|
||||
method @NonNull public String getPackage();
|
||||
method @NonNull public android.os.Bundle getSignals();
|
||||
method public int getUser();
|
||||
method @NonNull public android.os.UserHandle getUserHandle();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
|
||||
field public static final String KEY_CONTEXTUAL_ACTIONS = "key_contextual_actions";
|
||||
field public static final String KEY_IMPORTANCE = "key_importance";
|
||||
field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
|
||||
field public static final String KEY_TEXT_REPLIES = "key_text_replies";
|
||||
field public static final String KEY_USER_SENTIMENT = "key_user_sentiment";
|
||||
}
|
||||
|
||||
@Deprecated public abstract class ConditionProviderService extends android.app.Service {
|
||||
method @Deprecated public boolean isBound();
|
||||
}
|
||||
|
||||
public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
|
||||
ctor public NotificationAssistantService();
|
||||
method public final void adjustNotification(@NonNull android.service.notification.Adjustment);
|
||||
method public final void adjustNotifications(@NonNull java.util.List<android.service.notification.Adjustment>);
|
||||
method public void onActionInvoked(@NonNull String, @NonNull android.app.Notification.Action, int);
|
||||
method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent);
|
||||
method public void onCapabilitiesChanged();
|
||||
method public void onNotificationDirectReplied(@NonNull String);
|
||||
method @Nullable public abstract android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification);
|
||||
method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel);
|
||||
method public void onNotificationExpansionChanged(@NonNull String, boolean, boolean);
|
||||
method public abstract void onNotificationSnoozedUntilContext(@NonNull android.service.notification.StatusBarNotification, @NonNull String);
|
||||
method public void onNotificationsSeen(@NonNull java.util.List<java.lang.String>);
|
||||
method public void onSuggestedReplySent(@NonNull String, @NonNull CharSequence, int);
|
||||
method public final void unsnoozeNotification(@NonNull String);
|
||||
field public static final String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
|
||||
field public static final int SOURCE_FROM_APP = 0; // 0x0
|
||||
field public static final int SOURCE_FROM_ASSISTANT = 1; // 0x1
|
||||
}
|
||||
|
||||
public abstract class NotificationListenerService extends android.app.Service {
|
||||
method public void onNotificationRemoved(@NonNull android.service.notification.StatusBarNotification, @NonNull android.service.notification.NotificationListenerService.RankingMap, @NonNull android.service.notification.NotificationStats, int);
|
||||
}
|
||||
|
||||
@@ -1169,6 +1169,7 @@ public class NotificationManager {
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
|
||||
INotificationManager service = getService();
|
||||
try {
|
||||
@@ -1204,6 +1205,7 @@ public class NotificationManager {
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public @NonNull @Adjustment.Keys List<String> getAllowedAssistantCapabilities() {
|
||||
INotificationManager service = getService();
|
||||
try {
|
||||
@@ -1213,6 +1215,32 @@ public class NotificationManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void allowAssistantCapability(String capability) {
|
||||
INotificationManager service = getService();
|
||||
try {
|
||||
service.allowAssistantCapability(capability);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void disallowAssistantCapability(String capability) {
|
||||
INotificationManager service = getService();
|
||||
try {
|
||||
service.disallowAssistantCapability(capability);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
|
||||
INotificationManager service = getService();
|
||||
@@ -1310,6 +1338,7 @@ public class NotificationManager {
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
|
||||
boolean granted) {
|
||||
INotificationManager service = getService();
|
||||
@@ -1332,6 +1361,7 @@ public class NotificationManager {
|
||||
|
||||
/** @hide */
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public @Nullable ComponentName getAllowedNotificationAssistant() {
|
||||
INotificationManager service = getService();
|
||||
try {
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.service.notification;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.StringDef;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.Notification;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
@@ -40,6 +41,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public final class Adjustment implements Parcelable {
|
||||
private final String mPackage;
|
||||
private final String mKey;
|
||||
@@ -130,6 +132,7 @@ public final class Adjustment implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public Adjustment(String pkg, String key, Bundle signals, CharSequence explanation, int user) {
|
||||
mPackage = pkg;
|
||||
mKey = key;
|
||||
@@ -212,6 +215,7 @@ public final class Adjustment implements Parcelable {
|
||||
|
||||
/** @hide */
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public int getUser() {
|
||||
return mUser;
|
||||
}
|
||||
|
||||
@@ -53,4 +53,5 @@ oneway interface INotificationListener
|
||||
void onNotificationDirectReply(String key);
|
||||
void onSuggestedReplySent(String key, in CharSequence reply, int source);
|
||||
void onActionClicked(String key, in Notification.Action action, int source);
|
||||
void onCapabilitiesChanged();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
@@ -65,6 +66,7 @@ import java.util.List;
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public abstract class NotificationAssistantService extends NotificationListenerService {
|
||||
private static final String TAG = "NotificationAssistants";
|
||||
|
||||
@@ -357,6 +359,11 @@ public abstract class NotificationAssistantService extends NotificationListenerS
|
||||
args.argi2 = source;
|
||||
mHandler.obtainMessage(MyHandler.MSG_ON_ACTION_INVOKED, args).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapabilitiesChanged() {
|
||||
mHandler.obtainMessage(MyHandler.MSG_ON_CAPABILITIES_CHANGED).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private final class MyHandler extends Handler {
|
||||
@@ -367,6 +374,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS
|
||||
public static final int MSG_ON_NOTIFICATION_DIRECT_REPLY_SENT = 5;
|
||||
public static final int MSG_ON_SUGGESTED_REPLY_SENT = 6;
|
||||
public static final int MSG_ON_ACTION_INVOKED = 7;
|
||||
public static final int MSG_ON_CAPABILITIES_CHANGED = 8;
|
||||
|
||||
public MyHandler(Looper looper) {
|
||||
super(looper, null, false);
|
||||
@@ -448,6 +456,10 @@ public abstract class NotificationAssistantService extends NotificationListenerS
|
||||
onActionInvoked(key, action, source);
|
||||
break;
|
||||
}
|
||||
case MSG_ON_CAPABILITIES_CHANGED: {
|
||||
onCapabilitiesChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1398,6 +1398,11 @@ public abstract class NotificationListenerService extends Service {
|
||||
// no-op in the listener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapabilitiesChanged() {
|
||||
// no-op in the listener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationChannelModification(String pkgName, UserHandle user,
|
||||
NotificationChannel channel,
|
||||
|
||||
@@ -309,6 +309,7 @@ applications that come with the platform
|
||||
<permission name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS"/>
|
||||
<permission name="android.permission.SET_WALLPAPER" />
|
||||
<permission name="android.permission.SET_WALLPAPER_COMPONENT" />
|
||||
<permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
|
||||
</privapp-permissions>
|
||||
|
||||
<privapp-permissions package="com.android.statementservice">
|
||||
|
||||
@@ -154,6 +154,7 @@
|
||||
<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
|
||||
<!-- Permission needed to rename bugreport notifications (so they're not shown as Shell) -->
|
||||
<uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
|
||||
<uses-permission android:name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
|
||||
<!-- Permission needed to hold a wakelock in dumpstate.cpp (drop_root_user()) -->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<!-- Permission needed to enable/disable overlays -->
|
||||
|
||||
@@ -2869,7 +2869,7 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void allowAssistantCapability(String adjustmentType) {
|
||||
checkCallerIsSystemOrShell();
|
||||
checkCallerIsSystemOrSystemUiOrShell();
|
||||
mAssistants.allowAdjustmentType(adjustmentType);
|
||||
|
||||
handleSavePolicyFile();
|
||||
@@ -2877,7 +2877,7 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void disallowAssistantCapability(String adjustmentType) {
|
||||
checkCallerIsSystemOrShell();
|
||||
checkCallerIsSystemOrSystemUiOrShell();
|
||||
mAssistants.disallowAdjustmentType(adjustmentType);
|
||||
|
||||
handleSavePolicyFile();
|
||||
@@ -3811,7 +3811,7 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public ComponentName getAllowedNotificationAssistantForUser(int userId) {
|
||||
checkCallerIsSystem();
|
||||
checkCallerIsSystemOrSystemUiOrShell();
|
||||
List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
|
||||
if (allowedComponents.size() > 1) {
|
||||
throw new IllegalStateException(
|
||||
@@ -3894,7 +3894,7 @@ public class NotificationManagerService extends SystemService {
|
||||
@Override
|
||||
public void setNotificationAssistantAccessGrantedForUser(ComponentName assistant,
|
||||
int userId, boolean granted) {
|
||||
checkCallerIsSystemOrShell();
|
||||
checkCallerIsSystemOrSystemUiOrShell();
|
||||
mAssistants.setUserSet(userId, true);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -3929,10 +3929,6 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
if (!foundEnqueued) {
|
||||
// adjustment arrived too late to apply to enqueued; apply to posted
|
||||
// However, since the notification is now posted and may have alerted,
|
||||
// ignore any importance related adjustments
|
||||
adjustment.getSignals().remove(Adjustment.KEY_IMPORTANCE);
|
||||
applyAdjustmentFromAssistant(token, adjustment);
|
||||
}
|
||||
}
|
||||
@@ -4123,7 +4119,7 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mAllowedManagedServicePackages.test(assistant.getPackageName(), userId,
|
||||
if (!granted || mAllowedManagedServicePackages.test(assistant.getPackageName(), userId,
|
||||
mAssistants.getRequiredPermission())) {
|
||||
mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(),
|
||||
userId, false, granted);
|
||||
@@ -6995,6 +6991,16 @@ public class NotificationManagerService extends SystemService {
|
||||
throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid());
|
||||
}
|
||||
|
||||
private void checkCallerIsSystemOrSystemUiOrShell() {
|
||||
if (Binder.getCallingUid() == Process.SHELL_UID) {
|
||||
return;
|
||||
}
|
||||
if (isCallerSystemOrPhone()) {
|
||||
return;
|
||||
}
|
||||
getContext().enforceCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE, null);
|
||||
}
|
||||
|
||||
private void checkCallerIsSystemOrSameApp(String pkg) {
|
||||
if (isCallerSystemOrPhone()) {
|
||||
return;
|
||||
@@ -7302,7 +7308,7 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private ArrayMap<Integer, Boolean> mUserSetMap = new ArrayMap<>();
|
||||
private List<String> mAllowedAdjustments = new ArrayList<>();
|
||||
private Set<String> mAllowedAdjustments = new ArraySet<>();
|
||||
|
||||
public NotificationAssistants(Context context, Object lock, UserProfiles up,
|
||||
IPackageManager pm) {
|
||||
@@ -7390,12 +7396,18 @@ public class NotificationManagerService extends SystemService {
|
||||
synchronized (mLock) {
|
||||
mAllowedAdjustments.add(type);
|
||||
}
|
||||
for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
|
||||
mHandler.post(() -> notifyCapabilitiesChanged(info));
|
||||
}
|
||||
}
|
||||
|
||||
protected void disallowAdjustmentType(String type) {
|
||||
synchronized (mLock) {
|
||||
mAllowedAdjustments.remove(type);
|
||||
}
|
||||
for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
|
||||
mHandler.post(() -> notifyCapabilitiesChanged(info));
|
||||
}
|
||||
}
|
||||
|
||||
protected List<String> getAllowedAssistantCapabilities() {
|
||||
@@ -7455,6 +7467,15 @@ public class NotificationManagerService extends SystemService {
|
||||
setUserSet(userId, userSet);
|
||||
}
|
||||
|
||||
private void notifyCapabilitiesChanged(final ManagedServiceInfo info) {
|
||||
final INotificationListener assistant = (INotificationListener) info.service;
|
||||
try {
|
||||
assistant.onCapabilitiesChanged();
|
||||
} catch (RemoteException ex) {
|
||||
Slog.e(TAG, "unable to notify assistant (capabilities): " + assistant, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifySeen(final ManagedServiceInfo info,
|
||||
final ArrayList<String> keys) {
|
||||
final INotificationListener assistant = (INotificationListener) info.service;
|
||||
|
||||
@@ -2890,7 +2890,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyEnqueuedAdjustmentFromAssistant_importance_onTime() throws Exception {
|
||||
public void testApplyEnqueuedAdjustmentFromAssistant_importance() throws Exception {
|
||||
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
|
||||
mService.addEnqueuedNotification(r);
|
||||
NotificationManagerService.WorkerHandler handler = mock(
|
||||
@@ -2907,25 +2907,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(IMPORTANCE_LOW, r.getImportance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyEnqueuedAdjustmentFromAssistant_importance_tooLate() throws Exception {
|
||||
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
|
||||
mService.addNotification(r);
|
||||
NotificationManagerService.WorkerHandler handler = mock(
|
||||
NotificationManagerService.WorkerHandler.class);
|
||||
mService.setHandler(handler);
|
||||
when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
|
||||
|
||||
Bundle signals = new Bundle();
|
||||
signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
|
||||
Adjustment adjustment = new Adjustment(
|
||||
r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
|
||||
mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
|
||||
|
||||
assertEquals(IMPORTANCE_DEFAULT, r.getImportance());
|
||||
assertFalse(r.hasAdjustment(KEY_IMPORTANCE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyEnqueuedAdjustmentFromAssistant_crossUser() throws Exception {
|
||||
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
|
||||
|
||||
Reference in New Issue
Block a user