Geeky business

December 12th, 2010 No comments

I thought its time to get my ass back to this “electronic typewriter” and do the writing exercise again. When I was working for Adobe they kinda forced me to do this … and I was grateful for that. I mean I love to search for answer and geeky stuff on Google and stumble on someone post that answer to my question. And this would not be possible if everybody was lazy like I was this year and didn’t want to share his hackings on this cool and crazy thing called The Internet.

Last 10 months were a very interesting ride for me to take. My decision to take a break from corporate world wasn’t planned in advance. It was more of an impulse thing following some health problem that I had at that time (I almost broke my back while playing tennis). Life in Adobe was not that great for me either as the business in the region got hit hard by the recession.  So I was kinda confused and scared. Scared because of my back issue.  Luckily I got a good advice from an childhood friend that told me: “Do you have enough money to stop working without freaking out about the cost  of living? Yeap, I said. Then just stop and after 2 months you will figure out!”.

And that is what I did. And I start thinking about taking a year off and going in Thailand. I even thought that would be not so hard to just do some small contract work and just linger there for some time. Then I thought about trying to get a PhD in social science. Social is the new cool thing today Smile. Oh, and speaking about social, I experimented also with social gaming but it didn’t took off. Not because the idea was not good but the team I joined then was more oriented to dreaming that to execution. Which made me think that the essential thing when you do a start-up is execution. More than a good idea.

Luckily I continued doing small consulting work cause I got bored in the afternoons (mornings were occupied by gym workouts with my back as the main beneficiary). And in one summer day a guy came to me wanting some custom Flex components. It sounded like fun as 20 years ago I started programming trying to do graphic things … on Z80 processors Smile. Working on these graphical components woke up the little geek in me. The other geeky part for this was that these components were designed to be used for visualizing data from Building Automation Systems. This gadget thing was another passion of my childhood. I still remember how I was trying to build a microphone out of a graphite bar and two razor blades.

The next thing I know was that after two months of crazy hacking I jumped into a plane to Los Angeles to meet the guy and I think it was an instant chemistry Smile. I found that this chemistry thing is important when you work with somebody. Another two months of hacking and here I am totally sold to the idea and I am about to open an office here in Romania (I am very reluctant leaving this country … although everybody tells me to do so) and start moving the hacking to a new level Smile. The company is called J2 Innovative Concepts and we are building some sort of a Visual Basic for devices (as I like to call it).

So I promise you to keep posting new technical stuff while I build the “next big thing”. I still do a lot of Air and Flash but now I look how I can make these technologies to be the front-end of microcontrollers, sensors and other geeky stuff Smile

What can I say, it seems that at least for me nothing beats hacking when it comes to fill a boring summer afternoon.

Categories: Uncategorized Tags:

Using Illustrator, Flash Catalyst and Flash Builder to create an avatar widget

February 6th, 2010 1 comment

bmw_z1Since I have a little more spare time now … I decided to hack a little bit :) . Avatar is the new hype nowadays :) and I wanted to understand how simple (or how complicated) will be to build an avatar widget. So I gave it a try, but instead of a Na’vi avatar, I decided to apply some artwork on top of an BMW Z1 :) .

I’ve made a video with my little workflow that you can watch it here (I couldn’t believe how easy it was).

You can also see the running demo (and download the source files) here.

Moving on

January 30th, 2010 9 comments

Yep, I decided to leave Adobe and move on. Last year the Adobe evangelist team got restructured, I ended up working in engineering and finally got a little time to breathe. I mean evangelism was a hell of a ride for an ‘introverted geek’ and it stretched me to the limit. But I must admit that I loved doing this … well maybe except the crazy traveling.

One Sunday morning I woke up, sat on the edge of my bed and asked myself: “Now WHAT?”. I realized that I really love coding but I also like giving presentations, teaching and what you can generally call ‘knowledge transfer’ activities … and I like also the business side of the technology too. Thus the engineering side only filled up half of it … maybe a little more cause I really love coding :) .

So I decided to stop, take a break (as I realized that I’ve spent none of my last year’s legal holidays) and look for a new challenge. That’s because I just couldn’t come up with a good answer to the “now what?” question and I realized that I might need to do some experiments to find out.

Categories: thinking Tags:

Enterprise RIA = Transport Tycoon

October 7th, 2009 No comments

I’ve just saw one of the coolest application ever at the MAX Day 2 Keynote. You might think that it’s something about entertainment or a new tweeter thing :) . Well no, the coolest application I’ve seen in a while was actually a business application. FedEx built an app to monitor critical packages (like artwork or cryogenic stuff). And it looks like Transport Tycoon if you remember the old game. You can manage a whole fleet using an app that looks very much like a strategy game. Only that this is for real, with real stuff, real events and real money. Who would have believed 10-15 years ago that the strategy games we played will become the management tools of today. Now I realize that this is not just the RIA and Flex. It’s about building a large interactive system, with sensors,
geolocation, all the hardware and the communication infrastructure. Flex and LCDS was only the cherry on top of the whole thing. I think these kinds of applications are way beyond “cool”. You can really feel the difference that these systems bring in productivity and eventually in our life. I wish we had such applications internally at Adobe :D . Watch out for the MAX Day 2 video, which should be posted soon on AdobeTV.

Categories: Uncategorized Tags:

Hard Play – No Flash on the iPhone – yet…

October 6th, 2009 9 comments

Last night Adobe announced Flash Player 10.1, which will support a lot of devices including Windows Mobile, Symbian, Android and WebOS (you can find more details in the official press release).
Sounds cool except of course … there is no iPhone there?

I am wondering why that is and what is Apple’s strategy? Everywhere I go people ask me, When will you guys be releasing Flash for iPhone? Why are you not releasing Flash for iPhone? And I don’t know what to tell you, but from what it seems Adobe is going for every smart phone out there. I mean there has been only fingerpointing so far: Apple saying Flash is not good enough, Adobe saying it is and now is delivering it for every other smart-phone.

Now I am wondering what Apple’s strategy is about that. I mean currently let’s face it: iPhone is by far the only significant smart phone out there with a design that was really innovative not only from the hardware point of view. The whole iPhone business ecosystem was way far ahead anything any competitor had put up forward.

But once Apple “got it right” now the spell is broken. Now, the entire industry not only knows what customers want, they are pressured to deliver it fast if they want to still be in this business 5-10 years from now. I think the whole game will change now into a long slog, a down in the trenches fight between Apple and the other big phone hardware manufacturers and telecom operators. Why do I think it will be a long slog? Well Apple did a big blow in the phone market with iPhone but I don’t think they will get 30% of the smart phones market very soon. And even if they get it I doubt that Apple will get 80% of the mobile phone market. And I don’t think they want it. Apple’s strategy is to get the most profitable 10-20% segment of the market, after that the profitability drops and it doesn’t look that nice.

Now back to the trenches. By leaving Flash out of the iPhone, Apple is keeping iPhone out of Flash and it’s betting on its own API to deliver applications and RIAs (I doubt they will adopt Silverlight :) ). With Flash and Silverlight pushing hard for all other smart-phones (which by the way are getting cooler and cooler) I expect that pretty soon they will get to be quite popular. So if Apple insists on using its own API, it will make application development for their platform expensive. If you have the coolest phone put out there, this makes perfect sense. But if the other phone manufacturers get their act together they will soon bridge that gap. With Flash, and soon AIR, support they will be able to reuse development skills and even running code to get people to make applications for their platforms. By making development more expensive on iPone than for the other platforms, Apple will position iPhone as a niche product. This clearly is not a mainstream strategy and playing the niche market with iPhone is a tricky strategy. And with Flash Player 10.1 on all the other phones, it kinda makes iPhone look a little strange because you can’t play video on it.

I wonder what Apple’s move or statement will be especially now that you will be able to compile Flash applications to get them run as native apps on the iPhone.

 

 

Categories: ria, thinking Tags:

Data-Centric Development with Flash Builder 4 @MAX

August 19th, 2009 1 comment

These days I’ve worked to finish my Max BYOL (Bring Your Own Laptop) lab. It’s about how you can easily develop data-centric front ends using the new data features in Flash Builder 4. I will be presenting this lab together with Enrique Duvos.

In this 90-min hands-on lab you will be building data-driven front ends that connect to either PHP, Java or ColdFusion … yeah we prepared materials for all these back-ends. I can’t wait to see how this will work live.

Plus you will add some advanced pieces of functionality like paging through large record-sets and client-side data management. If I got you interested then you can already  book your place in the room using Adobe MAX scheduler.

And if you have not registered yet for MAX, please take a look at the following two entries from Andrew Shorten and Serge Jespers. There are great discounts available!!!

Categories: Uncategorized Tags:

Skinning a list in Flex 4 – Magnifier Effect

August 16th, 2009 8 comments

Here’s a little video about how to use different Spark components to make a magnifier effect for a list. To create this effect I did the following:

  • used the Spark Component model with Skins and States
  • employed the new Spark item renderer that support Designer/Developer workflow
  • Parametrize Spark Skins with CSS

You can download the final project from here and watch the video here.


Categories: flex, video Tags:

Integrating PayPal Express Checkout with AIR and Flex

July 30th, 2009 1 comment

This article continues the series about integrating Flex and AIR with payment gateway services. Parts of this article are very similar with the other posts about this subject:
Integrating PayPal Express Checkout with Flex(which I recommend reading before this article),Using Amazon Flexible Payment System with Flex and Using Amazon Flexible Payment System with Flex & AIR.

I will focus mainly on how to take the PayPal + Flex workflow (described here) out of the browser and into an AIR application.

Although AIR applications run on the desktop and the local security constraints are different from those in the browser, from a payment gateway point of view things don’t change at all. As a result, we can conclude that because AIR is a client technology hardcoding sensitive information into an AIR app is highly insecure (even though the code is compiled into bytecode). This means that any credential related info (like API_USERNAME, API_PASSWORD and API_SIGNATURE) should NOT be stored in the AIR application.

Architectural Approach and UI solutions

Summing this up, our architectural solution has to comply with some concurrent demands:

  • an AIR front-end that is stateful and is built following the single page app paradigm
  • the need for security that requires that the AIR app should NOT deal with PayPal API credentials
  • The payment workflow has a part that is hosted on the PayPal servers and that is a standard request-response web application

In order to address these I propose the following approach:

  • all PayPal API calls should be done on the server side so that API credentials will be protected
  • the access to the PayPal web application should be done in a browser page. IMPORTANT SECURITY NOTE: Although technically it might be possible to use the HTML container of the AIR runtime this is an unsecure practice because the end user cannot visually verify that he is entering his credentials on the PayPal site. In the browser he can check the URL and the security certificate.

So the buyer workflow becomes:

  1. (Step 1) Chooses to checkout using PayPal in the AIR application (Security Note: Starting from this point it is mandatory that all requests are done through https)
  2. (Step 2) Sees a browser window open and logs into PayPal to authenticate his/her identity
  3. (Step 3) Reviews the transaction on PayPal
  4. (Step 4) Confirms the order and pays from your site
  5. (Step 5) Reviews the order confirmation on your site
  6. (Step 6) Returns to the AIR application

 

Calling the PayPal part of the checkout process

So the PayPal workflow should be open in a browser window. Here is how to do that in the AIR app:

var url:URLRequest = new URLRequest(URL_ROOT + "/payPalAIR/startPaymentFlex.php");
url.data = new URLVariables();
var obj:URLVariables = new URLVariables();
url.data.movieId = '1';
url.data.paymentReason = 'Enter The Matrix';
url.method = "GET";

navigateToURL(url, "new");
currentState='Wait';

Everything else is pretty similar with how you call the PayPal workflow from a Flex app.

Returning from PayPal and notifying the AIR application

Here again we follow an approach similar with how you return from PayPal to a Flex application (Step 4 and Step 5).

The only thing that differs is how we get back to the AIR application (Step 6). ExternalInterface is not suited for this job but we can use instead the LocalConnection to make the browser application communicate with the AIR one. LocalConnection, while being more secure than ExternalIterface, can still be exploited using techniques like DNS rewriting so we can’t pass sensitive information through it. Furthermore, since the AIR app is independent from the browser this means that our browser app has a different server session than the AIR App. So a simple notification is not enough: we need to also pass the session id. This is not sensitive information, but it will allow the AIR application to retrieve from the server any sensitive information that the browser application has set.

Let’s take a look on what we need to do right after we call the PAY operation in our return page. In the transaction detail page we will link to a little Flex application that will only communicate with the AIR application. We can use this little application to also forward the error and cancel messages. We will call it using an anchor parameter:

<a class="home" id="CallsLink" href="payPalAIRReturn.html#method=doStatus">Return to AIR</a>

This little application will only contain some code that will get the cookie string from the browser (remember we need this to make the AIR application connect to the same server session) and send a message through LocalConnection to the AIR application:

private var outbound:LocalConnection = new LocalConnection();
protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
	var browserManager:IBrowserManager = BrowserManager.getInstance();
	browserManager.init();
	var urlObj:Object = URLUtil.stringToObject(browserManager.fragment);
	if (urlObj.method) {
		//get the cookie string
		ExternalInterface.call('eval','window.cookieStr = function () {return document.cookie};')
			var cookieStr:String = ExternalInterface.call('cookieStr');
		outbound.connect("paymentSample");
		outbound.send("app#payPalAIR:paymentSample",urlObj.method,cookieStr);
		outbound.close();
	}
}

Please notice that when launching from Flex Builder the AIR Application has no Publisher ID so the connection name is “app#payPalAIR:paymentSample”. After packaging and installation the AIR app will get a Publisher ID so the connection name becomes something like this: app#payPalAIR.F0B3F68E1857B8A07069FED1D0638CAF200F76EB.1:paymentSample

You can get the publisher ID of the installed AIR app by looking at the META-INF/AIR/publisherid file within the application install directory.

Back in the AIR application we need to expose the functions through local connection:

private function initApp():void {
	//only allow connections from localhost
	//you need to replace "localhost" with the final domain
	//where your application will be hosted
	inbound.allowDomain("localhost");
	inbound.client = new Object();
	//this is the function that will be called by the Browser App
	inbound.client.doStatus = doStatus;
	inbound.client.doError = doError;
	inbound.client.doCancel = doCancel;

	//inbound.client.
	inbound.connect("paymentSample");

}

All methods (doStatus, do Error and doCancel) will receive the cookie string as a parameter. In do Status we need to check the transaction status on the server:

private function doStatus(cookieStr:String):void {
	var srv:HTTPService = new HTTPService();
	srv.headers.Cookie = cookieStr;
	srv.url = URL_ROOT + "/payPalAIR/getPaymentStatus.php";
	srv.addEventListener(ResultEvent.RESULT,function (event:ResultEvent):void {

		Alert.show(event.result.status.type);
		nativeApplication.activate();
		if (event.result.status.type == 'SUCCESS') {
			currentState = 'Succes';
		} else {
			currentState = 'Fail';
		}
	});
	srv.addEventListener(FaultEvent.FAULT,function (event:FaultEvent):void {
		nativeApplication.activate();
		currentState = 'Fail';
		Alert.show(event.message.toString());
	});
	srv.send();
}

where getPaymentStatus.php is just a simple page that gets the status from the session and serialize it in a simple XML format:

<?php
session_start();
?>
<status>
	<type><?php echo strtoupper ($_SESSION ['reshash'] ["ACK"] ) ?></type>
</status>

Installing the sample files

  1. In Flash Builder click File->Import .. and choose Flash Builder Project
  2. Choose payPalAIR.fxp
  3. Unzip payPalAIR.zip into your Web Root folder (For example: /work/www).
  4. Edit payPalAIR/ppNVP/constants.php and replace
  5. define('API_USERNAME', 'sdk-three_api1.sdk.com');
    define('API_PASSWORD', 'QFZCWN5HZM8VBG7Q');
    define('API_SIGNATURE', 'A.d9eRKfd1yVkRrtmMfCFLTqa6M9AyodL0SJkhYztxUi8W9pCXF6.4NI');
    

    with your ownPayPal API_USERNAME, API_PASSWORD and API_SIGNATURE

  6. In Flash Builder click File->Import … and choose Flash Builder Project.
  7. Choose payPalAIRReturn.fxp
  8. Fill the Output Folder Location (this one should point to where you have unzipped payPalAIR.zip, in your web root), Web Root and Root URL with your values. It should look something like this:


Categories: air, flex, payment gateways, tutorials Tags:

Using Amazon Flexible Payment System with Flex & AIR

July 26th, 2009 2 comments

I’ve already talked about using Flex with Amazon FPS, so now let’s see what is involved in taking this out of the browser into an AIR app. I recommend reading that article before reading this one, since many of the security considerations described there in detail are valid for AIR applications also. In this article I will only highlight the differences between building a Flex application that runs in the browser and one that runs on the desktop.

Although AIR applications run on the desktop and the local security constraints are different from those in the browser, from a payment gateway point of view things don’t change at all. As a result, we can conclude that because AIR is a client technology hardcoding sensitive information into an AIR app is highly insecure (even though the code is compiled into bytecode). This means that any signature related computation should NOT be made in AIR and the Amazon Secret Key should NOT under any circumstance be put into an AIR App.

Architectural Approach and UI solutions

Summing this up, our architectural solution has to comply with two concurrent demands:

  • an AIR front-end that is stateful and is built following the single page app paradigm
  • the security need that the AIR app should NOT deal with Amazon Security Key plus the need to go to the Amazon co-branded page to authenticate the users
    In order to address these I propose the following approach:

  • All payment related processing should be done on the server side to protect the Amazon Secret Key. Of course this means that the AIR app must be on-line when the payment takes place.
  • The access to the co-branded page should be done in a browser page. IMPORTANT SECURITY NOTE:  Although technically it might be possible to use the HTML container of the AIR runtime this is an unsecure practice because the end user cannot visually verify that he is entering his credentials on the Amazon site. In the browser he can check the URL and the security certificate.

Calling the Amazon Co-Branded User Interface

So the Amazon co-branded UI should be open in a browser window. Here is how to do that in the AIR app.

var url:URLRequest = new URLRequest("http://localhost/amazonAIR/startPayment.php");
url.data = new URLVariables();
var obj:URLVariables = new URLVariables();
url.data.movieId = 1;
url.data.paymentReason = 'Enter The Matrix';
url.method = "GET";
navigateToURL(url, "new");

Everything else is pretty similar with how you call the Amazon co-branded UI from a Flex app that runs in the browser.

Exactly the same goes with returning from Amazon and making the Pay request.

Using LocalConnection to notify the AIR App

The only thing left now is to notify the AIR application and bring it to front.

To do that we need to communicate between the browser app and the AIR app. In order to achieve this we can use the LocalConnection mechanism. LocalConnection objects can communicate among files that are running on the same client computer, but they can be running in different applications — for example, a file running in a browser and a SWF file running in Adobe AIR.

Now there is one important thing to remember about LocalConnection. It can be tricked using techniques like DNS rewriting. So we will not pass any sensitive information through LocalConnection. However, since the AIR app is independent from the browser this means that our browser app has a different server session than the AIR App. So a simple notification is not enough, we need to also pass the session id. This is not sensitive information, but it will allow the AIR application to retrieve from the server any sensitive information that the browser application has set.

Let’s take a look what we need to do right after the return.php page made the PAY operation.

For simplicity the returnAir.php page will have a link to a little Flex app that will communicate with the AIR app. All it needs to do is to get the cookie information and send it through LocalConnection to the AIR app:

private var outbound:LocalConnection = new LocalConnection();

private function gotoAIR():void {
	//get the cookie string
	ExternalInterface.call('eval','window.cookieStr = function () {return document.cookie};')
	var cookieStr:String = ExternalInterface.call('cookieStr');

	outbound.connect("paymentSample");
	outbound.send("app#amazonAIR:paymentSample","notifyPayment",cookieStr);
	//outbound.send("app#testAmazonAir.F0B3F68E1857B8A07069FED1D0638CAF200F76EB.1:paymentSample","notifyPayment",cookieStr);
	outbound.close();
}

Please notice that when launching from Flex Builder the AIR Application has no Publisher ID so the connection name is “app#amazonAIR:paymentSample”. After packaging and installation the AIR app will get a Publisher ID so the connection name becomes something like this: app#amazonAIR.F0B3F68E1857B8A07069FED1D0638CAF200F76EB.1:paymentSample

You can get the publisher ID of the installed AIR App by looking at the META-INF/AIR/publisherid file within the application install directory.

Back in our AIR app we need to expose a function to be available on LocalConnection.

//This will be used by return.php to notify the AIR App
//that the payment has been made
private var inbound:LocalConnection = new LocalConnection();

private function initApp():void {
	//only allow connections from localhost
	//you need to replace "localhost" with the final domain
	//where your application will be hosted
	inbound.allowDomain("localhost");
	inbound.client = new Object();
	//this is the function that will be called by the Browser App
	inbound.client.notifyPayment = paymentNotification;
	inbound.connect("paymentSample");
}

Where paymentNotification is a function that receives the cookie string as parameters and queries the server to check the transaction status:

public function paymentNotification(cookieStr:String):void {
	var srv:HTTPService = new HTTPService();
	srv.headers.Cookie = cookieStr;
	srv.url = "http://localhost/amazonAIR/paymentStatus.php";
	srv.addEventListener(ResultEvent.RESULT,function (event:ResultEvent):void {
		nativeApplication.activate();
		if (event.result.status == 'OK') {
			currentState = 'Succes';
		} else {
			currentState = 'Fail';
		}
	});
	srv.send();
}

Installing the sample files

  1. In Flash Builder click File->Import .. and choose Flash Builder Project
  2. Choose AmazonAIR.fxp
  3. Unzip amazonAIR.zip into your Web Root folder (For example: /work/www).
  4. Edit amazonAIR/amazon-fps/src/Amazon/FPS/Samples/.config.inc.php and replace
  5. define('AWS_ACCESS_KEY_ID', 'YOUR ACCESS KEY');
    define('AWS_SECRET_ACCESS_KEY', 'YOUR SECRET ACCESS KEY');
    

    with your own Amazon ACCESS key and SECRET_ACCESS_KEY.

  6. In Flash Builder click File->Import … and choose Flash Builder Project.
  7. Choose amazonAIRReturn.fxp
  8. Fill the Output Folder Location (this one should point to where you have unzipped amazonAIR.zip, in your web root), Web Root and Root URL with your values. It should look something like this:

Categories: air, flex, payment gateways, tutorials Tags:

The infamous Error #2044: Unhandled StatusEvent:. level=error, code= on LocalConnection

July 24th, 2009 1 comment

This is a blog post to all that was almost to throw their computers out of the window because they got "Error #2044: Unhandled StatusEvent:. level=error, code=" trying to communicate through LocalConnection.

So I am trying to send a message from a Flex application running in Flash Player to an AIR application. In the AIR application (called testAIR) I have something like:

private function initApp():void {
	var inbound:LocalConnection = new LocalConnection();
	//only allow connections from localhost
	inbound.allowDomain("localhost");
	inbound.client = new Object();
	//this is the function that will be called by the Browser App
	inbound.client.notifyPayment = function test():void {
		Alert.show("HERE");
	};
	inbound.connect("paymentSample");
}

pretty straightforward, right from the book.

In the Flex app I just do:

outbound.connect("paymentSample");
outbound.send("app#testAIR:paymentSample","notifyPayment");
outbound.close();

You might think that this should work. Well … NOT.  This is because in the AIR app the inbound LocalConnection is a variable that is declared in the local scope of a method. Now I was expecting that when I call  the connect method the inbound object will be referenced by another object (some LocalConnection manager, or event handler) and it will not get garbage collected after the method ends. Well, apparently is not the case. Either there is a bug in AIR, either this reference is a weak reference so it gets garbage collected. This means that by the time you try to send the message from Flash Player your inbound object is long gone!

The resolution is quite simple. You just need to reference the inbound object somewhere else, making him a member of class or something. In my case I just declare it as a private variable inside my MXML component:

private var inbound:LocalConnection = new LocalConnection();

private function initApp():void {
	//only allow connections from localhost
	inbound.allowDomain("localhost");
       ....

Hope this will help someone :)

Categories: Flash Player 10, flex, tips & tricks Tags: