AIR: Security Sandbox Violation when using remote images - apache-flex

The code below is simplified for example
I'm developing an AIR application (using Flex) which loads several of its images from a remote web server. The images display fine, however, whenever I'm manipulating the containers which hold the remotely-loaded images, I get errors in my console:
*** Security Sandbox Violation ***
SecurityDomain 'http://www.google.com/intl/en_ALL/images/logo.gif' tried to access incompatible context 'app:/sandbox_test.swf'
The images don't seem to be affected, but I don't like having errors displayed that I don't understand. Here's a sample app that exemplifies the problem:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication width="500" height="500" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:HDividedBox width="100%" height="300" horizontalCenter="0" verticalCenter="0" backgroundColor="#000000" liveDragging="true">
<mx:Image source="http://sstatic.net/so/img/logo.png"/>
<mx:Image source="http://www.google.com/intl/en_ALL/images/logo.gif"/>
</mx:HDividedBox>
</mx:WindowedApplication>
If you drag using the dragger on the HDividedBox, the security error appears.
I've looked at some of the Security class / security sandbox stuff for AIR, but by default AIR should have access to networked resources (which is why the images load I think). Using Security.allowDomain("www.google.com") isn't an option in AIR - it just throws a SecurityError.
Does anyone know what's causing it, or how to fix it? (Or maybe it's just a Flex/AIR bug?).
Also - does anyone know if there's a way to break when the error happens, so I can trace it to the root action causing it?

This security sandbox issue is specific to dragging UIComponents that have Image components in them. The Image components reference external images. I've looked everywhere and every post I run into the thread ends unanswered, which typically means its a bug.
My bootleg workaround? After the image has downloaded to the Image component, cache it as a bitmap and reassign the Image components source to the Bitmap. This fixed the issue for me:
private function authorImageLoadComplete(event:Event):void {
var bp:Bitmap = dupeImage(authorImage);
authorImage.source=bp;
}
private function dupeImage(source:Image):Bitmap {
var data:BitmapData = Bitmap(source.content).bitmapData;
var bitmap:Bitmap = new Bitmap(data);
return bitmap;
}
Then your image tag in your UIComponent:
<mx:Image id="authorImage" complete="authorImageLoadComplete(event)"></mx:Image>
Best of luck guys

For Flex 4, try setting the top level WindowedApplication's useNativeDragManager property to false, as documented here: http://cookbooks.adobe.com/post_How_do_you_make_a_Spark_custom_itemRenderer_with_a-16532.html

Do this images show up when you aren't running in Debug? The problem is that the domain doesn't have a crossdomain.xml file setup to allow for images in Flash.
http://www.google.com/crossdomain.xml:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="by-content-type" />
</cross-domain-policy>
You should probably just grab the images and place them in your application's assets, or on a domain you control and can properly add a crossdomain.xml that would allow for the content. Security.allowDomain isn't going to have the affect you are looking for. This article has the best explanation of crossdomain security I have read.
See ryanstewart's comment below. The above is hogwash for an AIR app.

Related

Flex mobile SWFLoader not loading

I'm trying to load a swf file into my flex mobile application with a swfloader however whenever I run the app the only thing that appears is a little square file icon. I've actually tried this with two swf files, both built in Flash CS Professionall but one in AS2 and one in AS3 and I get the same problem. I've tried setting autoLoad to true and it doesnt help. Also the complete event never runs, I'm assuming this is a result of the issue. Here is how I tried to make a SWFLoaders for both cases of which swf to load.
<s:SWFLoader id="mySWFLoader" bottom="10" left="10" source="/_flash/ffTalkSimpleSwf.swf" complete="setSwfMc()" />
<s:SWFLoader id="loader" width="75%" height="75%"
source="/Module tester/ITPM2/common/shell1/controller.swf" autoLoad="true" creationComplete="done()"/>
I've tried embeding the source and it works for the second swf, however I don't want the source embeded because that swf needs to communicate with other files because it is the controller file of another application which I am trying to load.
Thanks

Make Flex mobile full screen in desktop (as an air app)

I need to make flex mobile application to be full screen when it runs on desktop OSs (I've packaged it as an air app)
I'm pretty sure that your view will dispatch it's creationComplete event before the main Application is added to the stage, which is probably why you got the error.
In the past, I've used the applicationComplete event and the StageDisplayState.FULL_SCREEN. Here is an old blog post I wrote about it.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" alwaysInFront="true"
applicationComplete="onApplicationComplete()">
<mx:Script><![CDATA[
public function onApplicationComplete():void{
this.stage.displayState = StageDisplayState.FULL_SCREEN;
}
]]></mx:Script>
</mx:WindowedApplication>
I see no reason why this code wouldn't work in a Flex 4 / Spark app.
Switching to full screen through stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE can not be done on a creation complete handler. It must be done through user interaction. I actually just did this yesterday. Add a button to your app and set the onClick to a function that sets full screen and hides the button. That's how I did it anyways.

flex browser application initialization

Would anyone be able to point out some good tutorials on creating applications in flex that are don't have UI's?
Actually, it looks like all I really need to know is how to call a function upon initialization of the flash object. I tried the creationComplete attribute, but it doesn't work in browser.
Well, I'm not sure what made it work finally, but I ended up copying and pasting this code from some website (sorry, i don't remember the site):
<?xml version="1.0" encoding="utf-8"?>
<!-- wrapper/CheckExternalInterface.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="initApp()">
</s:Application>
And that ended up working! thanks anyway.
If you're intent is to connect JavaScript to a Java Server, why not use XMLHTTPRequest? IT is the basis of every AJAX style RIA application. The data format you pass back and forth can either be JSON or XML. It doesn't have to be binary.
Second, you don't need Flex for this. The Sockets APIs in ActionScript and are part of the Flash Player. You can use them without any dependencies to the Flex Framework.

Allowing mouse events to bubble reliably through the youtube chromeless player?

Hello all!
I'm working on a prototype that would require me being able to read and track the mouse movement over a playing youtube video. The basic code to replicate my problem boils down to this simple test case:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
initialize="{go();}">
<mx:VBox>
<mx:Label id="test" text=""/>
<mx:SWFLoader source="http://www.youtube.com/apiplayer?version=3" />
</mx:VBox>
<mx:Script>
<![CDATA[
function go(){
Security.allowDomain("*");
Security.allowInsecureDomain("*");
addEventListener(MouseEvent.MOUSE_MOVE,
function(e:MouseEvent){trace(test.text=e.stageX+"")});
}
]]>
</mx:Script>
</mx:Application>
Expected behavior is:
Youtube player loads
The label on the top right tracks the X coordinate of the mouse
The number should update even when moving the mouse over the Youtube player
So far the program behaves as expected when running from the IDE (tested on both FlashDevelop and FlashBuilder) and even when running the file manually from the output folder. But, alas, when I try to run it from anywhere else than the debug folder (be it another location on my computer or up on a webserver), the Youtube player seems to eat the events.
I don't get sandbox security warnings when debugging (thanks to allowDomain("*")) but I'm running out of ideas on why the program fails once you take the file out of the debug folder.
I would immensely appreciate any clues. Please note that as far as solutions go, I'm willing to try a different tech than flash if you have a proof of that working somewhere else.
Ok so I'm answering my own answer (I know...) only to let it recorded somewhere if someone needs it.
As much as I tried, there was no success with tweaking the security sandbox settings. I even tried all possible combinations, and no dice.
What I did do, out of desperation, was actually adding mouse listeners to the Loader.content property once loading is finished. And it worked well enough.
It's the only place I've found where a loading application can safely access the loadee's mouse events without obstructing its inner mouse logic.
Hope it helps someone else get unstuck in the future!

How can I detect if a Flex app loses focus

As a follow up to this question: Developing a online exam application, how do I prevent cheaters?
Can I detect when Flex application looses its focus? that is if a user has clicked onto another application or opened a browser tab?
I read this: Detecting when a Flex application loses focus but was not very clear...
The key part of the code at that link is the
systemManager.stage.addEventListener(Event.DEACTIVATE,deactivate);
The Flash player send outs activate and deactivate events when the focus enters and leaves the player. All you need to do is create a listenr for them and react appropriately.
A more clear example of how to use to the activate and deactivate events can be seen at blog.flexaxamples.com.
Also, it looks like the activate and deactivate events have trouble in some browsers. Colin Moock has more info on that here.
You can add a handler for activate in the main application tag. This detects whenever the flex application comes to focus.
Eg:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white"
activate="activateHandler(event);"
deactivate="deactivateHandler(event);">
This will work to detect when the Flex windows loses focus, but to detect when the window regains focus without having to actually click on the flex app requires an update in the HTML wrapper, correct? Something like:
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = ${version_major};
// Minor version of Flash required
var requiredMinorVersion = ${version_minor};
// Minor version of Flash required
var requiredRevision = ${version_revision};
// -----------------------------------------------------------------------------
// -->
function onAppFocusIn()
{
${application}.onAppFocusIn();
alert("onAppFocusIn");
}
</script>
<body scroll="no" onFocus="onAppFocusIn()">
I am trying to implement this but the onAppFocusIn() function is not executing once I move back to the flex app window. When I view the source, the code is there. Does anyone know why??
Thanks,
Annie
In Flex 4.6, this command works systemManager.stage.addEventListener(Event.DEACTIVATE, deactivate)
but make sure the flash app wmode is set to window (default). When the wmode was transparent, the event didn't get caught. You set the wmode in the embedded html where you put your flash app. example:
<object classid="clsid:D27WEE-A16D-21cf-90F2-422253540410" width="100%" height="100%"
id="MyApp" name="MyApp" align="middle">
<param name="movie" value="MyApp.swf?v=1.00.008" />
<param name="wmode" value="transparent"> <----- take out this
...

Resources