admin-service.js 8.2 KB
/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright 2015 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 may be covered by U.S. and Foreign Patents,
 * patents in process, 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/runtime/impl/admin-service', [
    'underscore',
    'screens/player/runtime/admin',
    'screens/player/shared/serviceadmin',
    'screens/player/store/store',
    'screens/player/firmware/core/statusmodel/statusmodel',
    'screens/player/firmware/preferences/preferences',
    'screens/player/firmware/core/config/config',
    'screens/player/ui/adminview',
    'module'
], function(_, Admin, ServiceAdmin, Store, StatusModel, Preferences, Config, AdminView, mod) {
    'use strict';

    /**
     * Defines the admin Service
     *
     * @class AdminService
     * @implements {Admin}
     */
    var AdminService = {

        serviceId: mod.id,

        /**
         * @memberof AdminService
         */
        serviceName: Admin.serviceName,

        /**
         * @memberof AdminService
         * @inheritdoc
         */
        activate: function() {
            var self = this;

            return new Promise(function(resolve) {
                    // waiting for the store because it is needed for the API
                    ServiceAdmin.onServiceHighestRankedStart(Store.serviceName, function(store) {
                        resolve(store);
                    });
                })
                .then(function(store) {
                    return new Promise(function(resolve) {
                        // waiting for the preferences because it will be needed in the view
                        ServiceAdmin.onServiceHighestRankedStart(Preferences.serviceName, function(preferences) {
                            resolve([store, preferences]);
                        });
                    });
                })
                .then(function(services) {
                    return new Promise(function(resolve) {
                        // waiting for the config because it will be needed in the view
                        ServiceAdmin.onServiceHighestRankedStart(Config.serviceName, function(config) {
                            services.push(config);
                            resolve(services);
                        });
                    });
                })
                .then(function(services) {
                    var store = services[0];

                    var state = store.getState();

                    self._preferencesChangeListener = store.subscribe(self._onPreferencesChange.bind(self), Preferences.NAMESPACE);
                    self._onPreferencesChange(state[Preferences.NAMESPACE]);

                    self._displayChangeListener = store.subscribe(self._onDisplayChange.bind(self), Config.NAMESPACES.DISPLAY);
                    self._onDisplayChange(state[Config.NAMESPACES.DISPLAY]);
                    self._view = new AdminView();

                    return Promise.resolve(services);
                })
                .catch(function(e) {
                    console.error('Error initialising the admin service.', e);
                });
        },

        /**
         * Handler for preference changes
         * @param {Map} preferences The new preferences
         * @private
         */
        _onPreferencesChange: function(preferences) {
            // Activate a listener for status if preferences changed
            if (preferences && !preferences.device) {
                var store = ServiceAdmin.getService(Store.serviceName);
                if (this._statusModelChangeListener) {
                    store.unsubscribe(this._statusModelChangeListener);
                    clearTimeout(this._statusTimer);
                }
                this.currentRegistrationState = store.getState()[StatusModel.NAMESPACE].registrationState;
                this._statusModelChangeListener = store.subscribe(this._onStatusChange.bind(this), StatusModel.NAMESPACE);

                // Unsubscribe after 30 seconds if no change happens to registration state after preference change
                if (this._statusTimer) {
                    clearTimeout(this._statusTimer);
                }
                this._statusTimer = setTimeout(function() {
                    this._unsubscribeStatus();
                }.bind(this), 30000);
            }
        },

        /**
         * Handler for status changes
         * @param {Map} statusModel The new status model
         * @private
         */
        _onStatusChange: function(statusModel) {
            // we show the admin ui registration tab if status is unregistered
            console.log(statusModel.registrationState);
            if (this.currentRegistrationState !== statusModel.registrationState) {
                if (statusModel.registrationState === 'UNREGISTERED') {
                    this.show('registration');
                }
                else {
                    this.show('config');
                }
                clearTimeout(this._statusTimer);
                this._unsubscribeStatus();
            }
        },

        /**
         * Timeout Handler for status changes
         * @private
         */
        _unsubscribeStatus: function() {
            this.currentRegistrationState = null;
            if (this._statusModelChangeListener) {
                var store = ServiceAdmin.getService(Store.serviceName);
                store.unsubscribe(this._statusModelChangeListener);
                this._statusModelChangeListener = null;
            }
        },

        /**
         * Handler for display config changes
         * @param {Map} newDisplay The new display properties
         * @private
         */
        _onDisplayChange: function(newDisplay) {
            // we show the admin ui in case no display is available but device is registered
            if (!_.isEmpty(newDisplay)) {
                return;
            }

            var preferencesService = ServiceAdmin.getService(Preferences.serviceName);
            if (preferencesService.getPreferences().device) {
                this.show('system');
            }
        },

        /**
         * @memberof AdminService
         * @inheritdoc
         */
        deactivate: function() {
            this._view.destroy();

            var store = ServiceAdmin.getService(Store.serviceName);
            if (this._preferencesChangeListener) {
                store.unsubscribe(this._preferencesChangeListener);
                this._preferencesChangeListener = null;
            }
            if (this._displayChangeListener) {
                store.unsubscribe(this._displayChangeListener);
                this._displayChangeListener = null;
            }
            if (this._statusModelChangeListener) {
                store.unsubscribe(this._statusModelChangeListener);
                this._statusModelChangeListener = null;
            }

            return Promise.resolve();
        },

        /**
         * @memberof AdminService
         * @inheritdoc
         */
        show: function(tabName) {
            var store = ServiceAdmin.getService(Store.serviceName);

            store.dispatch({
                type: Admin.ACTIONS.SHOW,
                payload: {
                    tabName: tabName
                }
            });
        },

        /**
         * @memberof AdminService
         * @inheritdoc
         */
        hide: function() {
            var store = ServiceAdmin.getService(Store.serviceName);

            store.dispatch({
                type: Admin.ACTIONS.HIDE,
                payload: {
                }
            });
        }
    };

    return AdminService;

});

require([
    'screens/player/runtime/impl/admin-service',
    'screens/player/shared/serviceadmin'
], function(AdminService, ServiceAdmin) {
    'use strict';
    ServiceAdmin.register(AdminService);
});