Loading services/core/java/com/android/server/am/ActiveServices.java +4 −2 Original line number Diff line number Diff line Loading @@ -3211,7 +3211,7 @@ public final class ActiveServices { // See if the intent refers to an alias. If so, update the intent with the target component // name. `resolution` will contain the alias component name, which we need to return // to the client. final ComponentAliasResolver.Resolution resolution = final ComponentAliasResolver.Resolution<ComponentName> resolution = mAm.mComponentAliasResolver.resolveService(service, resolvedType, /* match flags */ 0, userId, callingUid); Loading Loading @@ -3448,7 +3448,7 @@ public final class ActiveServices { return null; } } return new ServiceLookupResult(r, resolution.getAliasComponent()); return new ServiceLookupResult(r, resolution.getAlias()); } return null; } Loading Loading @@ -4448,6 +4448,8 @@ public final class ActiveServices { // being brought down. Mark it as dead. cr.serviceDead = true; cr.stopAssociation(); final ComponentName clientSideComponentName = cr.aliasComponent != null ? cr.aliasComponent : r.name; try { cr.conn.connected(r.name, null, true); } catch (Exception e) { Loading services/core/java/com/android/server/am/ComponentAliasResolver.java +15 −20 Original line number Diff line number Diff line Loading @@ -189,7 +189,7 @@ public class ComponentAliasResolver { @GuardedBy("mLock") private void loadOverridesLocked() { if (DEBUG) Slog.d(TAG, "Loading aliases overrides ..."); for (String line : mOverrideString.split("\\+")) { for (String line : mOverrideString.split("\\,+")) { final String[] fields = line.split("\\:+", 2); final ComponentName from = ComponentName.unflattenFromString(fields[0]); if (!validateComponentName(from)) { Loading Loading @@ -247,50 +247,45 @@ public class ComponentAliasResolver { /** * Contains alias resolution information. */ public static class Resolution { @NonNull public final Intent sourceIntent; public static class Resolution<T> { /** "From" component. Null if component alias is disabled. */ @Nullable public final ComponentName sourceComponent; public final T source; /** "To" component. Null if component alias is disabled, or the source isn't an alias. */ @Nullable public final ComponentName resolvedComponent; public final T resolved; public Resolution(Intent sourceIntent, ComponentName sourceComponent, ComponentName resolvedComponent) { this.sourceIntent = sourceIntent; this.sourceComponent = sourceComponent; this.resolvedComponent = resolvedComponent; public Resolution(T source, T resolved) { this.source = source; this.resolved = resolved; } @Nullable public boolean isAlias() { return this.resolvedComponent != null; return this.resolved != null; } @Nullable public ComponentName getAliasComponent() { return isAlias() ? sourceComponent : null; public T getAlias() { return isAlias() ? source : null; } @Nullable public ComponentName getTargetComponent() { return isAlias() ? resolvedComponent : null; public T getTarget() { return isAlias() ? resolved : null; } } @Nullable public Resolution resolveService( public Resolution<ComponentName> resolveService( @NonNull Intent service, @Nullable String resolvedType, int packageFlags, int userId, int callingUid) { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { if (!mEnabled) { return new Resolution(service, null, null); return new Resolution<>(null, null); } PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); Loading @@ -317,7 +312,7 @@ public class ComponentAliasResolver { + " -> " + target.flattenToShortString()); } } return new Resolution(service, alias, target); return new Resolution<>(alias, target); } } finally { Binder.restoreCallingIdentity(identity); Loading tests/componentalias/common/com/android/compatibility/common/util/BroadcastMessenger.java +81 −12 Original line number Diff line number Diff line Loading @@ -20,10 +20,13 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.HandlerThread; import android.os.Parcelable; import android.os.SystemClock; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import java.util.ArrayList; Loading @@ -37,39 +40,83 @@ public final class BroadcastMessenger { private static final String ACTION_MESSAGE = "com.android.compatibility.common.util.BroadcastMessenger.ACTION_MESSAGE"; private static final String ACTION_PING = "com.android.compatibility.common.util.BroadcastMessenger.ACTION_PING"; private static final String EXTRA_MESSAGE = "com.android.compatibility.common.util.BroadcastMessenger.EXTRA_MESSAGE"; /** Send a message to the {@link Receiver} in a given package. */ public static <T extends Parcelable> void send(@NonNull Context context, @NonNull String receiverPackage, @NonNull T message) { final Intent i = new Intent(ACTION_MESSAGE); i.putExtra(EXTRA_MESSAGE, message); /** * We need to drop messages that were sent before the receiver was created. We keep * track of the message send time in this extra. */ private static final String EXTRA_SENT_TIME = "com.android.compatibility.common.util.BroadcastMessenger.EXTRA_SENT_TIME"; private static long getCurrentTime() { return SystemClock.uptimeMillis(); } private static void sendBroadcast(@NonNull Intent i, @NonNull Context context, @NonNull String receiverPackage) { i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); i.setPackage(receiverPackage); i.putExtra(EXTRA_SENT_TIME, getCurrentTime()); Log.d(TAG, "Sending: " + message); context.sendBroadcast(i); } /** Send a message to the {@link Receiver} in a given package. */ public static <T extends Parcelable> void send(@NonNull Context context, @NonNull String receiverPackage, @NonNull T message) { final Intent i = new Intent(ACTION_MESSAGE); i.putExtra(EXTRA_MESSAGE, Preconditions.checkNotNull(message)); Log.i(TAG, "Sending: " + message); sendBroadcast(i, context, receiverPackage); } private static void sendPing(@NonNull Context context, @NonNull String receiverPackage) { final Intent i = new Intent(ACTION_PING); Log.i(TAG, "Sending a ping"); sendBroadcast(i, context, receiverPackage); } /** * Receive messages from the test app. * Receive messages sent with {@link #send}. Note it'll ignore all the messages that were * sent before instantiated. */ public static final class Receiver<T extends Parcelable> implements AutoCloseable { private final Context mContext; private final HandlerThread mReceiverThread = new HandlerThread(TAG); @GuardedBy("mMessages") private final ArrayList<T> mMessages = new ArrayList<>(); private final long mCreatedTime = getCurrentTime(); private boolean mRegistered; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!ACTION_MESSAGE.equals(intent.getAction())) { throw new RuntimeException("Unknown message received: " + intent); // Log.d(TAG, "Received intent: " + intent); switch (intent.getAction()) { case ACTION_MESSAGE: case ACTION_PING: break; default: throw new RuntimeException("Unknown broadcast received: " + intent); } if (intent.getLongExtra(EXTRA_SENT_TIME, 0) < mCreatedTime) { Log.i(TAG, "Dropping stale broadcast: " + intent); return; } // Note for a PING, the message will be null. final T message = intent.getParcelableExtra(EXTRA_MESSAGE); Log.d(TAG, "Received: " + message); if (message != null) { Log.i(TAG, "Received: " + message); } synchronized (mMessages) { mMessages.add(message); mMessages.notifyAll(); Loading @@ -83,8 +130,13 @@ public final class BroadcastMessenger { public Receiver(@NonNull Context context) { mContext = context; mReceiverThread.start(); final IntentFilter fi = new IntentFilter(ACTION_MESSAGE); context.registerReceiver(mReceiver, fi); fi.addAction(ACTION_PING); context.registerReceiver(mReceiver, fi, /** permission=*/ null, mReceiverThread.getThreadHandler()); mRegistered = true; } Loading @@ -92,6 +144,7 @@ public final class BroadcastMessenger { public void close() { if (mRegistered) { mContext.unregisterReceiver(mReceiver); mReceiverThread.quit(); mRegistered = false; } } Loading Loading @@ -121,5 +174,21 @@ public final class BroadcastMessenger { return mMessages.remove(0); } } /** * Ensure that no further messages have been received. * * Call it before {@link #close()}. */ public void ensureNoMoreMessages() throws Exception { // Send a ping to myself. sendPing(mContext, mContext.getPackageName()); final T m = waitForNextMessage(); if (m == null) { return; // Okay. Ping will deliver a null message. } throw new RuntimeException("No more messages expected, but received: " + m); } } } tests/componentalias/src/android/content/componentalias/tests/ComponentAliasServiceTest.java +61 −17 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.content.componentalias.tests.common.ComponentAliasTestComm import static android.content.componentalias.tests.common.ComponentAliasTestCommon.SUB1_PACKAGE; import static android.content.componentalias.tests.common.ComponentAliasTestCommon.SUB2_PACKAGE; import static android.content.componentalias.tests.common.ComponentAliasTestCommon.TAG; import static android.content.componentalias.tests.common.ComponentAliasTestCommon.TEST_PACKAGE; import static com.google.common.truth.Truth.assertThat; Loading @@ -34,18 +33,16 @@ import android.os.IBinder; import android.provider.DeviceConfig; import android.util.Log; import androidx.test.InstrumentationRegistry; import com.android.compatibility.common.util.BroadcastMessenger; import com.android.compatibility.common.util.BroadcastMessenger.Receiver; import com.android.compatibility.common.util.DeviceConfigStateHelper; import com.android.compatibility.common.util.ShellUtils; import com.android.compatibility.common.util.TestUtils; import androidx.test.InstrumentationRegistry; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /** Loading Loading @@ -95,7 +92,7 @@ public class ComponentAliasServiceTest { .setMethodName("onServiceConnected") .setComponent(name); BroadcastMessenger.send(sContext, TEST_PACKAGE, m); BroadcastMessenger.send(sContext, sContext.getPackageName(), m); } @Override Loading @@ -107,7 +104,7 @@ public class ComponentAliasServiceTest { .setMethodName("onServiceDisconnected") .setComponent(name); BroadcastMessenger.send(sContext, TEST_PACKAGE, m); BroadcastMessenger.send(sContext, sContext.getPackageName(), m); } @Override Loading @@ -118,7 +115,7 @@ public class ComponentAliasServiceTest { .setSenderIdentity("sServiceConnection") .setMethodName("onBindingDied"); BroadcastMessenger.send(sContext, TEST_PACKAGE, m); BroadcastMessenger.send(sContext, sContext.getPackageName(), m); } @Override Loading @@ -129,7 +126,7 @@ public class ComponentAliasServiceTest { .setSenderIdentity("sServiceConnection") .setMethodName("onNullBinding"); BroadcastMessenger.send(sContext, TEST_PACKAGE, m); BroadcastMessenger.send(sContext, sContext.getPackageName(), m); } }; Loading Loading @@ -165,6 +162,8 @@ public class ComponentAliasServiceTest { m = receiver.waitForNextMessage(); assertThat(m.getMethodName()).isEqualTo("onDestroy"); receiver.ensureNoMoreMessages(); } } Loading Loading @@ -193,24 +192,29 @@ public class ComponentAliasServiceTest { @Test public void testStartAndStopService_override() throws Exception { Intent i = new Intent().setPackage(APP_PACKAGE); i.setAction(APP_PACKAGE + ".IS_ALIAS_02"); i.setAction(APP_PACKAGE + ".IS_ALIAS_01"); ComponentName alias = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias02"); // Change some of the aliases from what's defined in <meta-data>. ComponentName aliasA = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias01"); ComponentName targetA = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Target02"); // Note, alias02 originally points at sub*2* package, but we override it in this test. ComponentName target = new ComponentName(SUB1_PACKAGE, APP_PACKAGE + ".s.Target02"); ComponentName aliasB = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias02"); ComponentName targetB = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Target01"); sDeviceConfig.set("component_alias_overrides", alias.flattenToShortString() + ":" + target.flattenToShortString()); aliasA.flattenToShortString() + ":" + targetA.flattenToShortString() + "," + aliasB.flattenToShortString() + ":" + targetB.flattenToShortString()); TestUtils.waitUntil("Wait until component alias is actually enabled", () -> { return ShellUtils.runShellCommand("dumpsys activity component-alias") .indexOf(alias.flattenToShortString() + " -> " + target.flattenToShortString()) > 0; .indexOf(aliasA.flattenToShortString() + " -> " + targetA.flattenToShortString()) > 0; }); testStartAndStopService_common(i, alias, target); testStartAndStopService_common(i, aliasA, targetA); } private void testBindAndUnbindService_common( Loading Loading @@ -253,6 +257,7 @@ public class ComponentAliasServiceTest { assertThat(m.getMethodName()).isEqualTo("onDestroy"); // Note onServiceDisconnected() won't be called in this case. receiver.ensureNoMoreMessages(); } } Loading @@ -275,4 +280,43 @@ public class ComponentAliasServiceTest { new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias02"), new ComponentName(SUB2_PACKAGE, APP_PACKAGE + ".s.Target02")); } @Test public void testBindService_serviceKilled() throws Exception { Intent originalIntent = new Intent().setPackage(APP_PACKAGE); originalIntent.setAction(APP_PACKAGE + ".IS_ALIAS_02"); final ComponentName componentNameForClient = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias02"); final ComponentName componentNameForTarget = new ComponentName(SUB2_PACKAGE, APP_PACKAGE + ".s.Target02"); ComponentAliasMessage m; try (Receiver<ComponentAliasMessage> receiver = new Receiver<>(sContext)) { // Bind to the service. assertThat(sContext.bindService( originalIntent, sServiceConnection, BIND_AUTO_CREATE)).isTrue(); // Check the target side behavior. m = receiver.waitForNextMessage(); assertThat(m.getMethodName()).isEqualTo("onBind"); m = receiver.waitForNextMessage(); assertThat(m.getMethodName()).isEqualTo("onServiceConnected"); assertThat(m.getComponent()).isEqualTo(componentNameForClient); // Now kill the service process. ShellUtils.runShellCommand("su 0 killall %s", SUB2_PACKAGE); // Check the target side behavior. m = receiver.waitForNextMessage(); assertThat(m.getMethodName()).isEqualTo("onServiceDisconnected"); assertThat(m.getComponent()).isEqualTo(componentNameForClient); receiver.ensureNoMoreMessages(); } } } Loading
services/core/java/com/android/server/am/ActiveServices.java +4 −2 Original line number Diff line number Diff line Loading @@ -3211,7 +3211,7 @@ public final class ActiveServices { // See if the intent refers to an alias. If so, update the intent with the target component // name. `resolution` will contain the alias component name, which we need to return // to the client. final ComponentAliasResolver.Resolution resolution = final ComponentAliasResolver.Resolution<ComponentName> resolution = mAm.mComponentAliasResolver.resolveService(service, resolvedType, /* match flags */ 0, userId, callingUid); Loading Loading @@ -3448,7 +3448,7 @@ public final class ActiveServices { return null; } } return new ServiceLookupResult(r, resolution.getAliasComponent()); return new ServiceLookupResult(r, resolution.getAlias()); } return null; } Loading Loading @@ -4448,6 +4448,8 @@ public final class ActiveServices { // being brought down. Mark it as dead. cr.serviceDead = true; cr.stopAssociation(); final ComponentName clientSideComponentName = cr.aliasComponent != null ? cr.aliasComponent : r.name; try { cr.conn.connected(r.name, null, true); } catch (Exception e) { Loading
services/core/java/com/android/server/am/ComponentAliasResolver.java +15 −20 Original line number Diff line number Diff line Loading @@ -189,7 +189,7 @@ public class ComponentAliasResolver { @GuardedBy("mLock") private void loadOverridesLocked() { if (DEBUG) Slog.d(TAG, "Loading aliases overrides ..."); for (String line : mOverrideString.split("\\+")) { for (String line : mOverrideString.split("\\,+")) { final String[] fields = line.split("\\:+", 2); final ComponentName from = ComponentName.unflattenFromString(fields[0]); if (!validateComponentName(from)) { Loading Loading @@ -247,50 +247,45 @@ public class ComponentAliasResolver { /** * Contains alias resolution information. */ public static class Resolution { @NonNull public final Intent sourceIntent; public static class Resolution<T> { /** "From" component. Null if component alias is disabled. */ @Nullable public final ComponentName sourceComponent; public final T source; /** "To" component. Null if component alias is disabled, or the source isn't an alias. */ @Nullable public final ComponentName resolvedComponent; public final T resolved; public Resolution(Intent sourceIntent, ComponentName sourceComponent, ComponentName resolvedComponent) { this.sourceIntent = sourceIntent; this.sourceComponent = sourceComponent; this.resolvedComponent = resolvedComponent; public Resolution(T source, T resolved) { this.source = source; this.resolved = resolved; } @Nullable public boolean isAlias() { return this.resolvedComponent != null; return this.resolved != null; } @Nullable public ComponentName getAliasComponent() { return isAlias() ? sourceComponent : null; public T getAlias() { return isAlias() ? source : null; } @Nullable public ComponentName getTargetComponent() { return isAlias() ? resolvedComponent : null; public T getTarget() { return isAlias() ? resolved : null; } } @Nullable public Resolution resolveService( public Resolution<ComponentName> resolveService( @NonNull Intent service, @Nullable String resolvedType, int packageFlags, int userId, int callingUid) { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { if (!mEnabled) { return new Resolution(service, null, null); return new Resolution<>(null, null); } PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); Loading @@ -317,7 +312,7 @@ public class ComponentAliasResolver { + " -> " + target.flattenToShortString()); } } return new Resolution(service, alias, target); return new Resolution<>(alias, target); } } finally { Binder.restoreCallingIdentity(identity); Loading
tests/componentalias/common/com/android/compatibility/common/util/BroadcastMessenger.java +81 −12 Original line number Diff line number Diff line Loading @@ -20,10 +20,13 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.HandlerThread; import android.os.Parcelable; import android.os.SystemClock; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import java.util.ArrayList; Loading @@ -37,39 +40,83 @@ public final class BroadcastMessenger { private static final String ACTION_MESSAGE = "com.android.compatibility.common.util.BroadcastMessenger.ACTION_MESSAGE"; private static final String ACTION_PING = "com.android.compatibility.common.util.BroadcastMessenger.ACTION_PING"; private static final String EXTRA_MESSAGE = "com.android.compatibility.common.util.BroadcastMessenger.EXTRA_MESSAGE"; /** Send a message to the {@link Receiver} in a given package. */ public static <T extends Parcelable> void send(@NonNull Context context, @NonNull String receiverPackage, @NonNull T message) { final Intent i = new Intent(ACTION_MESSAGE); i.putExtra(EXTRA_MESSAGE, message); /** * We need to drop messages that were sent before the receiver was created. We keep * track of the message send time in this extra. */ private static final String EXTRA_SENT_TIME = "com.android.compatibility.common.util.BroadcastMessenger.EXTRA_SENT_TIME"; private static long getCurrentTime() { return SystemClock.uptimeMillis(); } private static void sendBroadcast(@NonNull Intent i, @NonNull Context context, @NonNull String receiverPackage) { i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); i.setPackage(receiverPackage); i.putExtra(EXTRA_SENT_TIME, getCurrentTime()); Log.d(TAG, "Sending: " + message); context.sendBroadcast(i); } /** Send a message to the {@link Receiver} in a given package. */ public static <T extends Parcelable> void send(@NonNull Context context, @NonNull String receiverPackage, @NonNull T message) { final Intent i = new Intent(ACTION_MESSAGE); i.putExtra(EXTRA_MESSAGE, Preconditions.checkNotNull(message)); Log.i(TAG, "Sending: " + message); sendBroadcast(i, context, receiverPackage); } private static void sendPing(@NonNull Context context, @NonNull String receiverPackage) { final Intent i = new Intent(ACTION_PING); Log.i(TAG, "Sending a ping"); sendBroadcast(i, context, receiverPackage); } /** * Receive messages from the test app. * Receive messages sent with {@link #send}. Note it'll ignore all the messages that were * sent before instantiated. */ public static final class Receiver<T extends Parcelable> implements AutoCloseable { private final Context mContext; private final HandlerThread mReceiverThread = new HandlerThread(TAG); @GuardedBy("mMessages") private final ArrayList<T> mMessages = new ArrayList<>(); private final long mCreatedTime = getCurrentTime(); private boolean mRegistered; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!ACTION_MESSAGE.equals(intent.getAction())) { throw new RuntimeException("Unknown message received: " + intent); // Log.d(TAG, "Received intent: " + intent); switch (intent.getAction()) { case ACTION_MESSAGE: case ACTION_PING: break; default: throw new RuntimeException("Unknown broadcast received: " + intent); } if (intent.getLongExtra(EXTRA_SENT_TIME, 0) < mCreatedTime) { Log.i(TAG, "Dropping stale broadcast: " + intent); return; } // Note for a PING, the message will be null. final T message = intent.getParcelableExtra(EXTRA_MESSAGE); Log.d(TAG, "Received: " + message); if (message != null) { Log.i(TAG, "Received: " + message); } synchronized (mMessages) { mMessages.add(message); mMessages.notifyAll(); Loading @@ -83,8 +130,13 @@ public final class BroadcastMessenger { public Receiver(@NonNull Context context) { mContext = context; mReceiverThread.start(); final IntentFilter fi = new IntentFilter(ACTION_MESSAGE); context.registerReceiver(mReceiver, fi); fi.addAction(ACTION_PING); context.registerReceiver(mReceiver, fi, /** permission=*/ null, mReceiverThread.getThreadHandler()); mRegistered = true; } Loading @@ -92,6 +144,7 @@ public final class BroadcastMessenger { public void close() { if (mRegistered) { mContext.unregisterReceiver(mReceiver); mReceiverThread.quit(); mRegistered = false; } } Loading Loading @@ -121,5 +174,21 @@ public final class BroadcastMessenger { return mMessages.remove(0); } } /** * Ensure that no further messages have been received. * * Call it before {@link #close()}. */ public void ensureNoMoreMessages() throws Exception { // Send a ping to myself. sendPing(mContext, mContext.getPackageName()); final T m = waitForNextMessage(); if (m == null) { return; // Okay. Ping will deliver a null message. } throw new RuntimeException("No more messages expected, but received: " + m); } } }
tests/componentalias/src/android/content/componentalias/tests/ComponentAliasServiceTest.java +61 −17 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.content.componentalias.tests.common.ComponentAliasTestComm import static android.content.componentalias.tests.common.ComponentAliasTestCommon.SUB1_PACKAGE; import static android.content.componentalias.tests.common.ComponentAliasTestCommon.SUB2_PACKAGE; import static android.content.componentalias.tests.common.ComponentAliasTestCommon.TAG; import static android.content.componentalias.tests.common.ComponentAliasTestCommon.TEST_PACKAGE; import static com.google.common.truth.Truth.assertThat; Loading @@ -34,18 +33,16 @@ import android.os.IBinder; import android.provider.DeviceConfig; import android.util.Log; import androidx.test.InstrumentationRegistry; import com.android.compatibility.common.util.BroadcastMessenger; import com.android.compatibility.common.util.BroadcastMessenger.Receiver; import com.android.compatibility.common.util.DeviceConfigStateHelper; import com.android.compatibility.common.util.ShellUtils; import com.android.compatibility.common.util.TestUtils; import androidx.test.InstrumentationRegistry; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /** Loading Loading @@ -95,7 +92,7 @@ public class ComponentAliasServiceTest { .setMethodName("onServiceConnected") .setComponent(name); BroadcastMessenger.send(sContext, TEST_PACKAGE, m); BroadcastMessenger.send(sContext, sContext.getPackageName(), m); } @Override Loading @@ -107,7 +104,7 @@ public class ComponentAliasServiceTest { .setMethodName("onServiceDisconnected") .setComponent(name); BroadcastMessenger.send(sContext, TEST_PACKAGE, m); BroadcastMessenger.send(sContext, sContext.getPackageName(), m); } @Override Loading @@ -118,7 +115,7 @@ public class ComponentAliasServiceTest { .setSenderIdentity("sServiceConnection") .setMethodName("onBindingDied"); BroadcastMessenger.send(sContext, TEST_PACKAGE, m); BroadcastMessenger.send(sContext, sContext.getPackageName(), m); } @Override Loading @@ -129,7 +126,7 @@ public class ComponentAliasServiceTest { .setSenderIdentity("sServiceConnection") .setMethodName("onNullBinding"); BroadcastMessenger.send(sContext, TEST_PACKAGE, m); BroadcastMessenger.send(sContext, sContext.getPackageName(), m); } }; Loading Loading @@ -165,6 +162,8 @@ public class ComponentAliasServiceTest { m = receiver.waitForNextMessage(); assertThat(m.getMethodName()).isEqualTo("onDestroy"); receiver.ensureNoMoreMessages(); } } Loading Loading @@ -193,24 +192,29 @@ public class ComponentAliasServiceTest { @Test public void testStartAndStopService_override() throws Exception { Intent i = new Intent().setPackage(APP_PACKAGE); i.setAction(APP_PACKAGE + ".IS_ALIAS_02"); i.setAction(APP_PACKAGE + ".IS_ALIAS_01"); ComponentName alias = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias02"); // Change some of the aliases from what's defined in <meta-data>. ComponentName aliasA = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias01"); ComponentName targetA = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Target02"); // Note, alias02 originally points at sub*2* package, but we override it in this test. ComponentName target = new ComponentName(SUB1_PACKAGE, APP_PACKAGE + ".s.Target02"); ComponentName aliasB = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias02"); ComponentName targetB = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Target01"); sDeviceConfig.set("component_alias_overrides", alias.flattenToShortString() + ":" + target.flattenToShortString()); aliasA.flattenToShortString() + ":" + targetA.flattenToShortString() + "," + aliasB.flattenToShortString() + ":" + targetB.flattenToShortString()); TestUtils.waitUntil("Wait until component alias is actually enabled", () -> { return ShellUtils.runShellCommand("dumpsys activity component-alias") .indexOf(alias.flattenToShortString() + " -> " + target.flattenToShortString()) > 0; .indexOf(aliasA.flattenToShortString() + " -> " + targetA.flattenToShortString()) > 0; }); testStartAndStopService_common(i, alias, target); testStartAndStopService_common(i, aliasA, targetA); } private void testBindAndUnbindService_common( Loading Loading @@ -253,6 +257,7 @@ public class ComponentAliasServiceTest { assertThat(m.getMethodName()).isEqualTo("onDestroy"); // Note onServiceDisconnected() won't be called in this case. receiver.ensureNoMoreMessages(); } } Loading @@ -275,4 +280,43 @@ public class ComponentAliasServiceTest { new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias02"), new ComponentName(SUB2_PACKAGE, APP_PACKAGE + ".s.Target02")); } @Test public void testBindService_serviceKilled() throws Exception { Intent originalIntent = new Intent().setPackage(APP_PACKAGE); originalIntent.setAction(APP_PACKAGE + ".IS_ALIAS_02"); final ComponentName componentNameForClient = new ComponentName(APP_PACKAGE, APP_PACKAGE + ".s.Alias02"); final ComponentName componentNameForTarget = new ComponentName(SUB2_PACKAGE, APP_PACKAGE + ".s.Target02"); ComponentAliasMessage m; try (Receiver<ComponentAliasMessage> receiver = new Receiver<>(sContext)) { // Bind to the service. assertThat(sContext.bindService( originalIntent, sServiceConnection, BIND_AUTO_CREATE)).isTrue(); // Check the target side behavior. m = receiver.waitForNextMessage(); assertThat(m.getMethodName()).isEqualTo("onBind"); m = receiver.waitForNextMessage(); assertThat(m.getMethodName()).isEqualTo("onServiceConnected"); assertThat(m.getComponent()).isEqualTo(componentNameForClient); // Now kill the service process. ShellUtils.runShellCommand("su 0 killall %s", SUB2_PACKAGE); // Check the target side behavior. m = receiver.waitForNextMessage(); assertThat(m.getMethodName()).isEqualTo("onServiceDisconnected"); assertThat(m.getComponent()).isEqualTo(componentNameForClient); receiver.ensureNoMoreMessages(); } } }