Merge "Create startForeground option in VendorServiceController." into qt-dev
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index 4aef4a5..a81bed4 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -155,12 +155,14 @@
Every item in this array contains a flatten component name of a service that needs to be
started and a list of parameters after hashtag symbol. Here's the format:
- <item>com.bar.foo/.Service#bind={true|false},user={all|system|foreground},trigger={asap,userUnlocked}</item>
+ <item>com.bar.foo/.Service#bind={bind|start|startForeground},user={all|system|foreground},
+ trigger={asap,userUnlocked}</item>
- bind: indicates whether service needs to be bound or started, if the value is 'true'
- the service will be bound by calling Context#bindService(...), otherwise it will
- be started using Context#startService. If service was bound it will be restarted
- unless it is constantly crashing. The default value is 'false'
+ bind: bind - start service with Context#bindService
+ start - start service with Context#startService
+ startForeground - start service with Context#startForegroundService
+ If service was bound it will be restarted unless it is constantly crashing.
+ The default value is 'start'
user: all - the service will be bound/started for system and all foreground users
system - the service will be started/bound only for system user (u0)
foreground - the service will be bound/started only for foreground users
@@ -175,7 +177,7 @@
is no longer foreground.
-->
<string-array translatable="false" name="config_earlyStartupServices">
- <!-- list your services here -->
+ <item>com.android.car.messenger/.MessengerService#bind=startForeground,user=foreground,trigger=userUnlocked</item>
</string-array>
<string name="config_TetheredProjectionAccessPointSsid" translatable="false">CarAP</string>
diff --git a/service/src/com/android/car/pm/VendorServiceController.java b/service/src/com/android/car/pm/VendorServiceController.java
index 0c8eae3..189370e 100644
--- a/service/src/com/android/car/pm/VendorServiceController.java
+++ b/service/src/com/android/car/pm/VendorServiceController.java
@@ -300,6 +300,9 @@
Intent intent = mVendorServiceInfo.getIntent();
if (mVendorServiceInfo.shouldBeBound()) {
return mContext.bindServiceAsUser(intent, this, BIND_AUTO_CREATE, mHandler, mUser);
+ } else if (mVendorServiceInfo.shouldBeStartedInForeground()) {
+ mStarted = mContext.startForegroundServiceAsUser(intent, mUser) != null;
+ return mStarted;
} else {
mStarted = mContext.startServiceAsUser(intent, mUser) != null;
return mStarted;
diff --git a/service/src/com/android/car/pm/VendorServiceInfo.java b/service/src/com/android/car/pm/VendorServiceInfo.java
index 94a50a0..ba79978 100644
--- a/service/src/com/android/car/pm/VendorServiceInfo.java
+++ b/service/src/com/android/car/pm/VendorServiceInfo.java
@@ -53,17 +53,28 @@
})
@interface Trigger {}
- private final boolean mBind;
+ private static final int BIND = 0;
+ private static final int START = 1;
+ private static final int START_FOREGROUND = 2;
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ BIND,
+ START,
+ START_FOREGROUND,
+ })
+ @interface Bind {}
+
+ private final @Bind int mBind;
private final @UserScope int mUserScope;
private final @Trigger int mTrigger;
private final ComponentName mComponentName;
- private VendorServiceInfo(ComponentName componentName, boolean bind, @UserScope int userScope,
+ private VendorServiceInfo(ComponentName componentName, @Bind int bind, @UserScope int userScope,
@Trigger int trigger) {
mComponentName = componentName;
- mBind = bind;
mUserScope = userScope;
mTrigger = trigger;
+ mBind = bind;
}
boolean isSystemUserService() {
@@ -83,7 +94,11 @@
}
boolean shouldBeBound() {
- return mBind;
+ return mBind == BIND;
+ }
+
+ boolean shouldBeStartedInForeground() {
+ return mBind == START_FOREGROUND;
}
Intent getIntent() {
@@ -102,11 +117,11 @@
final ComponentName cn = ComponentName.unflattenFromString(serviceParamTokens[0]);
if (cn == null) {
- throw new IllegalArgumentException("Failed to parse service info: "
- + rawServiceInfo + ", expected a single '#' symbol");
+ throw new IllegalArgumentException("Failed to unflatten component name from: "
+ + rawServiceInfo);
}
- boolean bind = false;
+ int bind = START;
int userScope = USER_SCOPE_ALL;
int trigger = TRIGGER_UNLOCKED;
@@ -121,7 +136,15 @@
switch (key) {
case KEY_BIND:
- bind = TextUtils.equals("true", val.toLowerCase());
+ if ("bind".equals(val)) {
+ bind = BIND;
+ } else if ("start".equals(val)) {
+ bind = START;
+ } else if ("startForeground".equals(val)) {
+ bind = START_FOREGROUND;
+ } else {
+ throw new IllegalArgumentException("Unexpected bind option: " + val);
+ }
break;
case KEY_USER_SCOPE:
if ("all".equals(val)) {
diff --git a/tests/carservice_unit_test/src/com/android/car/pm/VendorServiceInfoTest.java b/tests/carservice_unit_test/src/com/android/car/pm/VendorServiceInfoTest.java
index 3045276..8174add 100644
--- a/tests/carservice_unit_test/src/com/android/car/pm/VendorServiceInfoTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/pm/VendorServiceInfoTest.java
@@ -43,7 +43,7 @@
@Test
public void multipleHashTags() {
exception.expect(IllegalArgumentException.class);
- VendorServiceInfo.parse(SERVICE_NAME + "#user=system#bind=true");
+ VendorServiceInfo.parse(SERVICE_NAME + "#user=system#bind=bind");
}
@Test
@@ -64,6 +64,7 @@
assertThat(info.getIntent().getComponent())
.isEqualTo(ComponentName.unflattenFromString(SERVICE_NAME));
assertThat(info.shouldBeBound()).isFalse();
+ assertThat(info.shouldBeStartedInForeground()).isFalse();
assertThat(info.isSystemUserService()).isTrue();
assertThat(info.isForegroundUserService()).isTrue();
assertThat(info.shouldStartOnUnlock()).isTrue();
@@ -71,16 +72,25 @@
@Test
public void startService() {
- VendorServiceInfo info = VendorServiceInfo.parse(SERVICE_NAME + "#bind=false");
+ VendorServiceInfo info = VendorServiceInfo.parse(SERVICE_NAME + "#bind=start");
assertThat(info.shouldBeBound()).isFalse();
+ assertThat(info.shouldBeStartedInForeground()).isFalse();
assertThat(info.getIntent().getComponent())
.isEqualTo(ComponentName.unflattenFromString(SERVICE_NAME));
}
@Test
public void bindService() {
- VendorServiceInfo info = VendorServiceInfo.parse(SERVICE_NAME + "#bind=true");
+ VendorServiceInfo info = VendorServiceInfo.parse(SERVICE_NAME + "#bind=bind");
assertThat(info.shouldBeBound()).isTrue();
+ assertThat(info.shouldBeStartedInForeground()).isFalse();
+ }
+
+ @Test
+ public void startServiceInForeground() {
+ VendorServiceInfo info = VendorServiceInfo.parse(SERVICE_NAME + "#bind=startForeground");
+ assertThat(info.shouldBeBound()).isFalse();
+ assertThat(info.shouldBeStartedInForeground()).isTrue();
}
@Test
@@ -131,7 +141,7 @@
@Test
public void allArgs() {
VendorServiceInfo info = VendorServiceInfo.parse(SERVICE_NAME
- + "#bind=true,user=foreground,trigger=userUnlocked");
+ + "#bind=bind,user=foreground,trigger=userUnlocked");
assertThat(info.getIntent().getComponent())
.isEqualTo(ComponentName.unflattenFromString(SERVICE_NAME));
assertThat(info.shouldBeBound()).isTrue();