Skip to content

SmartPhoneClientManager

The main entry point of CARP Mobile Sensing (CAMS) on the phone.

A singleton that holds all studies running on this phone, deploys them via a DeploymentService, and gives one SmartphoneStudyController per study. An app calls configure once at startup, then adds studies with addStudyFromProtocol, addStudyFromInvitation or addStudy.

Key points:

  • configure must be called before adding studies. It initializes the infrastructure services, registers the built-in data managers, restores studies saved in earlier app runs and resumes their sampling.
  • Deploying a study (tryDeployment) does not resume its task controls. Use resume and pause to control sampling in all studies. (A connected device that connects does resume its own task controls.)
  • Permission requests go through requestPermissions, one at a time.
  • measurements merges the measurements of all studies on this phone.
  • Is a ChangeNotifier: listeners are notified when the list of studies or the sampling state changes. events emits ClientManagerState changes.

See also SmartphoneStudyController, which runs a single study, and DeviceController, which manages the devices on this phone.

await SmartPhoneClientManager().configure();
var study = await SmartPhoneClientManager().addStudyFromProtocol(protocol);
await SmartPhoneClientManager().tryDeployment(
  study.studyDeploymentId,
  study.deviceRoleName,
);
SmartPhoneClientManager().resume();
Inheritance
Mixed-in types

Constructors

SmartPhoneClientManager

SmartPhoneClientManager()

Returns the singleton SmartPhoneClientManager.

An app has only one client manager.

Properties

askForPermissions

bool get askForPermissions

Whether permissions are asked for automatically when a study is deployed.

Set in configure.

deviceController

DeviceController get deviceController

The DeviceController that manages all devices on this phone.

Only available after configure has been called.

events

A stream of ClientManagerState events.

measurements

Stream<Measurement> get measurements

All Measurements collected by all studies on this client.

Merges SmartphoneStudyController.measurements of each study, so measurements are already transformed by the study's privacy schema and data format. A broadcast stream.

notificationManager

NotificationManager get notificationManager

The NotificationManager that shows notifications for AppTasks.

state

ClientManagerState get state
set state (ClientManagerState state)

The runtime state of this client manager.

Setting it emits the new state on events and notifies listeners.

Methods

addStudy

Future<SmartphoneStudy> addStudy(
  1. SmartphoneStudy study
)
override

Add a study which needs to be executed on this client. No deployment is attempted yet.

If a study with the same deployment id and device role name has already been added to this client, nothing happens and this study is returned.

Throws NotConfiguredException if the client has not yet been configured. Return the study successfully added to this client manager or the existing study if it was already added.

addStudyFromInvitation

Future<SmartphoneStudy> addStudyFromInvitation(
  1. ActiveParticipationInvitation invitation
)

Adds a study based on an invitation, e.g. from a CARP server.

Same as addStudy, but the study is created from the invitation. If the invitation has no device role name, Smartphone.DEFAULT_ROLE_NAME is used.

addStudyFromProtocol

Future<SmartphoneStudy> addStudyFromProtocol(
  1. StudyProtocol protocol, [
  2. String? studyDeploymentId
])

Creates a study deployment from protocol and adds it as a study.

Same as addStudy, but first creates the deployment in the deploymentService. If studyDeploymentId is specified, it is used as the study deployment id. Otherwise the deployment service generates one.

Meant for local protocols with one participant: the local user id from Settings.userId is used as participant id, and the first participant role in the protocol (or 'Participant') as participant role name.

configure

Future<void> configure({
  1. SmartphoneRegistration? registration,
  2. DeploymentService? deploymentService,
  3. DeviceDataCollectorFactory? dataCollectorFactory,
  4. bool enableNotifications = true,
  5. bool enableBackgroundMode = true,
  6. String? backgroundNotificationTitle,
  7. String? backgroundNotificationText,
  8. bool askForPermissions = true,
  9. PermissionRequester permissionRequester = requestPermissionsInOrder,
})
override

Configures this SmartPhoneClientManager. Call once, before adding studies.

If deploymentService is not specified, the local SmartphoneDeploymentService is used. If dataCollectorFactory is not specified, the DeviceController singleton is used. The registration is a unique device registration for this phone. If not specified, it is created with Smartphone.createRegistration.

If enableNotifications is true (default), a notification is shown when an AppTask is triggered.

If enableBackgroundMode is true (default), data sampling will be enabled to run in the background. This means that data sampling will continue even when the app is not in the foreground, as long as the phone is not restarted. If background mode is enabled, the backgroundNotificationTitle and backgroundNotificationText can be specified to customize the notification shown when data sampling is running in the background. If not specified, default English titles and text will be used. If you want to use localized titles and text, you can provide them here. Note that background mode is only supported on Android, and will be ignored on iOS.

If askForPermissions is true (default), this client manager asks for the permissions of all measures in a study when it is deployed. Set it to false if the app handles permissions itself.

The permissionRequester decides how the user is asked whenever CAMS needs a permission. Defaults to requestPermissionsInOrder, which shows the system dialogs one at a time. Pass your own to, e.g., show a rationale before each dialog.

This method also restores all studies saved in earlier app runs and resumes sampling in the ones that were resumed.

Does nothing if the client manager is already configured.

dispose

void dispose()
override

Pauses and disposes all studies on this client.

Then closes the ExecutorFactory and PersistenceService.

The client manager cannot be used afterwards.

getStudyController

SmartphoneStudyController? getStudyController(
  1. SmartphoneStudy study
)

Returns the SmartphoneStudyController for study.

Creates a new controller the first time a study is looked up, and adds its measurements to measurements.

pause

void pause()

Pauses data sampling in all studies on this client.

removeStudy

Future<void> removeStudy(
  1. String studyDeploymentId,
  2. String deviceRoleName
)
override

Remove the study with studyDeploymentId and deviceRoleName from this client manager.

Note that by removing a study, the deployment is not marked as stopped permanently in the deployment service. Hence, the study can later be added and deployed again using the addStudy and tryDeployment methods.

If a study deployment is to be permanently stopped, use the stopStudy method.

requestPermissions

Future<void> requestPermissions(
  1. List<Permission> permissions
)

Asks the user for permissions with the configured PermissionRequester.

CAMS sends its permission requests through here (the notification permission is asked by the NotificationManager itself). Requests are queued and run one at a time: Android denies, without showing anything, any request made while another dialog is up.

A failing requester is logged, not rethrown. Callers re-check the actual permission status afterwards, and an error must not block the requests queued behind it.

resume

void resume()

Restarts data sampling in all studies on this client.

Calls SmartphoneStudyController.restart, so any stored sampling state is ignored and all task controls are resumed.

stopStudy

Future<StudyStatus> stopStudy(
  1. String studyDeploymentId,
  2. String deviceRoleName
)
override

Permanently stop collecting data for the study with id studyDeploymentId and mark it as stopped.

Once a study is stopped it cannot be deployed anymore since it will be marked as permanently stopped in the deployment service.

If you want to remove the study from this client and be able to redeploy it later, use the removeStudy method instead. Note that stopping a study does not remove it from this client manager.