Documentation

Horde_ActiveSync_Device
in package

Horde_ActiveSync_Device:: Wraps all functionality related to device data.

Tags
license

http://www.horde.org/licenses/gpl GPLv2

copyright

2010-2020 Horde LLC (http://www.horde.org)

author

Michael J Rubinsky mrubinsk@horde.org

Table of Contents

ANNOUNCED_VERSION  = 'announcedVersion'
BLOCKED  = 'blocked'
IMEI  = 'Settings:IMEI'
MODEL  = 'Settings:Model'
MULTIPLEX  = 'multiplex'
MULTIPLEX_CALENDAR  = 2
MULTIPLEX_CONTACTS  = 1
MULTIPLEX_NOTES  = 8
MULTIPLEX_TASKS  = 4
NAME  = 'Settings:FriendlyName'
OPERATOR  = 'Settings:MobileOperator'
OS  = 'Settings:OS'
OS_LANGUAGE  = 'Settings:OSLanguage'
PHONE_NUMBER  = 'Settings:PhoneNumber'
QUIRK_INCORRECTLY_SENDS_EMPTY_PICTURE_TAG  = 2
iOS sends an empty picture tag on every edit of contacts whose pictures did not originate on the client itself.
QUIRK_NEEDS_SUPPORTED_PICTURE_TAG  = 1
Quirk to specify if the client fails to property ghost the POOMCONTACTS:Picture field. If this quirk is present, it means we should add the POOMCONTACTS:Picture field to the SUPPORTED array for this client.
QUIRK_SUPPORTS_TNEF  = 3
These client can support TNEF data without decoding it first.
TYPE_ANDROID  = 'android'
TYPE_BLACKBERRY  = 'blackberry'
TYPE_GMAIL  = 'gmail'
TYPE_IPAD  = 'ipad'
TYPE_IPHONE  = 'iphone'
TYPE_IPOD  = 'ipod'
TYPE_NINE  = 'nine'
TYPE_TOUCHDOWN  = 'touchdown'
TYPE_UNKNOWN  = 'unknown'
TYPE_WEBOS  = 'webos'
TYPE_WP  = 'windowsphone'
VERSION  = 'version'
$announcedVersion  : string
$blocked  : bool
$clientType  : string
$deviceType  : string
$id  : string
$multiplex  : int
$policykey  : string
$properties  : array<string|int, mixed>
$rwstatus  : int
$supported  : array<string|int, mixed>
$user  : string
$userAgent  : string
$_clientType  : string
Local override/cache of detected clientType.
$_dirty  : array<string|int, mixed>
Dirty flag
$_iOSVersion  : string
Cache of OS version.
$_multiplexSet  : bool
Flag to indicate self::multiplex was set externally.
$_properties  : array<string|int, mixed>
Device properties.
$_state  : Horde_ActiveSync_State_Base
State handler
__construct()  : mixed
Const'r
__get()  : mixed
Getter
__isset()  : mixed
Magic isset
__set()  : mixed
Setter
__toString()  : mixed
enforceProvisioning()  : bool
Check if we should enforce provisioning on this device.
getFormattedDeviceProperties()  : array<string|int, mixed>
Return an array of DEVICEINFO data, with keys suitable for displaying.
getLastSyncTimestamp()  : int
Return the last time the device issued a SYNC request.
getMajorVersion()  : int
Return the major version number of the OS (or client app) as reported by the client.
getMinorVersion()  : int
Return the minor version number of the OS (or client app) as reported by the client.
hasQuirk()  : bool
Return if this client has the described quirk.
isNonProvisionable()  : bool
Returns if the current device is an expected non-provisionable device.
needsVersionUpdate()  : bool
Indicates if we need to announce new EAS version string to the client.
normalizePoomContactsDates()  : Horde_Date
Return the number of hours to offset a POOMCONTACTS:BIRTHDAY or ANNIVERSARY field in an attempt to work around a bug in the protocol - the protocol states that "the time portion SHOULD be ignored, so that synchronizing between different timezones does not change the date" (MS-ASCNTC 2.2.2.6). However, it appears that next to zero clients actually honor this.
save()  : mixed
Save the dirty device info data.
setDeviceProperties()  : mixed
Set the device's DEVICEINFO data.
_getClientType()  : string
Attempt to determine the *client* application as opposed to the device, which may or may not be the client.
_getIosVersion()  : mixed
Detects the iOS version in M.m format and caches locally.
_isIos()  : bool
Return if this client is an iOS device. Different versions require different checks.
_isNine()  : bool
Helper method to sniff out the 9Folders client, "Nine".
_sniffMultiplex()  : mixed
Basic sniffing for determining if devices can support non-multiplexed collections.

Constants

ANNOUNCED_VERSION

public mixed ANNOUNCED_VERSION = 'announcedVersion'

BLOCKED

public mixed BLOCKED = 'blocked'

IMEI

public mixed IMEI = 'Settings:IMEI'

MODEL

public mixed MODEL = 'Settings:Model'

MULTIPLEX

public mixed MULTIPLEX = 'multiplex'

MULTIPLEX_CALENDAR

public mixed MULTIPLEX_CALENDAR = 2

MULTIPLEX_CONTACTS

public mixed MULTIPLEX_CONTACTS = 1

MULTIPLEX_NOTES

public mixed MULTIPLEX_NOTES = 8

MULTIPLEX_TASKS

public mixed MULTIPLEX_TASKS = 4

NAME

public mixed NAME = 'Settings:FriendlyName'

OPERATOR

public mixed OPERATOR = 'Settings:MobileOperator'

OS

public mixed OS = 'Settings:OS'

OS_LANGUAGE

public mixed OS_LANGUAGE = 'Settings:OSLanguage'

PHONE_NUMBER

public mixed PHONE_NUMBER = 'Settings:PhoneNumber'

QUIRK_INCORRECTLY_SENDS_EMPTY_PICTURE_TAG

iOS sends an empty picture tag on every edit of contacts whose pictures did not originate on the client itself.

public mixed QUIRK_INCORRECTLY_SENDS_EMPTY_PICTURE_TAG = 2

QUIRK_NEEDS_SUPPORTED_PICTURE_TAG

Quirk to specify if the client fails to property ghost the POOMCONTACTS:Picture field. If this quirk is present, it means we should add the POOMCONTACTS:Picture field to the SUPPORTED array for this client.

public mixed QUIRK_NEEDS_SUPPORTED_PICTURE_TAG = 1

QUIRK_SUPPORTS_TNEF

These client can support TNEF data without decoding it first.

public mixed QUIRK_SUPPORTS_TNEF = 3
Tags
since
2.40.0

TYPE_ANDROID

public mixed TYPE_ANDROID = 'android'

TYPE_BLACKBERRY

public mixed TYPE_BLACKBERRY = 'blackberry'

TYPE_GMAIL

public mixed TYPE_GMAIL = 'gmail'

TYPE_IPAD

public mixed TYPE_IPAD = 'ipad'

TYPE_IPHONE

public mixed TYPE_IPHONE = 'iphone'

TYPE_IPOD

public mixed TYPE_IPOD = 'ipod'

TYPE_NINE

public mixed TYPE_NINE = 'nine'

TYPE_TOUCHDOWN

public mixed TYPE_TOUCHDOWN = 'touchdown'

TYPE_UNKNOWN

public mixed TYPE_UNKNOWN = 'unknown'

TYPE_WEBOS

public mixed TYPE_WEBOS = 'webos'

TYPE_WP

public mixed TYPE_WP = 'windowsphone'

VERSION

public mixed VERSION = 'version'

Properties

$announcedVersion

public string $announcedVersion

The most last EAS supported versions announced to the device.

$blocked

public bool $blocked

True if device has been marked as blocked.

$clientType

public string $clientType

The client name, if available.

$deviceType

public string $deviceType

The device type string.

$id

public string $id

The device id.

$multiplex

public int $multiplex

Bitmask describing collections that this device does not support user created folders for, therefore all sources must be multiplexed together. Masks are the MULTIPLEX_* constants.

$policykey

public string $policykey

The current policykey, if provisioned.

$properties

public array<string|int, mixed> $properties

The device properties, sent in DEVICEINFO, along with any custom properties set.

$rwstatus

public int $rwstatus

The RemoteWipe status - a Horde_ActiveSync::RWSTATUS_* constant.

$supported

public array<string|int, mixed> $supported

The SUPPORTED data sent from this device.

$user

public string $user

The userid for the current device account.

$userAgent

public string $userAgent

The device's user agent string.

$_clientType

Local override/cache of detected clientType.

protected string $_clientType

$_dirty

Dirty flag

protected array<string|int, mixed> $_dirty = array()

$_iOSVersion

Cache of OS version.

protected string $_iOSVersion

$_multiplexSet

Flag to indicate self::multiplex was set externally.

protected bool $_multiplexSet = \false

$_properties

Device properties.

protected array<string|int, mixed> $_properties = array()

Methods

__get()

Getter

public & __get(mixed $property) : mixed
Parameters
$property : mixed
Return values
mixed

__isset()

Magic isset

public __isset(mixed $property) : mixed
Parameters
$property : mixed
Return values
mixed

__set()

Setter

public __set(mixed $property, mixed $value) : mixed
Parameters
$property : mixed
$value : mixed
Return values
mixed

__toString()

public __toString() : mixed
Return values
mixed

enforceProvisioning()

Check if we should enforce provisioning on this device.

public enforceProvisioning() : bool
Return values
bool

getFormattedDeviceProperties()

Return an array of DEVICEINFO data, with keys suitable for displaying.

public getFormattedDeviceProperties() : array<string|int, mixed>
Return values
array<string|int, mixed>

getLastSyncTimestamp()

Return the last time the device issued a SYNC request.

public getLastSyncTimestamp() : int
Return values
int

The timestamp.

getMajorVersion()

Return the major version number of the OS (or client app) as reported by the client.

public getMajorVersion() : int
Return values
int

The version number.

getMinorVersion()

Return the minor version number of the OS (or client app) as reported by the client.

public getMinorVersion() : int
Return values
int

The version number.

hasQuirk()

Return if this client has the described quirk.

public hasQuirk(int $quirk) : bool
Parameters
$quirk : int

The specified quirk to check for.

Return values
bool

True if quirk is present.

isNonProvisionable()

Returns if the current device is an expected non-provisionable device.

public isNonProvisionable() : bool

I.e., the client does not support provisioning at all, but should still be allowed to connect to a server that has provisioning set to Force. Currently, this only applies to Windows Communication Apps (Outlook 2013).

Return values
bool

True if the device should be allowed to connect to a Forced provision server. False if not.

needsVersionUpdate()

Indicates if we need to announce new EAS version string to the client.

public needsVersionUpdate(string $supported) : bool

If the property is empty, we don't send it since we are sending the EAS-Version header anyway and this is a new device.

Parameters
$supported : string

The current EAS-Version header.

Return values
bool

True if we need to send the MS-RP header, otherwise false.

normalizePoomContactsDates()

Return the number of hours to offset a POOMCONTACTS:BIRTHDAY or ANNIVERSARY field in an attempt to work around a bug in the protocol - the protocol states that "the time portion SHOULD be ignored, so that synchronizing between different timezones does not change the date" (MS-ASCNTC 2.2.2.6). However, it appears that next to zero clients actually honor this.

public normalizePoomContactsDates(Horde_Date $date[, bool $toEas = false ]) : Horde_Date

WP: Devices seem to send the birthdays at the entered date, with a time of 00:00:00 UTC during standard time and with 01:00:00 UTC during DST if the client's configured timezone observes it. No idea what purpose this serves since no timezone data is transmitted for birthday values.

iOS: Seems different based on version. iOS 5+, at least seems to send the birthday as midnight at the entered date in the device's timezone then converted to UTC. Some minor issues with offsets being off an hour or two for some timezones though.

iOS < 5 sends the birthday time part as the time the birthday was entered/edited on the device, converted to UTC, so it can't be trusted at all. The best we can do here is transform the date to midnight on date_default_timezone() converted to UTC.

Android: Lollipop and newer got rid of the stock "Email" app in favor of GMail. Gmail seems to send birthdays up at 12:00:00 UTC, but doesn't expect them at that time. It seems that sending them down at 00:00:00 UTC works, but Unfortunately I don't know the version history here as to if they always did this, so will rely on bug reports if this is not correct :)

For legacy android:

For contacts originating on the SERVER, the following is true:

Stock 4.3 Takes the down-synched bday value which is assumed to be UTC, does some magic to it (converts to milliseconds, creates a gregorian calendar object, then converts to YYYY-MM-DD). When sending the bday value up, it sends it up as-is. No conversion to/from UTC or local is done.

Stock 4.4.x does the above, but before sending the bday value, validates that it's in a correct format for sending to the server. This really only affects date data originally entered on the device for non-stock android clients.

There is some strange bit of code in Android that adds 1 to the DAY_OF_MONTH when HOUR_OF_DAY >= 12 in an attempt to "fix" birthday handling for GMT+n users. See: https://android.googlesource.com/platform/packages/apps/Exchange/+/32daacdd71b9de8fd5e3f59c37934e3e4a9fa972%5E!/exchange2/src/com/android/exchange/adapter/ContactsSyncAdapter.java Not sure what to make of it, or why it's not just converted to local tz when displaying but this probably breaks birthday handling for people in a few timezones.

For contacts originating on the CLIENT, the datetime is sent as 08:00:00 UTC, and this seems to be regardless of the timezone set in the Android system.

Given all of this, it makes sense to me to ALWAYS send birthday data as occuring at 08:00:00 UTC for native Android clients.

BB 10+ expects it at 11:00:00 UTC

Parameters
$date : Horde_Date

The date. This should normally be in the local timezone if encoding the date for the client. If decoding the date from the client, it will normally be in UTC.

$toEas : bool = false

Convert from local to device if true. DEFAULT: false

Return values
Horde_Date

The date of the birthday/anniversary, with any fixes applied for the current device. The timezone set in the object will depend on the client detected, and whether the date is being encoding or decoding.

save()

Save the dirty device info data.

public save([bool $all = true ]) : mixed
Parameters
$all : bool = true

If true, save all properties (deviceInfo and deviceProperties). Otherwise, just save dirty deviceProperties. @since 2.16.0

Tags
todo

For 3.0, make it clearer that deviceInfo is per-user and deviceProperties is per-device.

Return values
mixed

setDeviceProperties()

Set the device's DEVICEINFO data.

public setDeviceProperties(array<string|int, mixed> $data) : mixed
Parameters
$data : array<string|int, mixed>

The data array sent from the device.

Return values
mixed

_getClientType()

Attempt to determine the *client* application as opposed to the device, which may or may not be the client.

protected _getClientType() : string
Return values
string

The client name.

_getIosVersion()

Detects the iOS version in M.m format and caches locally.

protected _getIosVersion() : mixed
Return values
mixed

_isIos()

Return if this client is an iOS device. Different versions require different checks.

protected _isIos() : bool
Return values
bool

[description]

_isNine()

Helper method to sniff out the 9Folders client, "Nine".

protected _isNine() : bool
Tags
see
https://ninefolders.plan.io/track/7048/46b213

for the discussion on how to sniff out the Nine client. Not the best solution, but it's the one they decided to use.

Return values
bool

True if client is thought to be "Nine".

_sniffMultiplex()

Basic sniffing for determining if devices can support non-multiplexed collections.

protected _sniffMultiplex() : mixed
Return values
mixed

Search results