akihiko122 / swfobject

Automatically exported from code.google.com/p/swfobject
0 stars 0 forks source link

Enhancement suggestion: modified expressInstall.swf functionality #154

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
In issue #153 just submitted, I identified a case where I was trying to 
use some alternate XI behavior.  Let me expound on that case here, and the 
suggested enhancements I am making in regards to it.

Short backstory:
When the XI process is initiated in a browser (that is, expressInstall.swf 
is loaded), another file ("autoUpdater.swf") is downloaded from Adobe/MM.  
This file is the one that has the brains in it in terms of figuring out 
how and which player plugin payload to download and install.  It's an 
undocumented swf as far as I can tell.  However, I de-compiled it and 
evaluated the source of it, as part of my troubleshooting of the scenario 
I'm about to describe.

The autoUpdater.swf has (incorrectly in my opinion) logic in it which 
basically says that if it has been called on a system that already has the 
latest player plugin version (that is, nothing to update to), rather than 
giving some failure code or some other signal, it silently "return;"s out 
of the code logic and leaves the XI swf simply hanging there.

If an author (incorrectly) specifies a higher, non-existent version 
string, SWFObject will kick in the XI logic, which will then hang and sit 
silently, and the alt content will never be re-displayed.  Obviously, this 
is author mis-behavior, however there are (corner) cases where such can 
happen inadvertently, and XI is not robust in handling it, and so 
therefore SWFObject's handling of it is also impaired.

For instance, right now, "9.0.125" is a valid version string, but *only* 
for Solaris. If I were targetting code to that version of the plugin, I'd 
have to have some sort of browser detecting logic to use "9.0.124" 
everywhere else, and "9.0.125" only on Solaris. If I don't, then 
this "hang" behavior would occur on already updated non-solaris browsers.

A simple (I believe) change to the XI swf code logic can address this 
failure case though, by utilizing the already built in "timeout" failure 
logic.

Here's the suggested modified block of code in expressInstall.as:

var int_id          = setInterval(checkLoaded, delay);

var old_si = null;

function checkLoaded(){
    time += delay/1000;
    if(time > timeOut){
        // updater did not load in time, abort load and force 
alternative content
        clearInterval(int_id);
        loaderClip.unloadMovie();
        loadTimeOut();
        return;
    }
    if (loaderClip.startInstall.toString() == "[type Function]"){
        // updater has loaded successfully
        if (old_si == null) {
            old_si = loaderClip.startInstall;
            loaderClip.startInstall = function() {
                clearInterval(int_id);
                old_si();
            }
            loadComplete();
        }
    }
}

Notice a couple of things:
1. I renamed "id" to "int_id" to prevent some possible namespacing 
variable issues between the two SWF's.

2. I am checking for the "startInstall" rather than the "startUpdate" 
functions in the loaded SWF.

3. I simply piggyback on the "startInstall" function to know if the rest 
of "autoUpdater.swf"s logic has determined that an install should in fact 
begin.

4. If "startInstall" is never called by autoUpdater.swf's logic (the 
silent "return"), then the failure timeout eventually occurs (approx 5 
seconds later) and SWFObject is notified, so it can then re-display the 
alternate content.

My reasoning behind this suggested change is to make the XI process more 
robust to problems where a version string is not interpreted properly 
(buggy plugin installs) or is invalid for a particular browser/platform, 
and where XI is improperly launched but never backs itself out, instead 
just silently rests without telling anyone!

Original issue reported on code.google.com by get...@gmail.com on 25 Aug 2008 at 1:49

GoogleCodeExporter commented 9 years ago
Also, here's an example of the suggested code logic change in place (with the 
modified expressInstall.swf file).

http://www.flensed.com/code/dev-tests/test-swfobject-3.html

You can see that after about 5 seconds, the alternate content is re-displayed.

Original comment by get...@gmail.com on 25 Aug 2008 at 1:56

GoogleCodeExporter commented 9 years ago
Thanks Kyle, it's on the list for the next version :-)

Original comment by bobbyvandersluis on 25 Aug 2008 at 3:22

GoogleCodeExporter commented 9 years ago

Original comment by bobbyvandersluis on 25 Aug 2008 at 3:26

GoogleCodeExporter commented 9 years ago
FYI, I believe at the moment, this test now no longer shows the intended 
behavior 
(plugin update failing, timeout re-displaying alt content), because FP10 is out 
now, 
so the "bogus" version string I used now triggers an update from 9.0.124 to the 
10.0.12.36.  I'll update the test shortly to use a really bogus version like 
"12" so 
this test continues to show the behavior as intended (assuming you already have 
the 
latest FP10 plugin!), at least for a few more years til Adobe release FP12!  :)

Original comment by get...@gmail.com on 17 Oct 2008 at 7:32

GoogleCodeExporter commented 9 years ago
Updates are checked into SVN. I did wonder why you used old_si though, because I
thought it wasn't really necessary? 

Original comment by bobbyvandersluis on 8 Jan 2009 at 2:11

GoogleCodeExporter commented 9 years ago
saving the old/original "startInstall" into "old_si" is required because the 
functionality that is in that function still needs to be executed, but also the 
clearInterval needs to be executed. This is kind of "AOP style", where you take 
a 
function, and redefine it by wrapping it in another function that does the 
original 
stuff, but also more stuff before or after it.

If I hadn't saved the original function executable reference, then immediately 
after 
I did the reassign of the function, that functionality would be 
lost/inaccessible to 
be excuted.

And I needed to actually redefine the function because other code that we don't 
control (namely the payload that comes from Adobe dynamically) is hardcoded to 
call 
that particular function name. So this was the only way to get our 
"clearInterval" 
call made automatically when the Adobe payload arrives and fires off it's 
functionality.

Original comment by get...@gmail.com on 8 Jan 2009 at 3:20

GoogleCodeExporter commented 9 years ago
I thought that startInstall is executed automatically, so there would be no 
reason to
do this manually???

Original comment by bobbyvandersluis on 1 Apr 2009 at 2:59

GoogleCodeExporter commented 9 years ago
startInstall *is* called automatically by Adobe's payload that is downloaded. 
And we 
exploit that fact so that we can insert our own logic into the calling chain. 

If you are familiar with AOP, basically, this is a "before" definition. We need 
to 
wrap some of our own custom logic into startInstall, so that when it is called, 
our 
logic is called, *and* the original logic is also called.

We are essentially saying, "while you are doing XX, also do YY". So, we save a 
reference to the old startInstall (in "old_si"), then we redefine startInstall 
to be 
a function that does what we want it to do, which THEN also calls the old_si 
saved 
reference function.  This makes sure that *both* our new code, and the old 
original 
startInstall, get executed, when the Adobe payload calls the function 
"startInstall".

Does that make sense?

Original comment by get...@gmail.com on 1 Apr 2009 at 3:08

GoogleCodeExporter commented 9 years ago
You're correct, I have uploaded the changes, new expressInstall.swf is also 
available
in the 2.2 test suite

Original comment by bobbyvandersluis on 6 Apr 2009 at 11:25

GoogleCodeExporter commented 9 years ago
Included in the SWFObject 2.2 beta1 release

Original comment by bobbyvandersluis on 16 Apr 2009 at 3:05