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.