From 6546e9a9c116e7a0e6445ab2395cddbae336524b Mon Sep 17 00:00:00 2001 From: Alive Kuo Date: Tue, 28 Jan 2014 19:36:52 +0800 Subject: [PATCH] Bug 956938 - Fix active activity reference and remove the activity window correctly when there is multiple inline activities --- apps/system/js/activity_window.js | 19 ++++--- apps/system/js/activity_window_factory.js | 49 ++++++++++++++++--- .../test/unit/activity_window_factory_test.js | 40 ++++----------- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/apps/system/js/activity_window.js b/apps/system/js/activity_window.js index d496bf59608b..883a0134d205 100644 --- a/apps/system/js/activity_window.js +++ b/apps/system/js/activity_window.js @@ -203,7 +203,12 @@ if (this.activityCallee) { this.activityCallee.kill(); } - if (this.activityCaller instanceof AppWindow) { + this.debug('request caller to open again'); + if (this.activityCaller instanceof ActivityWindow) { + if (evt) { + this.activityCaller.open(); + } + } else if (this.activityCaller instanceof AppWindow) { // If we're killed by event handler, display the caller. if (evt) { // XXX: We should just request this.activityCaller.open() @@ -215,21 +220,21 @@ WindowManager.setDisplayedApp(this.activityCaller.origin); } } - } else if (this.activityCaller instanceof ActivityWindow) { - if (evt) { - this.activityCaller.open(); - } } else { console.warn('unknown window type of activity caller.'); } - this.containerElement.removeChild(this.element); + var e = this.containerElement.removeChild(this.element); + this.debug('removed ' + e); + this.publish('removed'); }.bind(this)); } else { this.publish('terminated'); if (this.activityCallee) { this.activityCallee.kill(); } - this.containerElement.removeChild(this.element); + var e = this.containerElement.removeChild(this.element); + this.debug('removed ' + e); + this.publish('removed'); } this.debug('killed by ', evt ? evt.type : 'direct function call.'); this.activityCaller.unsetActivityCallee(); diff --git a/apps/system/js/activity_window_factory.js b/apps/system/js/activity_window_factory.js index f812fb329000..6666212f93d4 100644 --- a/apps/system/js/activity_window_factory.js +++ b/apps/system/js/activity_window_factory.js @@ -1,4 +1,6 @@ (function(window) { + var DEBUG = false; + var ActivityWindowFactory = { // Last created activtiy window object. _lastActivity: null, @@ -7,6 +9,14 @@ _activities: [], + debug: function awm_debug() { + if (DEBUG) { + console.log('[ActivityWindowFactory]' + + '[' + Date.now() / 1000 + ']' + + Array.slice(arguments).concat()); + } + }, + init: function acwf_init() { window.addEventListener('mozChromeEvent', this); window.addEventListener('launchapp', this); @@ -28,6 +38,7 @@ }, handleEvent: function acwf_handleEvent(evt) { + this.debug('handling ' + evt.type); switch (evt.type) { // XXX: Move into appWindow. case 'appopen': @@ -70,9 +81,10 @@ case 'launchapp': if (evt.detail.isActivity && evt.detail.inline) { - if (this._lastActivity && this._lastActivity.isActive()) { + if (this._activeActivity) { + this.debug('caller is an activity: ', this._activeActivity.name); // If we already has a callee, remove it. - var callee = this._lastActivity.activityCallee; + var callee = this._activeActivity.activityCallee; if (callee) { // XXX: We don't know the activity is the same request // or not here. The data passed may be different. @@ -99,15 +111,16 @@ }); // If the lastActivity is the same as launch request, we don't // need to create another activity. - if (this._lastActivity.manifestURL === evt.detail.manifestURL && - this._lastActivity.url === evt.detail.url) { + if (this._activeActivity.manifestURL === evt.detail.manifestURL && + this._activeActivity.url === evt.detail.url) { return; } this._lastActivity = new ActivityWindow(evt.detail, - this._lastActivity); + this._activeActivity); break; } var app = WindowManager.getCurrentActiveAppWindow(); + this.debug('caller is an app: ' + (app && app.name)); var callee = app.activityCallee; if (callee) { // XXX: We don't know the activity is the same request @@ -160,16 +173,38 @@ break; case 'activitywillopen': - this._activeActivity = evt.detail; + var activity = evt.detail; + this.debug('activity: ' + activity.name + + ' is opening, its caller is ' + activity.activityCaller.name); + this._activeActivity = activity; break; + /** + * We should implement API to find out real active frame + * but now we only try to guess. + */ case 'activitywillclose': - if (this._activeActivity && + var activity = evt.detail; + this.debug('activity: ' + activity.name + + ' is closing, its caller is ' + activity.activityCaller.name); + if (activity.activityCaller && + activity.activityCaller instanceof ActivityWindow) { + this._activeActivity = activity.activityCaller; + } else if (this._activeActivity && this._activeActivity.instanceID == evt.detail.instanceID) { this._activeActivity = null; } break; } + }, + _dump: function() { + if (DEBUG) { + this.debug('dump all activity windows'); + var a = document.querySelectorAll('.activityWindow > iframe'); + for (var i = 0; i < a.length; i++) { + this.debug(a[i].src); + } + } } }; diff --git a/apps/system/test/unit/activity_window_factory_test.js b/apps/system/test/unit/activity_window_factory_test.js index cdb92c33973b..e5d18a56b93d 100644 --- a/apps/system/test/unit/activity_window_factory_test.js +++ b/apps/system/test/unit/activity_window_factory_test.js @@ -177,21 +177,27 @@ suite('system/ActivityWindowFactory', function() { }) }; MockWindowManager.mDisplayedApp = 'fake'; + resetActivityWindowFactory(); }); teardown(function() { }); + + function resetActivityWindowFactory() { + ActivityWindowFactory._lastActivity = null; + ActivityWindowFactory._activeActivity = null; + ActivityWindowFactory._activities = []; + }; test('activity request', function() { ActivityWindowFactory.handleEvent(fakeLaunchConfig1); assert.isTrue(ActivityWindowFactory._lastActivity != null); - - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); test('back to home: one inline activity', function() { + ActivityWindowFactory._activeActivity = null; ActivityWindowFactory.handleEvent(fakeLaunchConfig1); var activity = ActivityWindowFactory._lastActivity; + console.log(ActivityWindowFactory); var stubKill = this.sinon.stub(activity, 'kill'); ActivityWindowFactory.handleEvent({ @@ -199,10 +205,6 @@ suite('system/ActivityWindowFactory', function() { }); assert.isTrue(stubKill.called); - stubKill.restore(); - - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); test('second activity request on the same caller', function() { @@ -216,11 +218,6 @@ suite('system/ActivityWindowFactory', function() { ActivityWindowFactory.handleEvent(fakeLaunchConfig2); assert.isTrue(stubKill.called); - stubKill.restore(); - stubActive.restore(); - - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); @@ -232,9 +229,6 @@ suite('system/ActivityWindowFactory', function() { // launch again. ActivityWindowFactory.handleEvent(fakeLaunchConfig1); assert.equal(ActivityWindowFactory._activities.length, 1); - - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); test('maintain activity: created', function() { @@ -247,8 +241,6 @@ suite('system/ActivityWindowFactory', function() { }); assert.isTrue(ActivityWindowFactory._activities.length === current + 1); - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); test('maintain activity: terminated', function() { @@ -263,9 +255,6 @@ suite('system/ActivityWindowFactory', function() { }); assert.isTrue(ActivityWindowFactory._lastActivity == null); - - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); test('show current activity', function() { @@ -279,10 +268,6 @@ suite('system/ActivityWindowFactory', function() { }); assert.isTrue(stubSetVisible.calledWith(true)); - stubSetVisible.restore(); - - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); test('hide current activity', function() { @@ -296,10 +281,6 @@ suite('system/ActivityWindowFactory', function() { }); assert.isTrue(stubSetVisible.calledWith(false)); - stubSetVisible.restore(); - - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); test('update active activity', function() { @@ -324,9 +305,6 @@ suite('system/ActivityWindowFactory', function() { }); assert.equal(ActivityWindowFactory._activeActivity, activity); - - ActivityWindowFactory._lastActivity = null; - ActivityWindowFactory._activities = []; }); }); });