Getting started

This section is designed to give engineers a 5-minute overview of how cross-profile calls work with the SDK and how they can be tested. Don't try to build anything yet - this isn't designed to be used as a reference or a guide, but just as an introduction.

Custom profile-aware classes and methods

The connected apps SDK lets you to annotate your own classes and methods as cross-profile. This generates classes and methods that allow you to execute the annotated method on any profile.

For example, consider the following class, with SDK annotation added:

public class CalendarDatabase {

  @CrossProfile // SDK annotation
  public void deleteEvent(Event event, Account account) {
    // complex logic with database calls
  }
}

This generates a class prefixed with Profile, allowing you to call this API on the profile of your choice. For example: java profileCalendarDatabase.work().deleteEvent(event, account);

More complex examples

More realistically, your classes and methods will be more complex. For example, your existing API could use ListenableFuture return types and you might need to combine results from both profiles. Consider this example:

public class CalendarDatabase {

  @CrossProfile // SDK annotation
  public ListenableFuture<Collection<Event>> getEvents() {
    // complex logic with database calls
  }
}
// Merge results from both profiles into a set
profileCalendarDatabase.both()
  .getEvents()
  .transform((Map<Profile, Collection<Event>> events) -> {
    return events.values()
        .stream()
        .flatMap(Collection::stream)
        .collect(Collectors.toSet());
  }, directExecutor());

These generated classes and methods work as expected with full type safety and IDE code completion.

Each return and parameter type of your annotated APIs must be supported by the SDK, but it fully supports nesting and generics of lists, sets, arrays, primitives, any parcelable type, and any serializable type, in addition to ListenableFuture, Optional, and protos. It's also possible for you to add support for types not natively supported by the SDK. As an extreme example, it would seamlessly support ListenableFuture<List<Map<CustomProto, CustomParcelableType[]>>>.

Testing

The SDK is designed to simplify unit testing. For each generated Profile class, there is a corresponding FakeProfile class that you can provide work and personal instances to. For example:

// Create an instance of the SDK-generated fake connector class. This
// class lets you control the availability of the profiles, which
// profile you are now running on.
private final FakeCrossProfileConnector connector =
  new FakeCrossProfileConnector();

// Create an instance of your real/fake/mock class for both profiles.
private final CalendarDatabase personalCalendarDatabase =
  new FakeCalendarDatabase();
private final CalendarDatabase workCalendarDatabase =
  new FakeCalendarDatabase();

// Create an instance of the SDK-generated fake profile-aware class.
private final FakeProfileCalendarDatabase profileCalendarDatabase =
  FakeProfileCalendarDatabase.builder()
    .personal(personalCalendarDatabase)
    .work(workCalendarDatabase)
    .connector(connector)
    .build();

// Pass profileCalendarDatabase into your classes under test, or set
// Dagger up to inject the fake automatically.