reboot-service.js 5.05 KB
/*
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2017 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 */
/* globals Promise */
define('screens/player/firmware/reboot/impl/reboot-service', [
    'later',
    'screens/player/firmware/preferences/preferences',
    'screens/player/firmware/reboot/reboot',
    'screens/player/firmware/reboot/spi/reboot',
    'screens/player/shared/serviceadmin',
    'screens/player/shared/util',
    'screens/player/store/store',
    'screens/player/firmware/core/statusmodel/statusmodel',
    'module'
], function(later, Preferences, Reboot, RebootSpi, ServiceAdmin, Util, Store, StatusModel, mod) {
    'use strict';

    /**
     * Defines the Reboot Service
     *
     * @class RebootImpl
     * @implements {Reboot}
     */
    function RebootImpl() {}

    var _dispatchNextReboot = function(next) {
        var store = ServiceAdmin.getService(Store.serviceName);
        store.dispatch({
            type: StatusModel.ACTIONS.UPDATE,
            payload: { nextReboot: next || null }
        });
    };

    RebootImpl.prototype = _.assign({}, Reboot, {

        serviceId: mod.id,

        serviceRanking: 10,

        _lastRebootSchedule: null,

        activate: function() {
            var self = this;

            function _onPreferencesSubscribe(state) {
                var newSchedule = state.rebootSchedule;
                if (newSchedule !== self._lastRebootSchedule) {
                    if (!newSchedule) {
                        console.log('[reboot] Unscheduling the reboot');
                        self.clear();
                    } else {
                        self.schedule(state.rebootSchedule)
                            .then(function(schedule) {
                                console.log('[reboot] Scheduling reboot at: ' + schedule.next + ' (' + schedule.remaining + 'ms)');
                            })
                            .catch(console.error);
                    }
                    self._lastRebootSchedule = newSchedule;
                }
            }

            return new Promise(function(resolve, reject) {
                ServiceAdmin.onServiceHighestRankedStart(RebootSpi.serviceName, function(spi) {
                    self._rebootSpi = spi;
                    resolve();
                });
            }).then(function() {
                return new Promise(function(resolve, reject) {
                    ServiceAdmin.onServiceHighestRankedStart(Store.serviceName, function(store) {
                        self._preferencesChangeListner = store.subscribe(_onPreferencesSubscribe, Preferences.NAMESPACE);
                        resolve();
                    });
                });
            });
        },

        deactivate: function() {
            if (this._preferencesChangeListner) {
                var store = ServiceAdmin.getService(Store.serviceName);
                store.unsubscribe(this._preferencesChangeListner);
                this._preferencesChangeListner = null;
            }
        },

        schedule: function(scheduleExpr) {
            if (!scheduleExpr) {
                return Promise.reject(new Error('[reboot] Missing schedule expression.'));
            }

            var parsedSchedule = Util.getSchedule(later, scheduleExpr);
            if (!parsedSchedule) {
                _dispatchNextReboot();
                return Promise.reject(new Error('[reboot] Invalid schedule expression: ' + parsedSchedule + '. Cannot schedule a reboot'));
            }

            var next = Util.getNextScheduleOccurance(later, parsedSchedule);
            return this._rebootSpi.schedule(parsedSchedule, next)
                .then(function() {
                    var remaining = new Date(next).getTime() - new Date().getTime();
                    _dispatchNextReboot(next);
                    return Promise.resolve({
                        next: next,
                        remaining: remaining
                    });
                })
                .catch(function(err) {
                    _dispatchNextReboot();
                    return Promise.reject(new Error('[reboot] An error occured while scheduling the reboot: ' + err.message));
                });
        },

        clear: function() {
            return this._rebootSpi.clear().then(function() {
                _dispatchNextReboot();
            });
        }

    });

    return RebootImpl;
});

/* istanbul ignore next */
require([
    'screens/player/firmware/reboot/impl/reboot-service',
    'screens/player/shared/serviceadmin'
], function(Service, ServiceAdmin) {
    'use strict';
    ServiceAdmin.register(new Service());
});