How To Know That Your Flash Content Requires a Premium Feature License
A license is needed for your SWF if it uses premium features. The current premium feature that requires a license is a SWF that makes use of Stage3D
and ApplicationDomain.domainMemory
APIs at the same time. If only one is used without the other a license is not required.
Still not sure if your application requires the license? Well there is a way to find out with using a debug version of Flash Player. Starting with Flash Player 11.2 you will get a message that is rendered on top of your SWF if you require a license. Here is what it looks like:
And here is the code to force the watermark:
{
import flash.display.Sprite;
import flash.events.Event;
import flash.system.ApplicationDomain;
import flash.utils.ByteArray;
import flash.utils.Endian;
[SWF(width="320",height="160",backgroundColor="0x333333")]
public class PremiumFeatureCheck extends Sprite
{
public function PremiumFeatureCheck()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
trace("Stage3Ds Lenght: " + stage.stage3Ds.length + "");
stage.stage3Ds[0].addEventListener( Event.CONTEXT3D_CREATE, initStage3D );
stage.stage3Ds[0].requestContext3D();
var testData:ByteArray = new ByteArray();
testData.endian = Endian.LITTLE_ENDIAN;
testData.length=0xffff*4; //4bytes
ApplicationDomain.currentDomain.domainMemory=testData;
var testValue:int=123;
ApplicationDomain.currentDomain.domainMemory[0] = testValue;
var readValue:int = ApplicationDomain.currentDomain.domainMemory[0];
trace(readValue+"");//should print 123
}
protected function initStage3D(e:Event):void
{
var context3D:Object = stage.stage3Ds[0].context3D;
}
}
}
If you comment out “stage.stage3Ds[0].requestContext3D(); ” or remove the domainMemory lines of code you will not see this watermark.
NOTE: If you get a context3D error you need to make sure you have swf-version=13 and wmode=”direct” set up properly to run Stage3D content.
It’s also important to note that the watermark doesn’t show up until the features are used in your code. Take this code example:
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.system.ApplicationDomain;
import flash.utils.ByteArray;
import flash.utils.Endian;
[SWF(width="400",height="160",backgroundColor="0x333333")]
public class PremiumFeatureCheck extends Sprite
{
public function PremiumFeatureCheck()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
trace("Stage3Ds Lenght: " + stage.stage3Ds.length + "");
stage.stage3Ds[0].addEventListener( Event.CONTEXT3D_CREATE, initStage3D );
stage.stage3Ds[0].requestContext3D();
stage.addEventListener(MouseEvent.CLICK, useDomainMemory);
}
protected function initStage3D(e:Event):void
{
var context3D:Object = stage.stage3Ds[0].context3D;
}
protected function useDomainMemory(event:Event):void
{
var testData:ByteArray = new ByteArray();
testData.endian = Endian.LITTLE_ENDIAN;
testData.length=0xffff*4; //4bytes
ApplicationDomain.currentDomain.domainMemory=testData;
var testValue:int=123;
ApplicationDomain.currentDomain.domainMemory[0] = testValue;
var readValue:int = ApplicationDomain.currentDomain.domainMemory[0];
trace(readValue+"");//should print 123
}
}
}
The watermark will only show up once the domainMemory
chunk of code is ran after clicking on the stage.
Here is another scenario, SWFMain.swf loads both SWFStage3DAPI.swf and SWFDomainMemory.swf, do you need a license? Yes you do, the water shows up and stays (even if you try and unload) after you have run API calls for Stage3D or ApplicationDomain.domainMemory regardless if they are from the main SWF or loaded SWFs. If you want to try it out yourself here is the source code:
SWFMain.as
{
import flash.display.DisplayObjectContainer;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFormat;
public class SWFMain extends Sprite
{
public function SWFMain()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
format = new TextFormat();
format.size = 24;
format.color = 0xffffff;
}
public var loaderStage3D:Loader;
public var loaderDomainMemory:Loader;
public var format:TextFormat;
protected function addedToStageHandler(event:Event):void
{
// Create buttons
var s:Sprite = createButton("Load Stage3D SWF");
s.x = 10;
s.y = 10;
s = createButton("Load DomainMemory SWF");
s.x = 10;
s.y = 60;
}
protected function createButton(label:String):Sprite
{
var text:TextField = new TextField();
text.defaultTextFormat = format;
text.text = label;
text.width = 200;
var s:Sprite = new Sprite();
s.graphics.beginFill(0x222222, 0.8);
s.graphics.lineStyle(2,0x000000);
s.graphics.drawRect(0, 0, 240, 40);
s.graphics.endFill();
s.addEventListener(MouseEvent.CLICK, clickHandler);
s.addChild(text);
text.x = 10;
text.y = 8;
addChild(s);
return s;
}
protected function clickHandler(event:MouseEvent):void
{
var t:String = "";
if (event.currentTarget is Sprite)
t = ((event.currentTarget as DisplayObjectContainer).getChildAt(0) as TextField).text;
trace("Click handler:" + t);
if (t == "Load Stage3D SWF")
{
if (loaderStage3D)
{
loaderStage3D.unloadAndStop(true);
loaderStage3D = null;
}
else
{
loaderStage3D = new Loader();
loaderStage3D.load(new URLRequest("SWFStage3DAPI.swf"));
loaderStage3D.x = 40;
loaderStage3D.y = 160;
addChild(loaderStage3D);
}
}
if (t == "Load DomainMemory SWF")
{
if (loaderDomainMemory)
{
loaderDomainMemory.unloadAndStop(true);
loaderDomainMemory = null;
}
else
{
loaderDomainMemory = new Loader();
loaderDomainMemory.load(new URLRequest("SWFDomainMemory.swf"));
loaderDomainMemory.x = 40;
loaderDomainMemory.y = 200;
addChild(loaderDomainMemory);
}
}
}
}
}
Here is the SWFStage3DAPI.as
{
import flash.display.Sprite;
import flash.events.Event;
public class SWFStage3DAPI extends Sprite
{
public function SWFStage3DAPI()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
graphics.beginFill(0x0000ff);
graphics.drawRect(0, 0, 10, 10);
graphics.endFill();
trace("SWFStage3DAPI - Stage3Ds Lenght: " + stage.stage3Ds.length + "");
stage.stage3Ds[0].addEventListener( Event.CONTEXT3D_CREATE, initStage3D );
stage.stage3Ds[0].requestContext3D();
}
protected function initStage3D(e:Event):void
{
if (stage)
var context3D:Object = stage.stage3Ds[0].context3D;
}
}
}
Here is the SWFDomainMemory.as
{
import flash.display.Sprite;
import flash.events.Event;
import flash.system.ApplicationDomain;
import flash.utils.ByteArray;
import flash.utils.Endian;
public class SWFDomainMemory extends Sprite
{
public function SWFDomainMemory()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
graphics.beginFill(0xff0000);
graphics.drawRect(0, 0, 10, 10);
graphics.endFill();
var testData:ByteArray = new ByteArray();
testData.endian = Endian.LITTLE_ENDIAN;
testData.length=0xffff*4; //4bytes
ApplicationDomain.currentDomain.domainMemory=testData;
var testValue:int=123;
ApplicationDomain.currentDomain.domainMemory[0] = testValue;
var readValue:int = ApplicationDomain.currentDomain.domainMemory[0];
trace("SWFDomainMemroy " + readValue);//should print 123
}
}
}
Pingback: leebrimelow.com » An unofficial premium feature FAQ