Add API for requesting add controls from Provider
This API allows ControlsProviderService to request SystemUI to show UI to the user to add a favorite. This can be called at any time (not just when bound). Test: atest Fixes: 148936288 Change-Id: I8740b6a105ad64994e6df701f2604a4234a49154
This commit is contained in:
@@ -32,6 +32,7 @@ package android {
|
||||
field public static final String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
|
||||
field @Deprecated public static final String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
|
||||
field public static final String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE";
|
||||
field public static final String BIND_CONTROLS = "android.permission.BIND_CONTROLS";
|
||||
field public static final String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
|
||||
field public static final String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
|
||||
field public static final String BIND_INCALL_SERVICE = "android.permission.BIND_INCALL_SERVICE";
|
||||
@@ -43410,6 +43411,7 @@ package android.service.controls {
|
||||
method @NonNull public abstract java.util.concurrent.Flow.Publisher<android.service.controls.Control> publisherFor(@NonNull java.util.List<java.lang.String>);
|
||||
method @Nullable public java.util.concurrent.Flow.Publisher<android.service.controls.Control> publisherForAllAvailable();
|
||||
method @Nullable public java.util.concurrent.Flow.Publisher<android.service.controls.Control> publisherForSuggested();
|
||||
method public static void requestAddControl(@NonNull android.content.Context, @NonNull android.content.ComponentName, @NonNull android.service.controls.Control);
|
||||
field public static final String SERVICE_CONTROLS = "android.service.controls.ControlsProviderService";
|
||||
field @NonNull public static final String TAG = "ControlsProviderService";
|
||||
}
|
||||
|
||||
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package android.service.controls;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -51,6 +54,20 @@ public abstract class ControlsProviderService extends Service {
|
||||
@SdkConstant(SdkConstantType.SERVICE_ACTION)
|
||||
public static final String SERVICE_CONTROLS =
|
||||
"android.service.controls.ControlsProviderService";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_ADD_CONTROL =
|
||||
"android.service.controls.action.ADD_CONTROL";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_CONTROL =
|
||||
"android.service.controls.extra.CONTROL";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@@ -325,6 +342,33 @@ public abstract class ControlsProviderService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request SystemUI to prompt the user to add a control to favorites.
|
||||
*
|
||||
* @param context A context
|
||||
* @param componentName Component name of the {@link ControlsProviderService}
|
||||
* @param control A stateless control to show to the user
|
||||
*/
|
||||
public static void requestAddControl(@NonNull Context context,
|
||||
@NonNull ComponentName componentName,
|
||||
@NonNull Control control) {
|
||||
Preconditions.checkNotNull(context);
|
||||
Preconditions.checkNotNull(componentName);
|
||||
Preconditions.checkNotNull(control);
|
||||
final ComponentName sysuiComponent = ComponentName.unflattenFromString(
|
||||
context.getResources().getString(
|
||||
com.android.internal.R.string.config_systemUIServiceComponent));
|
||||
Intent intent = new Intent(ACTION_ADD_CONTROL);
|
||||
intent.putExtra(Intent.EXTRA_COMPONENT_NAME, componentName);
|
||||
intent.setPackage(sysuiComponent.getPackageName());
|
||||
if (isStatelessControl(control)) {
|
||||
intent.putExtra(EXTRA_CONTROL, control);
|
||||
} else {
|
||||
intent.putExtra(EXTRA_CONTROL, new Control.StatelessBuilder(control).build());
|
||||
}
|
||||
context.sendBroadcast(intent, Manifest.permission.BIND_CONTROLS);
|
||||
}
|
||||
|
||||
private static class SubscriptionAdapter extends IControlsSubscription.Stub {
|
||||
final Subscription mSubscription;
|
||||
|
||||
|
||||
@@ -3081,8 +3081,7 @@
|
||||
|
||||
<!-- Allows SystemUI to request third party controls.
|
||||
<p>Should only be requested by the System and required by
|
||||
ControlsService declarations.
|
||||
@hide
|
||||
{@link android.service.controls.ControlsProviderService} declarations.
|
||||
-->
|
||||
<permission android:name="android.permission.BIND_CONTROLS"
|
||||
android:protectionLevel="signature" />
|
||||
|
||||
@@ -25,9 +25,13 @@ import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.IIntentSender;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -44,6 +48,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@@ -59,6 +64,11 @@ import java.util.function.Consumer;
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ControlProviderServiceTest {
|
||||
|
||||
private static final ComponentName TEST_SYSUI_COMPONENT =
|
||||
ComponentName.unflattenFromString("sysui/.test.cls");
|
||||
private static final ComponentName TEST_COMPONENT =
|
||||
ComponentName.unflattenFromString("test.pkg/.test.cls");
|
||||
|
||||
private IBinder mToken = new Binder();
|
||||
@Mock
|
||||
private IControlsActionCallback.Stub mActionCallback;
|
||||
@@ -66,6 +76,12 @@ public class ControlProviderServiceTest {
|
||||
private IControlsSubscriber.Stub mSubscriber;
|
||||
@Mock
|
||||
private IIntentSender mIIntentSender;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
@Mock
|
||||
private Context mContext;
|
||||
@Captor
|
||||
private ArgumentCaptor<Intent> mIntentArgumentCaptor;
|
||||
|
||||
private PendingIntent mPendingIntent;
|
||||
private FakeControlsProviderService mControlsProviderService;
|
||||
@@ -81,6 +97,10 @@ public class ControlProviderServiceTest {
|
||||
when(mSubscriber.asBinder()).thenCallRealMethod();
|
||||
when(mSubscriber.queryLocalInterface(any())).thenReturn(mSubscriber);
|
||||
|
||||
when(mResources.getString(com.android.internal.R.string.config_systemUIServiceComponent))
|
||||
.thenReturn(TEST_SYSUI_COMPONENT.flattenToString());
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
|
||||
Bundle b = new Bundle();
|
||||
b.putBinder(ControlsProviderService.CALLBACK_TOKEN, mToken);
|
||||
Intent intent = new Intent();
|
||||
@@ -223,6 +243,21 @@ public class ControlProviderServiceTest {
|
||||
ControlAction.RESPONSE_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestAdd() {
|
||||
Control control = new Control.StatelessBuilder("TEST_ID", mPendingIntent).build();
|
||||
ControlsProviderService.requestAddControl(mContext, TEST_COMPONENT, control);
|
||||
|
||||
verify(mContext).sendBroadcast(mIntentArgumentCaptor.capture(),
|
||||
eq(Manifest.permission.BIND_CONTROLS));
|
||||
Intent intent = mIntentArgumentCaptor.getValue();
|
||||
assertEquals(ControlsProviderService.ACTION_ADD_CONTROL, intent.getAction());
|
||||
assertEquals(TEST_SYSUI_COMPONENT.getPackageName(), intent.getPackage());
|
||||
assertEquals(TEST_COMPONENT, intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME));
|
||||
assertTrue(equals(control,
|
||||
intent.getParcelableExtra(ControlsProviderService.EXTRA_CONTROL)));
|
||||
}
|
||||
|
||||
private static boolean equals(Control c1, Control c2) {
|
||||
if (c1 == c2) return true;
|
||||
if (c1 == null || c2 == null) return false;
|
||||
|
||||
Reference in New Issue
Block a user