You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ma...@apache.org on 2014/03/16 22:52:46 UTC
git commit: [flex-sdk] [refs/heads/develop] - COMPLETE - FLEX-33949:
Manage OS version in @media CSS - Now X.Y.Z version is supported is
os-version media selector - Computes version for Android devices. so now the
follow media query works: @media (os-
Repository: flex-sdk
Updated Branches:
refs/heads/develop 1da2381b2 -> d67e20c04
COMPLETE - FLEX-33949: Manage OS version in @media CSS
- Now X.Y.Z version is supported is os-version media selector
- Computes version for Android devices.
so now the follow media query works:
@media (os-platform: "android") AND (min-os-version: "4.1.2") {
/* JELLY BEAN SKINS */
}
Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/d67e20c0
Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/d67e20c0
Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/d67e20c0
Branch: refs/heads/develop
Commit: d67e20c04e6c262630e5ac91a76bdc784bb2e143
Parents: 1da2381
Author: mamsellem <ma...@systar.com>
Authored: Sun Mar 16 22:51:36 2014 +0100
Committer: mamsellem <ma...@systar.com>
Committed: Sun Mar 16 22:51:36 2014 +0100
----------------------------------------------------------------------
.../framework/src/mx/utils/MediaQueryParser.as | 219 +++++++++++++------
.../projects/framework/src/mx/utils/Platform.as | 131 ++++++++---
.../src/MobileComponentsClasses.as | 2 +
.../src/MobileComponentsClassesAIR2.as | 1 +
.../supportClasses/ViewNavigatorBase.as | 9 +
.../src/spark/utils/PlatformMobileHelper.as | 74 +++++++
6 files changed, 341 insertions(+), 95 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/d67e20c0/frameworks/projects/framework/src/mx/utils/MediaQueryParser.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/framework/src/mx/utils/MediaQueryParser.as b/frameworks/projects/framework/src/mx/utils/MediaQueryParser.as
index 55dcadd..ea1e1d6 100644
--- a/frameworks/projects/framework/src/mx/utils/MediaQueryParser.as
+++ b/frameworks/projects/framework/src/mx/utils/MediaQueryParser.as
@@ -31,6 +31,12 @@ use namespace mx_internal;
* Parser for CSS Media Query syntax. Not a full-fledged parser.
* Doesn't report syntax errors, assumes you have your attributes
* and identifiers spelled correctly, etc.
+ * Media query parser now supports os-version selectors such as X, X.Y or X.Y.Z
+ * Note that version with 3 parts must be quoted
+Examples:
+ (os-platform: "ios") AND (min-os-version: 7)
+ (os-platform: "android") AND (min-os-version: "4.1.2")
+
*
* @langversion 3.0
* @playerversion Flash 10.2
@@ -103,7 +109,7 @@ public class MediaQueryParser
applicationDpi = moduleFactory.info()["applicationDPI"];
}
osPlatform = getPlatform();
- osVersion = getOSVersion(osPlatform);
+ osVersion = getOSVersion();
}
/**
@@ -291,49 +297,52 @@ public class MediaQueryParser
// break into two pieces
var parts:Array = expr.split(":");
+ var key: String = parts[0];
var min:Boolean = false;
var max:Boolean = false;
// look for min
- if (parts[0].indexOf("min-") == 0)
+ if (key.indexOf("min-") == 0)
{
min = true;
- parts[0] = parts[0].substr(4);
+ key = key.substr(4);
}
// look for max
- else if (parts[0].indexOf("max-") == 0)
+ else if (key.indexOf("max-") == 0)
{
max = true;
- parts[0] = parts[0].substr(4);
+ key = key.substr(4);
}
// collapse hypens into camelcase
- if (parts[0].indexOf("-") > 0)
- parts[0] = deHyphenate(parts[0]);
+ if (key.indexOf("-") > 0)
+ key = deHyphenate(key);
// if only one part, then it only matters that this property exists
if (parts.length == 1)
{
- if (!(parts[0] in this))
+ if (!(key in this))
return false;
}
// if two parts, then make sure the property exists and value matches
if (parts.length == 2)
{
// if property doesn't exist, then bail
- if (!(parts[0] in this))
+ if (!(key in this))
return false;
+ var value: Object = normalize(parts[1], this[key]) ;
+ var cmp: int = compareValues(this[key], value) ;
// handle min (we don't check if min is allowed for this property)
if (min)
{
- if (this[parts[0]] < normalize(parts[1], typeof(this[parts[0]])))
- return false;
+ if (cmp < 0)
+ return false;
}
// handle max (we don't check if min is allowed for this property)
else if (max)
{
- if (this[parts[0]] > normalize(parts[1], typeof(this[parts[0]])))
+ if (cmp > 0)
return false;
}
// bail if the value doesn't match
- else if (this[parts[0]] != normalize(parts[1], typeof(this[parts[0]])))
+ else if (cmp != 0)
{
return false;
}
@@ -344,8 +353,9 @@ public class MediaQueryParser
return true;
}
- // strip off metrics (maybe convert metrics some day)
- private function normalize(s:String, type:String):Object
+ // strip off unit if currentValue is Number or int
+ // now supports versions (X.Y.Z) and numbers with units
+ private function normalize(s:String, currentValue: Object ):Object
{
var index:int;
@@ -356,7 +366,7 @@ public class MediaQueryParser
// for the numbers we currently handle, we
// might find dpi or ppi on it, that we just strip off.
// We don't handle dpcm yet.
- if (type == "number")
+ if (currentValue is Number)
{
index = s.indexOf("dpi");
if (index != -1)
@@ -365,25 +375,51 @@ public class MediaQueryParser
}
return Number(s);
}
- else if (type == "int")
+ else if (currentValue is int)
{
return int(s);
}
- else if (type == "string")
+ // string or CSS value
+ // strip quotes of strings
+ if (s.indexOf('"') == 0) {
+ if (s.lastIndexOf('"') == s.length - 1)
+ s = s.substr(1, s.length - 2);
+ else
+ s = s.substr(1);
+ }
+ // string , return
+ if (currentValue is String)
{
- // strip quotes of strings
- if (s.indexOf('"') == 0)
- {
- if (s.lastIndexOf('"') == s.length - 1)
- s = s.substr(1, s.length - 2);
- else
- s = s.substr(1);
- }
+ return s;
+ }
+ else if (currentValue is CssOsVersion) {
+ return new CssOsVersion(s) ;
}
-
return s;
}
-
+
+ /** @private
+ * Compares current value with test values, using currentValue type to determine comparison function
+ * accepts number, int, string and CssOsVersion.
+ * Will accept LexicalUnit in the future
+ *
+ * @param currentValue
+ * @param testValue
+ * @return -1 if currentValue < testValue, 1 if currentValue > testValue and 0 if equal
+ */
+ private function compareValues ( currentValue: Object, testValue: Object): int
+ {
+ if (currentValue is CssOsVersion)
+ return CssOsVersion(currentValue).compareTo(CssOsVersion(testValue)) ;
+ else // scalar compare operators
+ if ( currentValue == testValue)
+ return 0;
+ else if ( currentValue < testValue)
+ return -1;
+ else
+ return 1;
+ }
+
// collapse "-" to camelCase
private function deHyphenate(s:String):String
{
@@ -415,45 +451,10 @@ public class MediaQueryParser
}
/** @private
- * extract OS version information from os
- * os is typically a non-numeric string (such as Windows, iPhone OS, Android, etc...) followed by a number.
- * if no number is found, OS version is set to 0.
- * os on ADL will return the host OS and not the device OS.
- * That why we need to check for a specific sequence for iOS and Android
+ * returns a CssOsVersion suitable for MediaQueryParser for the current device operating system version.
* */
- private function getOSVersion(osPlatform:String):Number {
- //TODO (mamsellem) retrieve os version for Android, reading system/build.prop
- var os: String = Capabilities.os;
- var osMatch: Array;
-
- if (osPlatform == "ios")
- {
- osMatch = os.match(/iPhone OS\s([\d\.]+)/);
- }
- else
- {
- osMatch = os.match(/[A-Za-z\s]+([\d\.]+)/);
- }
-
- return osMatch ? convertVersionStringToNumber(osMatch[1]) : 0.0;
- }
-
- /** @private converts string version such as "X" or "X.Y" or "X.Y.Z" into a number.
- * minor version parts are normalized to 100 so that eg. X.1 < X.10
- * so "7.1" return 7.01 and "7.12" return 7.12
- */
- private function convertVersionStringToNumber(versionString: String): Number
- {
- var versionParts: Array = versionString.split(".");
- var version: Number = 0;
- var scale: Number = 1;
-
- for each (var part: String in versionParts) {
- version += Number(part) * scale;
- scale /= 100;
- }
-
- return version;
+ private function getOSVersion():CssOsVersion {
+ return new CssOsVersion(Platform.osVersion) ;
}
// the type of the media
@@ -466,8 +467,92 @@ public class MediaQueryParser
public var osPlatform:String;
// the platform os version of the media
- public var osVersion: Number;
+ public var osVersion: CssOsVersion;
}
+}
+
+/**
+ * Support class for MediaQueryParser to store and compare versions such as X.Y.Z
+ * Its mainly used in os-version media selector.
+ */
+internal class CssOsVersion
+{
+ /* separator between version parts*/
+ private static const SEPARATOR: String = ".";
+ /** Contructor
+ * Returns an CssOsVersion with the
+ * @param versionString
+ */
+ public function CssOsVersion(versionString: String = "")
+ {
+ var versionParts: Array = versionString.split(SEPARATOR);
+ var l: int = versionParts.length;
+ if (l >= 1)
+ major = Number(versionParts[0]);
+ if (l >= 2)
+ minor = Number(versionParts[1]);
+ if (l >= 3)
+ revision = Number(versionParts[2]);
+ // ignore remaining parts
+ }
+
+ /**
+ * major figure of the version.
+ */
+ public var major: int = 0;
+ /**
+ * minor figure of the version.
+ */
+ public var minor: int = 0;
+ /**
+ * revision figure of the version.
+ */
+ public var revision: int = 0;
+
+ /**
+ * Printable string of the version, as X.Y.Z
+ * @return version as a string
+ */
+ public function toString(): String
+ {
+ return major.toString() + SEPARATOR + minor.toString() + SEPARATOR + revision.toString();
+ }
+
+ /**
+ * Compares to another version.
+ *
+ * @param other Second Version.
+ *
+ * @return 0 if both versions are equal
+ * -1 if <code>this</code> is lower than <code>otherVersion</code>.
+ * 1 if <code>this</code> is greater than <code>otherVersion</code>.
+ * @langversion 3.0
+ * @productversion Flex 4.13
+ */
+ public function compareTo(otherVersion: CssOsVersion): int
+ {
+ if (major > otherVersion.major)
+ return 1;
+ else if (major < otherVersion.major)
+ return -1;
+ else //major == other.major)
+ {
+ if (minor > otherVersion.minor)
+ return 1;
+ else if (minor < otherVersion.minor)
+ return -1;
+ else //minor == other.minor)
+ {
+ if (revision > otherVersion.revision)
+ return 1;
+ else if (revision < otherVersion.revision)
+ return -1;
+ else
+ return 0; // all equal
+ }
+ }
+ }
}
+
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/d67e20c0/frameworks/projects/framework/src/mx/utils/Platform.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/framework/src/mx/utils/Platform.as b/frameworks/projects/framework/src/mx/utils/Platform.as
index 494b83c..9f3cd26 100644
--- a/frameworks/projects/framework/src/mx/utils/Platform.as
+++ b/frameworks/projects/framework/src/mx/utils/Platform.as
@@ -19,11 +19,12 @@
package mx.utils
{
-
+
import flash.system.Capabilities;
+import flash.utils.getDefinitionByName;
/**
- * The Platform utility class constain several static methods to check what
+ * The Platform utility class contains several static methods to check what
* desktop or mobile platform the application is running on.
*
* @langversion 3.0
@@ -34,8 +35,10 @@ import flash.system.Capabilities;
public class Platform
{
include "../core/Version.as";
+
+ private static var _instance: Platform;
- protected static var _initilised:Boolean;
+ protected static var _initialized:Boolean;
protected static var _isAndroid:Boolean;
protected static var _isIOS:Boolean;
protected static var _isIPad:Boolean;
@@ -47,9 +50,10 @@ public class Platform
protected static var _isDesktop:Boolean;
protected static var _isBrowser:Boolean;
protected static var _isAir:Boolean;
+ private static var _osVersion: String = null;
/**
- * Returns true if the applciation is runing on IOS.
+ * Returns true if the application is running on IOS.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -64,8 +68,8 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on an iPad.
- * Note this returns false in the mobile device simulator.
+ * Returns true if the application is running on an iPad.
+ * Note this returns false in the AIR mobile device simulator.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -80,7 +84,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on a BlackBerry.
+ * Returns true if the application is running on a BlackBerry.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -95,7 +99,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on Android.
+ * Returns true if the application is running on Android.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -110,7 +114,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on Windows.
+ * Returns true if the application is running on Windows.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -125,7 +129,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on a Mac.
+ * Returns true if the application is running on a Mac.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -140,7 +144,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on Linux.
+ * Returns true if the application is running on Linux.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -155,7 +159,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on a Desktop OS.
+ * Returns true if the application is running on a Desktop OS.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -170,7 +174,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on a Mobile device.
+ * Returns true if the application is running on a Mobile device.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -185,7 +189,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing on a desktop AIR.
+ * Returns true if the application is running on a desktop AIR.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -200,7 +204,7 @@ public class Platform
}
/**
- * Returns true if the applciation is runing in a browser.
+ * Returns true if the application is running in a browser.
*
* @langversion 3.0
* @playerversion Flash 10
@@ -213,27 +217,98 @@ public class Platform
return _isBrowser;
}
-
+
+ /**
+ * Returns the version of the OS the application is running on
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.0
+ * @productversion Flex 4.13
+ */
+ public static function get osVersion(): String
+ {
+ //We needed to compute _osVersion later than getPlatforms, because it relies on resources that ready later
+ if (_osVersion == null){
+ _osVersion = computeOSVersionString();
+ }
+ return _osVersion;
+ }
+
+ /* Notes on Capabilities.os for mobile apps:
+ - on ADL => returns the OS where the ADL is running ( eg. Windows 7, or Mac OS )
+ - on device => returns the OS of the device (eg. iPhone OS ... for iOS devices )
+ * */
protected static function getPlatforms():void {
- if (!_initilised)
+ if (!_initialized)
{
- _isAndroid = Capabilities.version.indexOf("AND") > -1;
- _isIOS = Capabilities.version.indexOf('IOS') > -1;
- _isBlackBerry = Capabilities.version.indexOf('QNX') > -1;
+ var cap: Class = Capabilities;
+ var version: String = Capabilities.version;
+ var os: String = Capabilities.os;
+ var playerType: String = Capabilities.playerType;
+
+ _isAndroid = version.indexOf("AND") > -1;
+ _isIOS = version.indexOf('IOS') > -1;
+ _isBlackBerry = version.indexOf('QNX') > -1;
_isMobile = _isAndroid || _isIOS || _isBlackBerry;
- _isMac = Capabilities.os.indexOf("Mac OS") != -1;
- _isWindows = Capabilities.os.indexOf("Windows") != -1;
- _isLinux = Capabilities.os.indexOf("Linux") != -1; // note that Android is also Linux
- _isIPad = Capabilities.os.indexOf('iPad') > -1;
+ _isMac = os.indexOf("Mac OS") != -1;
+ _isWindows = os.indexOf("Windows") != -1;
+ _isLinux = os.indexOf("Linux") != -1; // note that Android is also Linux
+ _isIPad = os.indexOf('iPad') > -1;
_isDesktop = !_isMobile;
- _isAir = Capabilities.playerType == "Desktop";
- _isBrowser = (Capabilities.playerType == "Plugin" || Capabilities.playerType == "ActiveX");
+ _isAir = playerType == "Desktop";
+ _isBrowser = (playerType == "Plugin" || playerType == "ActiveX");
- _initilised = true;
+ _initialized = true;
}
}
-}
+ /** @private
+ * extract OS version information from Capabilities.os
+ * os is typically a non-numeric string (such as Windows, iPhone OS, Android, etc...) followed by a number sequence.
+ * if no number is found, OS version is set to 0.
+ * os on ADL will return the host OS and not the device OS.
+ *
+ * That's why we need to check for a specific sequence for iOS and Android.
+ * On Android, os is the Linux kernel version (such as Linux 3.4.34-1790463).
+ * So the version information must be retrieved from an internal file.
+ * Since reading files API is only available on AIR, it's delegated to PlatformMobileHelper in mobilecomponents.swc
+ * @see spark.utils.PlatformMobileHelper
+ *
+ * @return version number string, or empty string if could not retrieve the version.
+ * */
+ private static function computeOSVersionString(): String
+ {
+ var os: String = Capabilities.os;
+ var osVersionMatch: Array;
+ var version: String = "";
+
+ if (isIOS) {
+ osVersionMatch = os.match(/iPhone OS\s([\d\.]+)/);
+ if (osVersionMatch && osVersionMatch.length == 2)
+ version = osVersionMatch[1];
+ }
+ else if (isAndroid) {
+ try {
+ var mobileHelperClass: Class = Class(getDefinitionByName("spark.utils::PlatformMobileHelper"));
+ if (mobileHelperClass != null) {
+ version = mobileHelperClass["computeOSVersionForAndroid"]();
+ }
+ }
+ catch (e: Error) {
+ trace("Error: " + e.message);
+ }
+ }
+ else {
+ //on other OS, extract version
+ osVersionMatch = os.match(/[A-Za-z\s]+([\d\.]+)/);
+ if (osVersionMatch && osVersionMatch.length == 2)
+ version = osVersionMatch[1];
+ }
+ return version;
+ }
+
+}
}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/d67e20c0/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as b/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as
index bde526a..677324a 100644
--- a/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as
+++ b/frameworks/projects/mobilecomponents/src/MobileComponentsClasses.as
@@ -31,6 +31,8 @@ internal class MobileComponentsClasses
* For example, Button does not have a reference to ButtonSkin,
* but ButtonSkin needs to be in framework.swc along with Button.
*/
+
+ import spark.utils.PlatformMobileHelper; PlatformMobileHelper;
import spark.preloaders.SplashScreen; SplashScreen;
import spark.components.supportClasses.StyleableStageText; StyleableStageText;
import spark.components.supportClasses.ScrollableStageText; ScrollableStageText;
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/d67e20c0/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as b/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as
index d5468cd..7c0fec6 100644
--- a/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as
+++ b/frameworks/projects/mobilecomponents/src/MobileComponentsClassesAIR2.as
@@ -34,5 +34,6 @@ internal class MobileComponentsClassesAIR2
import spark.preloaders.SplashScreen; SplashScreen;
import spark.components.supportClasses.StyleableTextField; StyleableTextField;
import spark.components.ActionBarDefaultButtonAppearance; ActionBarDefaultButtonAppearance;
+ import spark.utils.PlatformMobileHelper; PlatformMobileHelper;
}
}
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/d67e20c0/frameworks/projects/mobilecomponents/src/spark/components/supportClasses/ViewNavigatorBase.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/components/supportClasses/ViewNavigatorBase.as b/frameworks/projects/mobilecomponents/src/spark/components/supportClasses/ViewNavigatorBase.as
index 857f97a..4421498 100644
--- a/frameworks/projects/mobilecomponents/src/spark/components/supportClasses/ViewNavigatorBase.as
+++ b/frameworks/projects/mobilecomponents/src/spark/components/supportClasses/ViewNavigatorBase.as
@@ -35,6 +35,7 @@ import mx.utils.DensityUtil;
import spark.components.SkinnableContainer;
import spark.components.View;
import spark.utils.MultiDPIBitmapSource;
+import spark.utils.PlatformMobileHelper;
use namespace mx_internal;
@@ -91,6 +92,14 @@ public class ViewNavigatorBase extends SkinnableContainer
// Variables
//
//--------------------------------------------------------------------------
+
+ /**
+ * @private this is to force inclusion by dependency of PlatformMobileHelper in the final application swf ,
+ * as it's only accessed by QName from framework's mx.utils.Platform class.
+ * We use ViewNavigatorBase as the referring class because it's always included in a mobile application.
+ * Note that including PlatformMobileHelper in MobileComponentClasses only ensures that its included in mobilecomponents.swc
+ */
+ private static const __includeClasses: Array = [ PlatformMobileHelper];
/**
* @private
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/d67e20c0/frameworks/projects/mobilecomponents/src/spark/utils/PlatformMobileHelper.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/mobilecomponents/src/spark/utils/PlatformMobileHelper.as b/frameworks/projects/mobilecomponents/src/spark/utils/PlatformMobileHelper.as
new file mode 100644
index 0000000..8f99eb8
--- /dev/null
+++ b/frameworks/projects/mobilecomponents/src/spark/utils/PlatformMobileHelper.as
@@ -0,0 +1,74 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.utils
+{
+import flash.filesystem.File;
+import flash.filesystem.FileMode;
+import flash.filesystem.FileStream;
+
+/** @private
+ * Helper class for computing device -dependent platform capabilities.
+ * This class should not be used directly.
+ */
+
+public class PlatformMobileHelper
+{
+ /** Function to retrieve OS version string on Android devices, in X.Y.Z format.
+ * On Android, Capabilities.os contains the Linux kernel version (such as Linux 3.4.34-1790463), not the Android version.
+ * So the version information must be retrieved from an internal file: <code> /system/build.prop</code>
+ * as <code>ro.build.version.release</code> property value.
+ *
+ * @return the OS version as "X.Y.Z" string, or "" (empty string) if not found.
+ *
+ * @see mx.utils.Platform
+ *
+ * @langversion 3.0
+ * @playerversion AIR 2.0
+ * @productversion Flex 4.13
+ */
+ public static function computeOSVersionForAndroid(): String
+ {
+ var version: String = "";
+
+ var file: File = new File();
+ var fs: FileStream = new FileStream();
+ file.nativePath = "/system/build.prop";
+ if (file.exists) {
+ try {
+ var osVersionMatch: Array;
+ fs.open(file, FileMode.READ);
+ var content: String = fs.readUTFBytes(file.size);
+ osVersionMatch = content.match(/ro.build.version.release=([\d\.]+)/);
+ if (osVersionMatch && osVersionMatch.length == 2)
+ version = osVersionMatch[1];
+ }
+ catch (e: Error) {
+ // trace the error, and return empty string
+ trace("Error while reading build.prop file:" + e.message);
+ }
+ finally {
+ if (fs)
+ fs.close();
+ }
+ }
+ return version;
+ }
+}
+}