Skip to content

Commit 9e2f37a

Browse files
authored
Merge pull request #3 from GeoTecINIT/fix-recog-setup
Recognizer setup method was not taking into account original start options
2 parents 6e00740 + fce13f3 commit 9e2f37a

File tree

9 files changed

+120
-36
lines changed

9 files changed

+120
-36
lines changed

demo/app/tests/internal/activity-recognition/recognizers/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
Resolution,
77
HumanActivity,
88
} from "nativescript-context-apis/internal/activity-recognition";
9+
import { StartOptions } from "nativescript-context-apis/internal/activity-recognition/recognizers";
910
import { RecognizerManager } from "nativescript-context-apis/internal/activity-recognition/recognizers/recognizer-manager";
1011

1112
export function createCallbackManagerMock(): RecognizerCallbackManager {
@@ -30,7 +31,13 @@ export function createRecognizersStateStoreMock(): RecognizerStateStore {
3031
isActive(recognizer: Resolution): Promise<boolean> {
3132
return Promise.resolve(false);
3233
},
33-
markAsActive(recognizer: Resolution): Promise<void> {
34+
getStartOptions(recognizer: Resolution): Promise<StartOptions> {
35+
return Promise.resolve(null);
36+
},
37+
markAsActive(
38+
recognizer: Resolution,
39+
startOptions: StartOptions
40+
): Promise<void> {
3441
return Promise.resolve();
3542
},
3643
markAsInactive(recognizer: Resolution): Promise<void> {

demo/app/tests/internal/activity-recognition/recognizers/low-res/android/recognizer.android.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { RecognizerManager } from "nativescript-context-apis/internal/activity-r
33
import { RecognizerCallbackManager } from "nativescript-context-apis/internal/activity-recognition/recognizers/callback-manager";
44
import { AndroidLowResRecognizer } from "nativescript-context-apis/internal/activity-recognition/recognizers/low-res/android/recognizer.android";
55
import { Resolution } from "nativescript-context-apis/internal/activity-recognition";
6+
import { StartOptions } from "nativescript-context-apis/internal/activity-recognition/recognizers";
67
import {
78
createRecognizersStateStoreMock,
89
createCallbackManagerMock,
@@ -16,6 +17,7 @@ import {
1617

1718
describe("Android low resolution activity recognizer", () => {
1819
const recognizerType = Resolution.LOW;
20+
const startOptions: StartOptions = {};
1921

2022
let recognizerState: RecognizerStateStore;
2123
let callbackManager: RecognizerCallbackManager;
@@ -32,7 +34,7 @@ describe("Android low resolution activity recognizer", () => {
3234
recognizerManager
3335
);
3436
spyOn(recognizerState, "markAsActive")
35-
.withArgs(recognizerType)
37+
.withArgs(recognizerType, startOptions)
3638
.and.returnValue(Promise.resolve());
3739
spyOn(recognizerState, "markAsInactive")
3840
.withArgs(recognizerType)
@@ -63,8 +65,13 @@ describe("Android low resolution activity recognizer", () => {
6365
spyOn(recognizerState, "isActive")
6466
.withArgs(recognizerType)
6567
.and.returnValue(Promise.resolve(true));
68+
spyOn(recognizerState, "getStartOptions").and.returnValue(
69+
Promise.resolve(startOptions)
70+
);
6671
await recognizer.setup();
67-
expect(recognizerManager.startListening).toHaveBeenCalled();
72+
expect(recognizerManager.startListening).toHaveBeenCalledWith(
73+
startOptions
74+
);
6875
});
6976

7077
it("does not (re)start listening when inactive", async () => {
@@ -78,10 +85,11 @@ describe("Android low resolution activity recognizer", () => {
7885

7986
it("allows to start the recognition by activating the underlying subsystem", async () => {
8087
spyOn(recognizerManager, "startListening");
81-
await recognizer.startRecognizing();
88+
await recognizer.startRecognizing(startOptions);
8289
expect(recognizerManager.startListening).toHaveBeenCalled();
8390
expect(recognizerState.markAsActive).toHaveBeenCalledWith(
84-
recognizerType
91+
recognizerType,
92+
startOptions
8593
);
8694
});
8795

@@ -91,9 +99,7 @@ describe("Android low resolution activity recognizer", () => {
9199
await expectAsync(recognizer.startRecognizing()).toBeRejectedWith(
92100
listenError
93101
);
94-
expect(recognizerState.markAsActive).not.toHaveBeenCalledWith(
95-
recognizerType
96-
);
102+
expect(recognizerState.markAsActive).not.toHaveBeenCalled();
97103
});
98104

99105
it("allows to stop the recognition by deactivating the underlying subsystem", async () => {

demo/app/tests/internal/activity-recognition/recognizers/medium-res/android/recognizer.android.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { RecognizerManager } from "nativescript-context-apis/internal/activity-r
33
import { RecognizerCallbackManager } from "nativescript-context-apis/internal/activity-recognition/recognizers/callback-manager";
44
import { AndroidMediumResRecognizer } from "nativescript-context-apis/internal/activity-recognition/recognizers/medium-res/android/recognizer.android";
55
import { Resolution } from "nativescript-context-apis/internal/activity-recognition";
6+
import { StartOptions } from "nativescript-context-apis/internal/activity-recognition/recognizers";
67
import {
78
createRecognizersStateStoreMock,
89
createCallbackManagerMock,
@@ -16,6 +17,7 @@ import {
1617

1718
describe("Android medium resolution activity recognizer", () => {
1819
const recognizerType = Resolution.MEDIUM;
20+
const startOptions: StartOptions = { detectionInterval: 60000 };
1921

2022
let recognizerState: RecognizerStateStore;
2123
let callbackManager: RecognizerCallbackManager;
@@ -32,7 +34,7 @@ describe("Android medium resolution activity recognizer", () => {
3234
recognizerManager
3335
);
3436
spyOn(recognizerState, "markAsActive")
35-
.withArgs(recognizerType)
37+
.withArgs(recognizerType, startOptions)
3638
.and.returnValue(Promise.resolve());
3739
spyOn(recognizerState, "markAsInactive")
3840
.withArgs(recognizerType)
@@ -63,8 +65,13 @@ describe("Android medium resolution activity recognizer", () => {
6365
spyOn(recognizerState, "isActive")
6466
.withArgs(recognizerType)
6567
.and.returnValue(Promise.resolve(true));
68+
spyOn(recognizerState, "getStartOptions").and.returnValue(
69+
Promise.resolve(startOptions)
70+
);
6671
await recognizer.setup();
67-
expect(recognizerManager.startListening).toHaveBeenCalled();
72+
expect(recognizerManager.startListening).toHaveBeenCalledWith(
73+
startOptions
74+
);
6875
});
6976

7077
it("does not (re)start listening when inactive", async () => {
@@ -78,22 +85,21 @@ describe("Android medium resolution activity recognizer", () => {
7885

7986
it("allows to start the recognition by activating the underlying subsystem", async () => {
8087
spyOn(recognizerManager, "startListening");
81-
await recognizer.startRecognizing();
88+
await recognizer.startRecognizing(startOptions);
8289
expect(recognizerManager.startListening).toHaveBeenCalled();
8390
expect(recognizerState.markAsActive).toHaveBeenCalledWith(
84-
recognizerType
91+
recognizerType,
92+
startOptions
8593
);
8694
});
8795

8896
it("does not mark the recognizer as active if the activation fails", async () => {
8997
const listenError = new Error("Could not start listening");
9098
spyOn(recognizerManager, "startListening").and.rejectWith(listenError);
91-
await expectAsync(recognizer.startRecognizing()).toBeRejectedWith(
92-
listenError
93-
);
94-
expect(recognizerState.markAsActive).not.toHaveBeenCalledWith(
95-
recognizerType
96-
);
99+
await expectAsync(
100+
recognizer.startRecognizing(startOptions)
101+
).toBeRejectedWith(listenError);
102+
expect(recognizerState.markAsActive).not.toHaveBeenCalled();
97103
});
98104

99105
it("allows to stop the recognition by deactivating the underlying subsystem", async () => {

demo/app/tests/internal/activity-recognition/recognizers/state-store.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Resolution,
44
HumanActivity,
55
} from "nativescript-context-apis/internal/activity-recognition";
6+
import { StartOptions } from "nativescript-context-apis/internal/activity-recognition/recognizers";
67

78
describe("Recognizers state store", () => {
89
const recognizer = Resolution.HIGH;
@@ -12,8 +13,28 @@ describe("Recognizers state store", () => {
1213
expect(isActive == true || isActive == false).toBeTrue();
1314
});
1415

16+
it("returns the start options of a recognizer marked as active", async () => {
17+
const expectedStartOptions: StartOptions = { detectionInterval: 60000 };
18+
await recognizersStateStoreDb.markAsActive(
19+
recognizer,
20+
expectedStartOptions
21+
);
22+
const startOptions = await recognizersStateStoreDb.getStartOptions(
23+
recognizer
24+
);
25+
expect(startOptions).toEqual(expectedStartOptions);
26+
});
27+
28+
it("returns no start options when the recognizer is marked as inactive", async () => {
29+
await recognizersStateStoreDb.markAsInactive(recognizer);
30+
const startOptions = await recognizersStateStoreDb.getStartOptions(
31+
recognizer
32+
);
33+
expect(startOptions).toBeNull();
34+
});
35+
1536
it("marks a recognizer as active", async () => {
16-
await recognizersStateStoreDb.markAsActive(recognizer);
37+
await recognizersStateStoreDb.markAsActive(recognizer, {});
1738
const isActive = await recognizersStateStoreDb.isActive(recognizer);
1839
expect(isActive).toBeTrue();
1940
});
@@ -33,7 +54,7 @@ describe("Recognizers state store", () => {
3354
});
3455

3556
it("successfully updates the last activity of an active recognizer", async () => {
36-
await recognizersStateStoreDb.markAsActive(recognizer);
57+
await recognizersStateStoreDb.markAsActive(recognizer, {});
3758
const activity = HumanActivity.RUNNING;
3859
await recognizersStateStoreDb.updateLastActivity(recognizer, activity);
3960
const lastActivity = await recognizersStateStoreDb.getLastActivity(

src/geolocation/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export {
22
getGeolocationProvider,
33
GeolocationProvider,
44
Geolocation,
5+
GeolocationLike,
56
AcquireOptions,
67
StreamOptions,
78
} from "../internal/geolocation";

src/internal/activity-recognition/recognizers/abstract-recognizer.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@ export abstract class AbstractActivityRecognizer implements ActivityRecognizer {
2424
async setup(): Promise<void> {
2525
const active = await this.recognizerState.isActive(this.recognizerType);
2626
if (active) {
27-
await this.recognitionManager.startListening();
27+
const startOptions = await this.recognizerState.getStartOptions(
28+
this.recognizerType
29+
);
30+
await this.recognitionManager.startListening(startOptions);
2831
}
2932
}
3033

3134
async startRecognizing(options: StartOptions = {}): Promise<void> {
3235
await this.recognitionManager.startListening(options);
33-
await this.recognizerState.markAsActive(this.recognizerType);
36+
await this.recognizerState.markAsActive(this.recognizerType, options);
3437
}
3538

3639
async stopRecognizing(): Promise<void> {

src/internal/activity-recognition/recognizers/state/model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const recognizersStateModel: InanoSQLTableConfig = {
55
model: {
66
"id:string": { pk: true },
77
"active:boolean": {},
8+
"startOptions:string": {},
89
"lastActivity:string": {},
910
},
1011
};

src/internal/activity-recognition/recognizers/state/store.ts

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { HumanActivity, Resolution } from "../../index";
1+
import { HumanActivity, Resolution, StartOptions } from "../../index";
22
import { pluginDb } from "../../../persistence/plugin-db";
33
import { recognizersStateModel } from "./model";
44

55
export interface RecognizerStateStore {
66
isActive(recognizer: Resolution): Promise<boolean>;
7-
markAsActive(recognizer: Resolution): Promise<void>;
7+
getStartOptions(recognizer: Resolution): Promise<StartOptions>;
8+
markAsActive(
9+
recognizer: Resolution,
10+
startOptions: StartOptions
11+
): Promise<void>;
812
markAsInactive(recognizer: Resolution): Promise<void>;
913
getLastActivity(recognizer: Resolution): Promise<HumanActivity>;
1014
updateLastActivity(
@@ -17,19 +21,31 @@ class RecognizersStateStoreDb implements RecognizerStateStore {
1721
private tableName = recognizersStateModel.name;
1822

1923
async isActive(recognizer: Resolution): Promise<boolean> {
20-
const instance = await this.db();
21-
const rows = await instance
22-
.query("select")
23-
.where(["id", "=", recognizer])
24-
.exec();
25-
if (rows.length === 0) {
24+
const recognizerData = await this.getRecognizerData(recognizer);
25+
if (!recognizerData) {
2626
return false;
2727
}
28-
return rows[0].active;
28+
return recognizerData.active;
29+
}
30+
31+
async getStartOptions(recognizer: Resolution): Promise<StartOptions> {
32+
const isActive = await this.isActive(recognizer);
33+
if (!isActive) {
34+
return null;
35+
}
36+
37+
const recognizerData = await this.getRecognizerData(recognizer);
38+
if (!recognizerData) {
39+
return null;
40+
}
41+
return JSON.parse(recognizerData.startOptions);
2942
}
3043

31-
async markAsActive(recognizer: Resolution): Promise<void> {
32-
await this.updateStatus(recognizer, true);
44+
async markAsActive(
45+
recognizer: Resolution,
46+
startOptions: StartOptions
47+
): Promise<void> {
48+
await this.updateStatus(recognizer, true, startOptions);
3349
}
3450

3551
async markAsInactive(recognizer: Resolution): Promise<void> {
@@ -64,13 +80,36 @@ class RecognizersStateStoreDb implements RecognizerStateStore {
6480
.exec();
6581
}
6682

67-
private async updateStatus(recognizer: Resolution, active: boolean) {
83+
private async updateStatus(
84+
recognizer: Resolution,
85+
active: boolean,
86+
startOptions: StartOptions = {}
87+
) {
6888
const instance = await this.db();
6989
await instance
70-
.query("upsert", { id: recognizer, active, lastActivity: null })
90+
.query("upsert", {
91+
id: recognizer,
92+
active,
93+
startOptions: JSON.stringify(startOptions),
94+
lastActivity: null,
95+
})
7196
.exec();
7297
}
7398

99+
private async getRecognizerData(
100+
recognizer: Resolution
101+
): Promise<{ [key: string]: any }> {
102+
const instance = await this.db();
103+
const rows = await instance
104+
.query("select")
105+
.where(["id", "=", recognizer])
106+
.exec();
107+
if (rows.length === 0) {
108+
return null;
109+
}
110+
return rows[0];
111+
}
112+
74113
private db(tableName = this.tableName) {
75114
return pluginDb.instance(tableName);
76115
}

src/internal/geolocation/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export interface StreamOptions extends AcquireOptions {
5555
saveBattery?: boolean;
5656
}
5757

58-
export { Geolocation } from "./geolocation";
58+
export { Geolocation, GeolocationLike } from "./geolocation";
5959

6060
function geolocationOptionsToPluginOptions(
6161
options: AcquireOptions | StreamOptions

0 commit comments

Comments
 (0)