@rustwirebot/rustplus.js 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +351 -0
  3. package/camera.js +425 -0
  4. package/cli/index.js +308 -0
  5. package/cli/pair.html +49 -0
  6. package/docs/API.md +101 -0
  7. package/docs/DownloadBundle.md +7 -0
  8. package/docs/PairingFlow.md +19 -0
  9. package/donate.md +10 -0
  10. package/examples/10_shoot_autoturret.js +100 -0
  11. package/examples/1_send_team_chat.js +16 -0
  12. package/examples/2_turn_smart_switch_on.js +21 -0
  13. package/examples/3_turn_smart_switch_off.js +21 -0
  14. package/examples/4_entity_changed_broadcasts.js +58 -0
  15. package/examples/5_download_map_jpeg.js +22 -0
  16. package/examples/6_async_requests.js +35 -0
  17. package/examples/7_render_camera.js +34 -0
  18. package/examples/8_move_ptz_camera.js +56 -0
  19. package/examples/9_zoom_ptz_camera.js +37 -0
  20. package/package.json +48 -0
  21. package/rustplus.js +380 -0
  22. package/rustplus.js.svg +34 -0
  23. package/rustplus.proto +431 -0
  24. package/vendor/push-receiver/LICENSE +21 -0
  25. package/vendor/push-receiver/NOTICE.md +32 -0
  26. package/vendor/push-receiver/android/fcm.js +134 -0
  27. package/vendor/push-receiver/client.js +216 -0
  28. package/vendor/push-receiver/constants.js +53 -0
  29. package/vendor/push-receiver/fcm/index.js +52 -0
  30. package/vendor/push-receiver/fcm/server-key/index.js +67 -0
  31. package/vendor/push-receiver/gcm/android_checkin.proto +96 -0
  32. package/vendor/push-receiver/gcm/checkin.proto +155 -0
  33. package/vendor/push-receiver/gcm/index.js +128 -0
  34. package/vendor/push-receiver/index.js +17 -0
  35. package/vendor/push-receiver/mcs.proto +328 -0
  36. package/vendor/push-receiver/parser.js +276 -0
  37. package/vendor/push-receiver/register/index.js +18 -0
  38. package/vendor/push-receiver/utils/base64/index.js +15 -0
  39. package/vendor/push-receiver/utils/decrypt/index.js +23 -0
  40. package/vendor/push-receiver/utils/http-request/index.js +43 -0
  41. package/vendor/push-receiver/utils/request/index.js +27 -0
  42. package/vendor/push-receiver/utils/timeout/index.js +7 -0
@@ -0,0 +1,216 @@
1
+ const EventEmitter = require('events');
2
+ const Long = require('long');
3
+ const Parser = require('./parser');
4
+ const decrypt = require('./utils/decrypt');
5
+ const path = require('path');
6
+ const tls = require('tls');
7
+ const { checkIn } = require('./gcm');
8
+ const {
9
+ kMCSVersion,
10
+ kLoginRequestTag,
11
+ kDataMessageStanzaTag,
12
+ kLoginResponseTag,
13
+ } = require('./constants');
14
+ const { load } = require('protobufjs');
15
+
16
+ const HOST = 'mtalk.google.com';
17
+ const PORT = 5228;
18
+ const MAX_RETRY_TIMEOUT = 15;
19
+
20
+ let proto = null;
21
+
22
+ module.exports = class Client extends EventEmitter {
23
+ static async init() {
24
+ if (proto) {
25
+ return;
26
+ }
27
+ proto = await load(path.resolve(__dirname, 'mcs.proto'));
28
+ }
29
+
30
+ constructor(androidId, securityToken, persistentIds) {
31
+ super();
32
+ this._androidId = androidId;
33
+ this._securityToken = securityToken;
34
+ this._persistentIds = persistentIds || [];
35
+ this._retryCount = 0;
36
+ this._onSocketConnect = this._onSocketConnect.bind(this);
37
+ this._onSocketClose = this._onSocketClose.bind(this);
38
+ this._onSocketError = this._onSocketError.bind(this);
39
+ this._onMessage = this._onMessage.bind(this);
40
+ this._onParserError = this._onParserError.bind(this);
41
+ }
42
+
43
+ async connect() {
44
+ await Client.init();
45
+ await this._checkIn();
46
+ this._connect();
47
+ // can happen if the socket immediately closes after being created
48
+ if (!this._socket) {
49
+ return;
50
+ }
51
+ await Parser.init();
52
+ // can happen if the socket immediately closes after being created
53
+ if (!this._socket) {
54
+ return;
55
+ }
56
+ this._parser = new Parser(this._socket);
57
+ this._parser.on('message', this._onMessage);
58
+ this._parser.on('error', this._onParserError);
59
+ }
60
+
61
+ destroy() {
62
+ this._destroy();
63
+ }
64
+
65
+ async _checkIn() {
66
+ return checkIn(
67
+ this._androidId,
68
+ this._securityToken,
69
+ );
70
+ }
71
+
72
+ _connect() {
73
+ this._socket = new tls.TLSSocket();
74
+ this._socket.setKeepAlive(true);
75
+ this._socket.on('connect', this._onSocketConnect);
76
+ this._socket.on('close', this._onSocketClose);
77
+ this._socket.on('error', this._onSocketError);
78
+ this._socket.connect({ host : HOST, port : PORT });
79
+ this._socket.write(this._loginBuffer());
80
+ }
81
+
82
+ _destroy() {
83
+ clearTimeout(this._retryTimeout);
84
+ if (this._socket) {
85
+ this._socket.removeListener('connect', this._onSocketConnect);
86
+ this._socket.removeListener('close', this._onSocketClose);
87
+ this._socket.removeListener('error', this._onSocketError);
88
+ this._socket.destroy();
89
+ this._socket = null;
90
+ }
91
+ if (this._parser) {
92
+ this._parser.removeListener('message', this._onMessage);
93
+ this._parser.removeListener('error', this._onParserError);
94
+ this._parser.destroy();
95
+ this._parser = null;
96
+ }
97
+ }
98
+
99
+ _loginBuffer() {
100
+ const LoginRequestType = proto.lookupType('mcs_proto.LoginRequest');
101
+ const hexAndroidId = Long.fromString(
102
+ this._androidId
103
+ ).toString(16);
104
+ const loginRequest = {
105
+ adaptiveHeartbeat : false,
106
+ authService : 2,
107
+ authToken : this._securityToken,
108
+ id : 'chrome-63.0.3234.0',
109
+ domain : 'mcs.android.com',
110
+ deviceId : `android-${hexAndroidId}`,
111
+ networkType : 1,
112
+ resource : this._androidId,
113
+ user : this._androidId,
114
+ useRmq2 : true,
115
+ setting : [{ name : 'new_vc', value : '1' }],
116
+ // Id of the last notification received
117
+ clientEvent : [],
118
+ receivedPersistentId : this._persistentIds,
119
+ };
120
+
121
+ const errorMessage = LoginRequestType.verify(loginRequest);
122
+ if (errorMessage) {
123
+ throw new Error(errorMessage);
124
+ }
125
+
126
+ const buffer = LoginRequestType.encodeDelimited(loginRequest).finish();
127
+
128
+ return Buffer.concat([
129
+ Buffer.from([kMCSVersion, kLoginRequestTag]),
130
+ buffer,
131
+ ]);
132
+ }
133
+
134
+ _onSocketConnect() {
135
+ this._retryCount = 0;
136
+ this.emit('connect');
137
+ }
138
+
139
+ _onSocketClose() {
140
+ this.emit('disconnect');
141
+ this._retry();
142
+ }
143
+
144
+ _onSocketError(error) {
145
+ // ignore, the close handler takes care of retry
146
+ }
147
+
148
+ _onParserError(error) {
149
+ this._retry();
150
+ }
151
+
152
+ _retry() {
153
+ this._destroy();
154
+ const timeout = Math.min(++this._retryCount, MAX_RETRY_TIMEOUT) * 1000;
155
+ this._retryTimeout = setTimeout(this.connect.bind(this), timeout);
156
+ }
157
+
158
+ _onMessage({ tag, object }) {
159
+ if (tag === kLoginResponseTag) {
160
+ // clear persistent ids, as we just sent them to the server while logging
161
+ // in
162
+ this._persistentIds = [];
163
+ } else if (tag === kDataMessageStanzaTag) {
164
+ this._onDataMessage(object);
165
+ }
166
+ }
167
+
168
+ _onDataMessage(object) {
169
+ if (this._persistentIds.includes(object.persistentId)) {
170
+ return;
171
+ }
172
+
173
+ // if crypto keys not provided, notification is probably not encrypted, so return message as is
174
+ if(!("crypto-key" in object.appData)){
175
+ this._persistentIds.push(object.persistentId);
176
+ this.emit('ON_DATA_RECEIVED', object);
177
+ return;
178
+ }
179
+
180
+ let message;
181
+ try {
182
+
183
+ // decrypt message
184
+ message = decrypt(object, keys);
185
+
186
+ } catch (error) {
187
+ switch (true) {
188
+ case error.message.includes(
189
+ 'Unsupported state or unable to authenticate data'
190
+ ):
191
+ case error.message.includes('crypto-key is missing'):
192
+ case error.message.includes('salt is missing'):
193
+ // NOTE(ibash) Periodically we're unable to decrypt notifications. In
194
+ // all cases we've been able to receive future notifications using the
195
+ // same keys. So, we silently drop this notification.
196
+ console.warn(
197
+ 'Message dropped as it could not be decrypted: ' + error.message
198
+ );
199
+ this._persistentIds.push(object.persistentId);
200
+ return;
201
+ default: {
202
+ throw error;
203
+ }
204
+ }
205
+ }
206
+
207
+ // Maintain persistentIds updated with the very last received value
208
+ this._persistentIds.push(object.persistentId);
209
+ // Send notification
210
+ this.emit('ON_NOTIFICATION_RECEIVED', {
211
+ notification : message,
212
+ persistentId : object.persistentId,
213
+ object : object,
214
+ });
215
+ }
216
+ };
@@ -0,0 +1,53 @@
1
+ module.exports = {
2
+ // enum ProcessingState
3
+ //
4
+ // Processing the version, tag, and size packets (assuming minimum length
5
+ // size packet). Only used during the login handshake.
6
+ MCS_VERSION_TAG_AND_SIZE : 0,
7
+ // Processing the tag and size packets (assuming minimum length size
8
+ // packet). Used for normal messages.
9
+ MCS_TAG_AND_SIZE : 1,
10
+ // Processing the size packet alone.
11
+ MCS_SIZE : 2,
12
+ // Processing the protocol buffer bytes (for those messages with non-zero
13
+ // sizes).
14
+ MCS_PROTO_BYTES : 3,
15
+
16
+ // # of bytes a MCS version packet consumes.
17
+ kVersionPacketLen : 1,
18
+ // # of bytes a tag packet consumes.
19
+ kTagPacketLen : 1,
20
+ // Max # of bytes a length packet consumes. A Varint32 can consume up to 5 bytes
21
+ // (the msb in each byte is reserved for denoting whether more bytes follow).
22
+ // Although the protocol only allows for 4KiB payloads currently, and the socket
23
+ // stream buffer is only of size 8KiB, it's possible for certain applications to
24
+ // have larger message sizes. When payload is larger than 4KiB, an temporary
25
+ // in-memory buffer is used instead of the normal in-place socket stream buffer.
26
+ kSizePacketLenMin : 1,
27
+ kSizePacketLenMax : 5,
28
+
29
+ // The current MCS protocol version.
30
+ kMCSVersion : 41,
31
+
32
+ // MCS Message tags.
33
+ // WARNING: the order of these tags must remain the same, as the tag values
34
+ // must be consistent with those used on the server.
35
+ // enum MCSProtoTag {
36
+ kHeartbeatPingTag : 0,
37
+ kHeartbeatAckTag : 1,
38
+ kLoginRequestTag : 2,
39
+ kLoginResponseTag : 3,
40
+ kCloseTag : 4,
41
+ kMessageStanzaTag : 5,
42
+ kPresenceStanzaTag : 6,
43
+ kIqStanzaTag : 7,
44
+ kDataMessageStanzaTag : 8,
45
+ kBatchPresenceStanzaTag : 9,
46
+ kStreamErrorStanzaTag : 10,
47
+ kHttpRequestTag : 11,
48
+ kHttpResponseTag : 12,
49
+ kBindAccountRequestTag : 13,
50
+ kBindAccountResponseTag : 14,
51
+ kTalkMetadataTag : 15,
52
+ kNumProtoTypes : 16,
53
+ };
@@ -0,0 +1,52 @@
1
+ const crypto = require('crypto');
2
+ const request = require('../utils/http-request');
3
+ const { escape } = require('../utils/base64');
4
+
5
+ const FCM_SUBSCRIBE = 'https://fcm.googleapis.com/fcm/connect/subscribe';
6
+ const FCM_ENDPOINT = 'https://fcm.googleapis.com/fcm/send';
7
+
8
+ module.exports = registerFCM;
9
+
10
+ async function registerFCM({ senderId, token }) {
11
+ const keys = await createKeys();
12
+ const response = await request({
13
+ url : FCM_SUBSCRIBE,
14
+ method : 'POST',
15
+ headers : {
16
+ 'Content-Type' : 'application/x-www-form-urlencoded',
17
+ },
18
+ form : {
19
+ authorized_entity : senderId,
20
+ endpoint : `${FCM_ENDPOINT}/${token}`,
21
+ encryption_key : keys.publicKey
22
+ .replace(/=/g, '')
23
+ .replace(/\+/g, '-')
24
+ .replace(/\//g, '_'),
25
+ encryption_auth : keys.authSecret
26
+ .replace(/=/g, '')
27
+ .replace(/\+/g, '-')
28
+ .replace(/\//g, '_'),
29
+ },
30
+ });
31
+ return {
32
+ keys,
33
+ fcm : JSON.parse(response),
34
+ };
35
+ }
36
+
37
+ function createKeys() {
38
+ return new Promise((resolve, reject) => {
39
+ const dh = crypto.createECDH('prime256v1');
40
+ dh.generateKeys();
41
+ crypto.randomBytes(16, (err, buf) => {
42
+ if (err) {
43
+ return reject(err);
44
+ }
45
+ return resolve({
46
+ privateKey : escape(dh.getPrivateKey('base64')),
47
+ publicKey : escape(dh.getPublicKey('base64')),
48
+ authSecret : escape(buf.toString('base64')),
49
+ });
50
+ });
51
+ });
52
+ }
@@ -0,0 +1,67 @@
1
+ module.exports = [
2
+ 0x04,
3
+ 0x33,
4
+ 0x94,
5
+ 0xf7,
6
+ 0xdf,
7
+ 0xa1,
8
+ 0xeb,
9
+ 0xb1,
10
+ 0xdc,
11
+ 0x03,
12
+ 0xa2,
13
+ 0x5e,
14
+ 0x15,
15
+ 0x71,
16
+ 0xdb,
17
+ 0x48,
18
+ 0xd3,
19
+ 0x2e,
20
+ 0xed,
21
+ 0xed,
22
+ 0xb2,
23
+ 0x34,
24
+ 0xdb,
25
+ 0xb7,
26
+ 0x47,
27
+ 0x3a,
28
+ 0x0c,
29
+ 0x8f,
30
+ 0xc4,
31
+ 0xcc,
32
+ 0xe1,
33
+ 0x6f,
34
+ 0x3c,
35
+ 0x8c,
36
+ 0x84,
37
+ 0xdf,
38
+ 0xab,
39
+ 0xb6,
40
+ 0x66,
41
+ 0x3e,
42
+ 0xf2,
43
+ 0x0c,
44
+ 0xd4,
45
+ 0x8b,
46
+ 0xfe,
47
+ 0xe3,
48
+ 0xf9,
49
+ 0x76,
50
+ 0x2f,
51
+ 0x14,
52
+ 0x1c,
53
+ 0x63,
54
+ 0x08,
55
+ 0x6a,
56
+ 0x6f,
57
+ 0x2d,
58
+ 0xb1,
59
+ 0x1a,
60
+ 0x95,
61
+ 0xb0,
62
+ 0xce,
63
+ 0x37,
64
+ 0xc0,
65
+ 0x9c,
66
+ 0x6e,
67
+ ];
@@ -0,0 +1,96 @@
1
+ // Copyright 2014 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ //
5
+ // Logging information for Android "checkin" events (automatic, periodic
6
+ // requests made by Android devices to the server).
7
+
8
+ syntax = "proto2";
9
+
10
+ option optimize_for = LITE_RUNTIME;
11
+ package checkin_proto;
12
+
13
+ // Build characteristics unique to the Chrome browser, and Chrome OS
14
+ message ChromeBuildProto {
15
+ enum Platform {
16
+ PLATFORM_WIN = 1;
17
+ PLATFORM_MAC = 2;
18
+ PLATFORM_LINUX = 3;
19
+ PLATFORM_CROS = 4;
20
+ PLATFORM_IOS = 5;
21
+ // Just a placeholder. Likely don't need it due to the presence of the
22
+ // Android GCM on phone/tablet devices.
23
+ PLATFORM_ANDROID = 6;
24
+ }
25
+
26
+ enum Channel {
27
+ CHANNEL_STABLE = 1;
28
+ CHANNEL_BETA = 2;
29
+ CHANNEL_DEV = 3;
30
+ CHANNEL_CANARY = 4;
31
+ CHANNEL_UNKNOWN = 5; // for tip of tree or custom builds
32
+ }
33
+
34
+ // The platform of the device.
35
+ optional Platform platform = 1;
36
+
37
+ // The Chrome instance's version.
38
+ optional string chrome_version = 2;
39
+
40
+ // The Channel (build type) of Chrome.
41
+ optional Channel channel = 3;
42
+ }
43
+
44
+ // Information sent by the device in a "checkin" request.
45
+ message AndroidCheckinProto {
46
+ // Miliseconds since the Unix epoch of the device's last successful checkin.
47
+ optional int64 last_checkin_msec = 2;
48
+
49
+ // The current MCC+MNC of the mobile device's current cell.
50
+ optional string cell_operator = 6;
51
+
52
+ // The MCC+MNC of the SIM card (different from operator if the
53
+ // device is roaming, for instance).
54
+ optional string sim_operator = 7;
55
+
56
+ // The device's current roaming state (reported starting in eclair builds).
57
+ // Currently one of "{,not}mobile-{,not}roaming", if it is present at all.
58
+ optional string roaming = 8;
59
+
60
+ // For devices supporting multiple user profiles (which may be
61
+ // supported starting in jellybean), the ordinal number of the
62
+ // profile that is checking in. This is 0 for the primary profile
63
+ // (which can't be changed without wiping the device), and 1,2,3,...
64
+ // for additional profiles (which can be added and deleted freely).
65
+ optional int32 user_number = 9;
66
+
67
+ // Class of device. Indicates the type of build proto
68
+ // (IosBuildProto/ChromeBuildProto/AndroidBuildProto)
69
+ // That is included in this proto
70
+ optional DeviceType type = 12 [default = DEVICE_ANDROID_OS];
71
+
72
+ // For devices running MCS on Chrome, build-specific characteristics
73
+ // of the browser. There are no hardware aspects (except for ChromeOS).
74
+ // This will only be populated for Chrome builds/ChromeOS devices
75
+ optional checkin_proto.ChromeBuildProto chrome_build = 13;
76
+
77
+ // Note: Some of the Android specific optional fields were skipped to limit
78
+ // the protobuf definition.
79
+ // Next 14
80
+ }
81
+
82
+ // enum values correspond to the type of device.
83
+ // Used in the AndroidCheckinProto and Device proto.
84
+ enum DeviceType {
85
+ // Android Device
86
+ DEVICE_ANDROID_OS = 1;
87
+
88
+ // Apple IOS device
89
+ DEVICE_IOS_OS = 2;
90
+
91
+ // Chrome browser - Not Chrome OS. No hardware records.
92
+ DEVICE_CHROME_BROWSER = 3;
93
+
94
+ // Chrome OS
95
+ DEVICE_CHROME_OS = 4;
96
+ }
@@ -0,0 +1,155 @@
1
+ // Copyright 2014 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ //
5
+ // Request and reply to the "checkin server" devices poll every few hours.
6
+
7
+ syntax = "proto2";
8
+
9
+ option optimize_for = LITE_RUNTIME;
10
+
11
+ package checkin_proto;
12
+
13
+ import "android_checkin.proto";
14
+
15
+ // A concrete name/value pair sent to the device's Gservices database.
16
+ message GservicesSetting {
17
+ required bytes name = 1;
18
+ required bytes value = 2;
19
+ }
20
+
21
+ // Devices send this every few hours to tell us how they're doing.
22
+ message AndroidCheckinRequest {
23
+ // IMEI (used by GSM phones) is sent and stored as 15 decimal
24
+ // digits; the 15th is a check digit.
25
+ optional string imei = 1; // IMEI, reported but not logged.
26
+
27
+ // MEID (used by CDMA phones) is sent and stored as 14 hexadecimal
28
+ // digits (no check digit).
29
+ optional string meid = 10; // MEID, reported but not logged.
30
+
31
+ // MAC address (used by non-phone devices). 12 hexadecimal digits;
32
+ // no separators (eg "0016E6513AC2", not "00:16:E6:51:3A:C2").
33
+ repeated string mac_addr = 9; // MAC address, reported but not logged.
34
+
35
+ // An array parallel to mac_addr, describing the type of interface.
36
+ // Currently accepted values: "wifi", "ethernet", "bluetooth". If
37
+ // not present, "wifi" is assumed.
38
+ repeated string mac_addr_type = 19;
39
+
40
+ // Serial number (a manufacturer-defined unique hardware
41
+ // identifier). Alphanumeric, case-insensitive.
42
+ optional string serial_number = 16;
43
+
44
+ // Older CDMA networks use an ESN (8 hex digits) instead of an MEID.
45
+ optional string esn = 17; // ESN, reported but not logged
46
+
47
+ optional int64 id = 2; // Android device ID, not logged
48
+ optional int64 logging_id = 7; // Pseudonymous logging ID for Sawmill
49
+ optional string digest = 3; // Digest of device provisioning, not logged.
50
+ optional string locale = 6; // Current locale in standard (xx_XX) format
51
+ required AndroidCheckinProto checkin = 4;
52
+
53
+ // DEPRECATED, see AndroidCheckinProto.requested_group
54
+ optional string desired_build = 5;
55
+
56
+ // Blob of data from the Market app to be passed to Market API server
57
+ optional string market_checkin = 8;
58
+
59
+ // SID cookies of any google accounts stored on the phone. Not logged.
60
+ repeated string account_cookie = 11;
61
+
62
+ // Time zone. Not currently logged.
63
+ optional string time_zone = 12;
64
+
65
+ // Security token used to validate the checkin request.
66
+ // Required for android IDs issued to Froyo+ devices, not for legacy IDs.
67
+ optional fixed64 security_token = 13;
68
+
69
+ // Version of checkin protocol.
70
+ //
71
+ // There are currently two versions:
72
+ //
73
+ // - version field missing: android IDs are assigned based on
74
+ // hardware identifiers. unsecured in the sense that you can
75
+ // "unregister" someone's phone by sending a registration request
76
+ // with their IMEI/MEID/MAC.
77
+ //
78
+ // - version=2: android IDs are assigned randomly. The device is
79
+ // sent a security token that must be included in all future
80
+ // checkins for that android id.
81
+ //
82
+ // - version=3: same as version 2, but the 'fragment' field is
83
+ // provided, and the device understands incremental updates to the
84
+ // gservices table (ie, only returning the keys whose values have
85
+ // changed.)
86
+ //
87
+ // (version=1 was skipped to avoid confusion with the "missing"
88
+ // version field that is effectively version 1.)
89
+ optional int32 version = 14;
90
+
91
+ // OTA certs accepted by device (base-64 SHA-1 of cert files). Not
92
+ // logged.
93
+ repeated string ota_cert = 15;
94
+
95
+ // Honeycomb and newer devices send configuration data with their checkin.
96
+ // optional DeviceConfigurationProto device_configuration = 18;
97
+
98
+ // A single CheckinTask on the device may lead to multiple checkin
99
+ // requests if there is too much log data to upload in a single
100
+ // request. For version 3 and up, this field will be filled in with
101
+ // the number of the request, starting with 0.
102
+ optional int32 fragment = 20;
103
+
104
+ // For devices supporting multiple users, the name of the current
105
+ // profile (they all check in independently, just as if they were
106
+ // multiple physical devices). This may not be set, even if the
107
+ // device is using multiuser. (checkin.user_number should be set to
108
+ // the ordinal of the user.)
109
+ optional string user_name = 21;
110
+
111
+ // For devices supporting multiple user profiles, the serial number
112
+ // for the user checking in. Not logged. May not be set, even if
113
+ // the device supportes multiuser. checkin.user_number is the
114
+ // ordinal of the user (0, 1, 2, ...), which may be reused if users
115
+ // are deleted and re-created. user_serial_number is never reused
116
+ // (unless the device is wiped).
117
+ optional int32 user_serial_number = 22;
118
+
119
+ // NEXT TAG: 23
120
+ }
121
+
122
+ // The response to the device.
123
+ message AndroidCheckinResponse {
124
+ required bool stats_ok = 1; // Whether statistics were recorded properly.
125
+ optional int64 time_msec = 3; // Time of day from server (Java epoch).
126
+ // repeated AndroidIntentProto intent = 2;
127
+
128
+ // Provisioning is sent if the request included an obsolete digest.
129
+ //
130
+ // For version <= 2, 'digest' contains the digest that should be
131
+ // sent back to the server on the next checkin, and 'setting'
132
+ // contains the entire gservices table (which replaces the entire
133
+ // current table on the device).
134
+ //
135
+ // for version >= 3, 'digest' will be absent. If 'settings_diff'
136
+ // is false, then 'setting' contains the entire table, as in version
137
+ // 2. If 'settings_diff' is true, then 'delete_setting' contains
138
+ // the keys to delete, and 'setting' contains only keys to be added
139
+ // or for which the value has changed. All other keys in the
140
+ // current table should be left untouched. If 'settings_diff' is
141
+ // absent, don't touch the existing gservices table.
142
+ //
143
+ optional string digest = 4;
144
+ optional bool settings_diff = 9;
145
+ repeated string delete_setting = 10;
146
+ repeated GservicesSetting setting = 5;
147
+
148
+ optional bool market_ok = 6; // If Market got the market_checkin data OK.
149
+
150
+ optional fixed64 android_id = 7; // From the request, or newly assigned
151
+ optional fixed64 security_token = 8; // The associated security token
152
+
153
+ optional string version_info = 11;
154
+ // NEXT TAG: 12
155
+ }