-
Notifications
You must be signed in to change notification settings - Fork 62
GPII-228 Capture Settings Backend (Snapshotter 2018) #616
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 51 commits
f846454
000b33c
e36f564
179e705
eb78e33
04f4e0a
b45079c
fa8a2fb
526d545
25ac4d4
4516c89
1764ef9
2ef4b41
1c05b52
3c55217
29a2708
f30a253
cd8127b
eba8606
179c7e1
b94f137
c727f64
4aba301
db831bb
f484faf
b79d476
b26a588
38bea00
8dec2c5
eb54bb8
d594966
0131b23
f562fe8
17ce607
ec7cb2f
f32a13d
e15f44d
1b636f7
edd5160
6b0416d
511e08b
adcf338
0fd86ac
49e4a38
dd53284
3e70229
2017627
98e56d4
2b3f8e9
caa6508
4b167f8
146119b
2eb479f
e710078
382c51f
41b100d
53ae908
b71918f
97b5f82
5c985d0
3834082
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,286 @@ | ||
| /** | ||
| * GPII snapshot Handler | ||
| * | ||
| * Copyright 2014 Raising the Floor - International | ||
| * | ||
| * Licensed under the New BSD license. You may not use this file except in | ||
| * compliance with this License. | ||
| * | ||
| * You may obtain a copy of the License at | ||
| * https://github.com/gpii/universal/LICENSE.txt | ||
| */ | ||
| "use strict"; | ||
|
|
||
| var fluid = require("infusion"), | ||
| gpii = fluid.registerNamespace("gpii"); | ||
|
|
||
| fluid.defaults("gpii.flowManager.capture", { | ||
| gradeNames: ["fluid.component"], | ||
| events: { | ||
| onSolutionsForCurrentDevice: null, | ||
sgithens marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| onCaptureSettingsForCurrentDevice: null | ||
| }, | ||
| listeners: { | ||
| onSolutionsForCurrentDevice: [ | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| funcName: "gpii.lifecycleManager.getDeviceContextPromise", | ||
| args: ["{flowManager}.deviceReporter"] | ||
| }, | ||
| { | ||
| funcName: "gpii.flowManager.getSolutionsPromise", | ||
| args: [ "{flowManager}.solutionsRegistryDataSource", "{arguments}.0"] | ||
| }, | ||
| { | ||
| funcName: "fluid.toPromise", | ||
| args: ["{arguments}.0.solutionsRegistryEntries"] | ||
| } | ||
| ], | ||
| onCaptureSettingsForCurrentDevice: [ | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| func: "{that}.getInstalledSolutions" | ||
| }, | ||
| { | ||
| func: "{that}.captureSystemSettings", | ||
| args: ["{arguments}.0", "{arguments}.1"] | ||
| }, | ||
| { | ||
| func: "gpii.flowManager.formatRawCapturedSettings", | ||
| args: ["{arguments}.0"] | ||
| } | ||
| ] | ||
| }, | ||
| invokers: { | ||
| getInstalledSolutions: { | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| funcName: "gpii.flowManager.getInstalledSolutions", | ||
| args: ["{that}"] | ||
| }, | ||
| getSystemSettingsCapture: { | ||
| funcName: "gpii.flowManager.getSystemSettingsCapture", | ||
| args: ["{that}.events.onCaptureSettingsForCurrentDevice", "{arguments}.0"] // Options | ||
| }, | ||
| captureSystemSettings: { | ||
| funcName: "gpii.flowManager.captureSystemSettings", | ||
| args: ["{lifecycleManager}.invokeSettingsHandlerGet", "{lifecycleManager}.variableResolver", | ||
| "{arguments}.0", "{arguments}.1"] | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| }); | ||
|
|
||
| gpii.flowManager.getInstalledSolutions = function (that) { | ||
| return fluid.promise.fireTransformEvent(that.events.onSolutionsForCurrentDevice); | ||
| }; | ||
|
|
||
| /** | ||
| * This main API entry point for capturing settings from a system or computer. This captures | ||
| * the actual settings on the device, so it assumed to be running in a local untrusted flow | ||
| * manager. | ||
| * | ||
| * @param {Event} onCaptureSettingsForCurrentDevice - The transforming promise chain | ||
| * @param {Object} options - Options for this chain. | ||
| * @param {Array} options.solutionsList - An array of solution IDs to filter by when | ||
| * retreiving settings. If this option is not included, all available settings will be | ||
| * returned. ex: `["com.microsoft.windows.mouseSettings", "com.freedomscientific.jaws"]`. | ||
| * @return {Promise} A promise resolved with the payload of captured system settings. | ||
| */ | ||
| gpii.flowManager.getSystemSettingsCapture = function (onCaptureSettingsForCurrentDevice, options) { | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return fluid.promise.fireTransformEvent(onCaptureSettingsForCurrentDevice, | ||
| {}, options); | ||
| }; | ||
|
|
||
| /** | ||
| * This function invokers a settings handler to fetch settings, but wraps the processing and reports | ||
| * back any failures in an `isError: true` json block. | ||
| * | ||
| * @param {Function} invokeSettingsHandlerGet - The get function from the appropriate settings handler. | ||
| * @param {String} solutionID - The dotted solution id, ex `com.freedomscientific.jaws` | ||
| * @param {Object} handlerSpec - TODO, exactly how much of the solutions entry block is this? | ||
| * @return {Object} The returned settings, or an error block with debugging information. | ||
| */ | ||
| gpii.flowManager.capture.safeHandlerGet = function (invokeSettingsHandlerGet, solutionID, handlerSpec) { | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| var promiseTogo = fluid.promise(); | ||
| try { | ||
| invokeSettingsHandlerGet(solutionID, handlerSpec).then(function (data) { | ||
| promiseTogo.resolve(data); | ||
| }, function (err) { | ||
| promiseTogo.resolve({ | ||
| solutionId: solutionID, | ||
| handlerSpec: handlerSpec, | ||
| isError: true, | ||
| message: "Settings Handler Promise Rejection", | ||
| err: err | ||
| }); | ||
| }); | ||
| } | ||
| catch (err) { | ||
| promiseTogo.resolve({ | ||
| solutionId: solutionID, | ||
| handlerSpec: handlerSpec, | ||
| isError: true, | ||
| message: "Unexpected Error in operating settings handler.", | ||
|
||
| err: err | ||
| }); | ||
| } | ||
| return promiseTogo; | ||
| }; | ||
|
|
||
| /** | ||
| * Fetches all settings for a particular solution, going through all of the solutions settings handlers. | ||
| * | ||
| * @param {lifecycleManager.invokeSettingsHandlerGet} invokeSettingsHandlerGet - Invoker from the `lifecycleManager` | ||
| * necessary for extracting settings from a solution and it's spec. | ||
| * @param {Object} solution - The solution registry entry body for this solution. | ||
| * @param {String} solutionID - The dotted solution id, example `com.microsoft.windows.cursors`. | ||
| * @param {lifecycleManager.variableResolver} resolver - Resolver for looking up handler specifications | ||
| * @return {Array} An array of promises resolving to the results from each settings handler the solution uses. | ||
| */ | ||
| gpii.flowManager.capture.fetchAllSettingsForSolution = function (invokeSettingsHandlerGet, solution, solutionID, resolver) { | ||
| var settingsPromisesTogo = []; | ||
|
|
||
| var newSolution = gpii.lifecycleManager.transformSolutionSettings(solution, gpii.settingsHandlers.changesToSettings); | ||
|
|
||
| // TODO GPII-4146 In progress refactoring back to gpii-windows | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // https://issues.gpii.net/browse/GPII-4146 | ||
| // if (solutionID === "com.freedomscientific.jaws") { | ||
| // newSolution = gpii.flowManager.jawsVoiceProfileAdjustment(newSolution, localResolver); | ||
| // } | ||
|
|
||
| fluid.each(newSolution.settingsHandlers, function (handlerSpec) { | ||
| //if applicationSettings is unspecified, dont attempt to get settings | ||
| if (!handlerSpec.supportedSettings) { | ||
| return; | ||
| } | ||
| handlerSpec.settings = handlerSpec.supportedSettings; | ||
| // TODO There is some in progress refactoring that happened here to update spiSettingsHandler. | ||
| // No longer here, but this is a reminder to resolve it when there are acceptance tests for the SPI settings capture. | ||
| handlerSpec = resolver.resolve(handlerSpec, {}); | ||
| settingsPromisesTogo.push(gpii.flowManager.capture.safeHandlerGet(invokeSettingsHandlerGet, solutionID, handlerSpec)); | ||
| }); | ||
| return settingsPromisesTogo; | ||
| }; | ||
|
|
||
| /** | ||
| * Fetches all the settings for an entire list of solutions. | ||
| * | ||
| * @param {Object} solutionsToFetch - A keyed object of solutions using the same format as the solutions registry. Keys | ||
| * are solutionsIDs, like `com.freedomscientific.jaws` and the entries are the full solution registry entries. | ||
| * @param {lifecycleManager.invokeSettingsHandlerGet} invokeSettingsHandlerGet - Invoker from the `lifecycleManager` | ||
| * necessary for extracting settings from a solution and it's spec. | ||
| * @param {lifecycleManager.variableResolver} resolver - Resolver for looking up handler specifications | ||
| * @return {Array} Returns a list of promises that resolve to captured settings for each particular settings handler in | ||
| * every solution. | ||
| */ | ||
| gpii.flowManager.capture.fetchAllSettingsForSolutionsList = function (solutionsToFetch, invokeSettingsHandlerGet, resolver) { | ||
|
||
| var handlerGetPromises = []; | ||
|
|
||
| fluid.each(solutionsToFetch, function (solution, solutionID) { | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| var nextPromises = gpii.flowManager.capture.fetchAllSettingsForSolution(invokeSettingsHandlerGet, solution, solutionID, resolver); | ||
| handlerGetPromises = handlerGetPromises.concat(nextPromises); | ||
| }); | ||
|
|
||
| return fluid.promise.sequence(handlerGetPromises); | ||
| }; | ||
|
|
||
| /** | ||
| * Runs through all the solutions currently available on the system, pulls the current | ||
| * setting for each supportedSetting and returns them in an object. Primary use case | ||
| * is for backing Capture tools that would allow a user to set up their GPII profile | ||
| * starting with the current settings for their applications on the local machine. | ||
| * | ||
| * @param {lifecycleManager.invokeSettingsHandlerGet} invokeSettingsHandlerGet - Invoker from the `lifecycleManager` | ||
| * necessary for extracting settings from a solution and it's spec. | ||
| * @param {lifecycleManager.variableResolver} resolver - Resolver for looking up handler specifications | ||
| * @param {Object} solutions - Solutions registry entries for solutions available on the current machine. | ||
| * @param {Object} options - Extra options for processing. | ||
| * @param {Array} options.solutionsList - If provided, only solutions in this list of `solutionsID`s will | ||
| * be captures. Example: | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * | ||
| * '''json | ||
| * ["com.microsoft.windows.cursors", "com.freedomscientific.jaws"] | ||
| * ''' | ||
| * @return {fluid.promise} Returns a promise resolving with the entire system settings capture. | ||
| */ | ||
| gpii.flowManager.captureSystemSettings = function (invokeSettingsHandlerGet, resolver, solutions, options) { | ||
| var solutionsToFetch = solutions; | ||
| if (options.solutionsList) { | ||
sgithens marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| solutionsToFetch = {}; | ||
| fluid.each(solutions, function (solution, solutionID) { | ||
| if (options.solutionsList.indexOf(solutionID) >= 0) { | ||
| solutionsToFetch[solutionID] = solution; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| return gpii.flowManager.capture.fetchAllSettingsForSolutionsList(solutionsToFetch, invokeSettingsHandlerGet, resolver); | ||
| }; | ||
|
|
||
| /** | ||
| * The raw return payload from the capture promise sequence looks like: | ||
| * '''json | ||
| * [ | ||
| * { | ||
| * "fakemag1": [ | ||
| * { | ||
| * "settings": { | ||
| * "magnification": 2 | ||
| * } | ||
| * } | ||
| * ] | ||
| * }, | ||
| * { | ||
| * "fakemag1": [ | ||
| * { | ||
| * "settings": { | ||
| * "invert": true | ||
| * } | ||
| * } | ||
| * ] | ||
| * }, | ||
| * { | ||
| * "fakemag2": [ | ||
| * { | ||
| * "settings": { | ||
| * "magnification": 2, | ||
| * "invert": true | ||
| * } | ||
| * } | ||
| * ] | ||
| * } | ||
| * ] | ||
| * ''' | ||
| * | ||
| * and we want: | ||
| * '''json | ||
| * { | ||
| * "fakemag1": { | ||
| * "magnification": 2, | ||
| * "invert": true | ||
| * }, | ||
| * "fakemag2": { | ||
| * "magnification": 2, | ||
| * "invert": true | ||
| * } | ||
| * } | ||
| * ''' | ||
| * | ||
| * @param {Object} data - The raw captured data. | ||
| * @return {Object} Returns a new payload with collapsed data, and multiple settings handler | ||
| * results for the same solution merged together. | ||
| */ | ||
| gpii.flowManager.formatRawCapturedSettings = function (data) { | ||
| var togo = {}; | ||
| fluid.each(data, function (sequenceItem) { | ||
| if (sequenceItem.isError) { | ||
| fluid.log("Error capturing settings for: ", sequenceItem); | ||
| return; | ||
| } | ||
| fluid.each(sequenceItem, function (item, key) { | ||
| if (!togo[key]) { | ||
| togo[key] = {}; | ||
| } | ||
| fluid.each(item[0].settings, function (value, settingId) { | ||
sgithens marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| togo[key][settingId] = value; | ||
| }); | ||
| }); | ||
| }); | ||
| return togo; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -92,13 +92,29 @@ | |
| * is fired with the modified mmpayload. | ||
| */ | ||
| gpii.flowManager.getSolutions = function (solutionsRegistryDataSource, deviceContext, event, onError) { | ||
| gpii.flowManager.getSolutionsPromise(solutionsRegistryDataSource, deviceContext).then( | ||
| function (data) { | ||
| event.fire(data.solutionsRegistryEntries, data.solutions); | ||
| }, | ||
| onError.fire | ||
| ); | ||
| }; | ||
|
|
||
| gpii.flowManager.getSolutionsPromise = function (solutionsRegistryDataSource, deviceContext) { | ||
|
||
| var promiseTogo = fluid.promise(); | ||
|
|
||
| var os = fluid.get(deviceContext, "OS.id"); | ||
| var promise = solutionsRegistryDataSource.get({}); | ||
| promise.then(function (solutions) { | ||
| var solutionsRegistryEntries = gpii.matchMakerFramework.filterSolutions(solutions[os], deviceContext); | ||
| fluid.log("Fetched filtered solutions registry entries: ", gpii.renderMegapayload({solutionsRegistryEntries: solutionsRegistryEntries})); | ||
| event.fire(solutionsRegistryEntries, solutions); | ||
| }, onError.fire); | ||
| promiseTogo.resolve({ | ||
| solutionsRegistryEntries: solutionsRegistryEntries, | ||
| solutions: solutions | ||
| }); | ||
| }, promiseTogo.reject); | ||
|
|
||
| return promiseTogo; | ||
| }; | ||
|
|
||
| // initialPayload contains fields | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.