From 570e6d3b7d1fbed84d8eb4856dbf31c6bfcfef9c Mon Sep 17 00:00:00 2001 From: Markus Birth Date: Sun, 22 Feb 2015 21:32:56 +0100 Subject: [PATCH] Added various posts. --- assets/genapidoc.py | 153 ++ assets/titanium.js | 2306 +++++++++++++++++ assets/tmobile_germany.ipcc | Bin 0 -> 6670 bytes .../_posts/2009-04-26-flash-in-safari.md | 19 + .../_posts/2009-05-16-appulous.md | 32 + .../_posts/2009-05-24-firmware-unpacking.md | 136 + .../_posts/2009-05-27-crashing-apps.md | 20 + .../_posts/2009-05-30-google-calendars.md | 33 + .../_posts/2009-06-20-carrier-settings.md | 69 + .../_posts/2009-06-20-hidden-features.md | 91 + .../_posts/2009-08-01-firmware-3-beta.md | 96 + .../apple-iphone/_posts/2009-11-30-emojis.md | 41 + .../_posts/2010-03-30-iphone-vs-android.md | 36 + .../_posts/2010-04-02-develop-apps.md | 39 + .../2010-05-17-airvideo-server-linux.md | 83 + .../2010-06-08-appcelerator-titanium.md | 91 + 16 files changed, 3245 insertions(+) create mode 100644 assets/genapidoc.py create mode 100644 assets/titanium.js create mode 100644 assets/tmobile_germany.ipcc create mode 100644 know-how/hardware/apple-iphone/_posts/2009-04-26-flash-in-safari.md create mode 100644 know-how/hardware/apple-iphone/_posts/2009-05-16-appulous.md create mode 100644 know-how/hardware/apple-iphone/_posts/2009-05-24-firmware-unpacking.md create mode 100644 know-how/hardware/apple-iphone/_posts/2009-05-27-crashing-apps.md create mode 100644 know-how/hardware/apple-iphone/_posts/2009-05-30-google-calendars.md create mode 100644 know-how/hardware/apple-iphone/_posts/2009-06-20-carrier-settings.md create mode 100644 know-how/hardware/apple-iphone/_posts/2009-06-20-hidden-features.md create mode 100644 know-how/hardware/apple-iphone/_posts/2009-08-01-firmware-3-beta.md create mode 100644 know-how/hardware/apple-iphone/_posts/2009-11-30-emojis.md create mode 100644 know-how/hardware/apple-iphone/_posts/2010-03-30-iphone-vs-android.md create mode 100644 know-how/hardware/apple-iphone/_posts/2010-04-02-develop-apps.md create mode 100644 know-how/hardware/apple-iphone/_posts/2010-05-17-airvideo-server-linux.md create mode 100644 know-how/software/_posts/2010-06-08-appcelerator-titanium.md diff --git a/assets/genapidoc.py b/assets/genapidoc.py new file mode 100644 index 0000000..5f3739f --- /dev/null +++ b/assets/genapidoc.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import json +import re +import sys + +class JSDocGen: + def __init__( self, apifile, prefix ): + self.jsonfile = apifile + self.indent = 0 + self.indentstring = " " + jf = open( apifile, "r" ) + self.json = json.load( jf ) + jf.close() + self.parse( self.json, prefix, True ) + + def p( self, str, end=None ): + indent = self.indentstring * self.indent + print( indent + str, end=end ) + + def getTypeExample( self, type ): + if type == "string": + return "''" + elif type == "boolean" or type == "bool": + return "true" + elif type == "Object" or type == "object": + return "new Object()" + elif type == "list": + return "[]" + elif type == "double": + return "0.0" + return "0" # default to int + + def parseProperty( self, name, obj, isLast ): + print() + self.p( "/**" ) + if "description" in obj: + self.p( " * %s" % obj["description"] ) + + if "type" in obj: + type = obj["type"] + else: + type = "undefined" + + if name == name.upper(): + self.p( " * @constant" ) + self.p( " * @final" ) + + if "since" in obj: + self.p( " * @since %s" % obj["since"] ) + + self.p( " */" ) + dummyvalue = self.getTypeExample( type ) + self.p( "%s: %s" % ( name, dummyvalue ), end="" ) + if not isLast: + print( "," ) # we don't want indentation here + else: + print() # we don't want indentation here + + def getJSType( self, type ): + if type == "string" or type == "String": + return "String" + elif type == "bool" or type == "boolean": + return "bool" + elif type == "int" or type == "integer": + return "int" + elif type == "double": + return "double" + elif type == "list" or type == "array": + return "Array" + elif type == "method" or type == "function": + return "Function" + elif type == "object" or type == "args" or type == "options" or type == "Object" or type == "hash": + return "Object" + elif type == "contact": + return "Titanium.Contacts.Contact" + print( "WARNING: Type %s may be no valid JavaScript type." % type, file=sys.stderr ) + return type + + def parseMethod( self, name, obj, isLast ): + print() + self.p( "/**" ) + if "description" in obj: + self.p( " * %s" % obj["description"] ) + + args = [] + if "arguments" in obj: + for a in obj["arguments"]: + self.p( " * @param %s (%s) %s" % ( a["name"], self.getJSType( a["type"] ), a["description"] ) ) + args.append( a["name"] ) + args = ", ".join( args ) + if "returns" in obj and obj["returns"] is not None: + self.p( " * @return (%s) %s" % ( self.getJSType( obj["returns"]["type"] ), obj["returns"]["description"] ) ) + self.p( " */" ) + + self.p( "%s: function(%s) { }" % ( name, args ), end="" ) + #self.p( "}", end="" ) + if not isLast: + print( "," ) # we don't want indentation here + else: + print() # we don't want indentation here + + def cleanObject( self, obj ): + for k in [ "deprecated", "description", "name", "object", "platforms", "property", "since", "method", "arguments", "returns" ]: + if k in obj: + del obj[k] + return obj + + def parseObject( self, name, obj, isLast ): + obj = self.cleanObject( obj ) # remove all properties which do not belong to the object + + if name == "Titanium": + self.p( "%s = {" % ( name ) ) # root element + else: + self.p( "%s: {" % ( name ) ) + + self.indent += 1 + subitems = len( obj ) + ctr = 0 + for subname, sub in obj.items(): + ctr += 1 + lastone = False + if ( ctr == subitems ): + lastone = True + self.parse( sub, subname, lastone ) + self.indent -= 1 + self.p( "}", end="" ) + if isLast and self.indent == 0: + print( ";" ) # we don't want indentation here + print( "Ti = Titanium;" ) # copy object to alias + elif not isLast: + print( "," ) # we don't want indentation here + else: + print() # do newline only + + def parse( self, jsonobj, name, isLast ): + if "property" in jsonobj or "method" in jsonobj and not "object" in jsonobj: + if "property" in jsonobj and jsonobj["property"]: + # Property / Constant + self.parseProperty( name, jsonobj, isLast ) + elif "method" in jsonobj and jsonobj["method"]: + # Function / Method + self.parseMethod( name, jsonobj, isLast ) + else: + print( "!!! UNKNOWN TYPE for %s !!!" % name, file=sys.stderr ) + else: + # Object + self.parseObject( name, jsonobj, isLast ) + + +if __name__=="__main__": + jsd = JSDocGen( "apicoverage.json", "Titanium" ) diff --git a/assets/titanium.js b/assets/titanium.js new file mode 100644 index 0000000..ed11310 --- /dev/null +++ b/assets/titanium.js @@ -0,0 +1,2306 @@ +/** + * @package Titanium + * @namespace Global Titanium namespace + */ +Titanium = { + /** + * Titanium platform name property. For iPhone, the value is 'iphone' (regardless of version). For Android, the value is 'android'. + * @since 0.4 + */ + 'platform': 'iphone', + + /** + * Titanium platform version property. This is the version/build of the Titanium Mobile SDK you're using. + * @since 0.4 + */ + 'version': '0.8.0' +}; + +/** + * @package Titanium + * @subpackage Platform + */ +Titanium.Platform = { + /** + * IP address if any. [read-only] + * The primary IP address of the system. + * @since 0.4 + */ + 'address': '192.168.1.1', + + /** + * CPU description [read-only] + * The operating system architecture. + * @since 0.4 + */ + 'architecture': 'i386', + + /** + * Available memory as reported by the VM. [read-only] + * Memory availible on the system. + * @since 0.4 + */ + 'availableMemory': 1243.93359375, + + /** + * Display metrics. [read-only] + * Array containing keys: width, height, density, dpi. + * @since 0.8 + */ + 'displayCaps': { + 'width': 320, + 'height': 480, + 'density': 'low', + 'dpi': 160 + }, + + /** + * Device identifier [read-only] + * The unique machine id of the system. + * @since 0.4 + */ + 'id': '00000000-0000-1000-8000-DEADCAFEBABE', + + /** + * MAC address if any. [read-only] + * The primary MAC address of the system. + * @since 0.4 + */ + 'macaddress': 'DE:AD:CA:FE:BA:BE', + + /** + * Model identifier of the device [read-only] + * The model name of the device. + * @since 0.4 + */ + 'model': 'Simulator', + + /** + * Platform name [read-only] + * The operating system name. + * @since 0.4 + */ + 'name': 'iPhone OS', + + /** + * OS type [read-only] + * The architecture type of the system (either 32 bit or 64 bit). + * @since 0.4 + */ + 'ostype': '32bit', + + /** + * Number of processors as reported by device. [read-only] + * The number of processors for the machine. + * @since 0.4 + */ + 'processorCount': 1, + + /** + * Name of user. [read-only] + * The platform's user name. + * @since 0.4 + */ + 'username': 'iPhone Simulator', + + /** + * Platform version information [read-only] + * The operating system version. + * @since 0.4 + */ + 'version': '3.0', + + /** + * Creates a globally unique id + */ + 'createUUID': function() { }, + + /** + * A developer helper method to see installed applications. This api will most likely be replaced in the future. It should not be used in production. + * @deprecated + * @since 0.4 + */ + 'logInstalledApplicationNames': function() { }, + + /** + * Launch an Android application use the helper method {@link #logInstalledApplicationNames} to discover applications. + * @param {String} app Android application name + * @return {Boolean} true if application was launched. + * @since 0.4 + */ + 'openApplication': function( app ) { }, + + /** + * Launch the system browser + * Opens a URL in the default system browser. + * @param {String} url url to open + * @return {Boolean} true if browser was launched + * @since 0.4 + */ + 'openURL': function( url ) { } +}; + +/** + * @package Titanium + * @subpackage Network + */ +Titanium.Network = { + + /** + * The network connection is a LAN. + * Indicates that there is an ethernet or wired network present. + * @constant + * @final + * @since 0.4 + */ + 'NETWORK_LAN': 1, + + /** + * The network connection is Mobile. + * Indicates that there is either an EDGE or 3G network present. + * @constant + * @final + * @since 0.4 + */ + 'NETWORK_MOBILE': 2, + + /** + * No network connection. + * Indicates that there is no network present. + * @constant + * @final + * @since 0.4 + */ + 'NETWORK_NONE': 0, + + /** + * The network type is unknown. + * Indicates that there is a network, but its nature is unknown. + * @constant + * @final + * @since 0.4 + */ + 'NETWORK_UNKNOWN': -1, + + /** + * The network connection is WIFI. + * Indicates that there is a WiFi network present. + * @constant + * @final + * @since 0.4 + */ + 'NETWORK_WIFI': 3, + + /** + * The current network connection type. + * The kind of network that the device is connected to. + * @since 0.4 + */ + 'networkType': 0, + + /** + * The current network connection type. + * The human-readable name of kind of network that the device is connected to. + * @since 0.4 + */ + 'networkTypeName': 'WiFi', + + /** + * Examine connectivity state. + * Whether or not the system is connected to the internet. + * @since 0.4 + */ + 'online': true, + + /** + * Not supported in android. Use addEventListener. + * Adds a connectivity change listener that fires when the system connects or disconnects from the internet. + * @since 0.4 + */ + 'addConnectivityListener': function() { }, + + /** + * Register an event handler for connectivity events. + * @param {String} eventName Must be 'connectivity'. Only event currently supported. + * @param {function} listener function to receive notification of network connectivity changes. + * @return {Number} an id used to remove the event listener. + * @since 0.4 + */ + 'addEventListener': function( eventName, listener ) { }, + + /** + * Create an HTTPClient object. + * Creates an HTTPClient object. You can only create one HTTPClient object per window, + * so if you want to do multiple requests you'll need to reuse the same instance. + * Also, since the request is asynchronous, if you depend on the result of the first + * call to use in the second, you'll need to chain the calls together so that they + * happen in sequence. + * @return {Titanium.Network.HTTPClient} the HTTP client + * @since 0.4 + */ + 'createHTTPClient': function() { }, + + /** + * URL Decode + * Decodes a URI component. + * @param {String} fragment The fragment to URL decode + * @return {String} the decoded fragment + * @since 0.4 + */ + 'decodeURIComponent': function( fragment ) { }, + + /** + * URL Encode + * Encodes a URI Component. + * @param {String} fragment URL fragment to encode + * @return {String} the encoded fragment + * @since 0.4 + */ + 'encodeURIComponent': function( fragment ) { }, + + /** + * Not supported in android. Use removeEventListener. + * Removes a connectivity change listener. + * @since 0.4 + */ + 'removeConnectivityListener': function() { }, + + /** + * RemoveEventListener + * @param {String} eventName The event name used to register for an event. + * @param {Number} listenerId The id returned by addEventListener + * @since 0.4 + */ + 'removeEventListener': function( eventName, listenerId ) { } + +}; + +/** + * @package Titanium + * @subpackage Network + */ +Titanium.Network.HTTPClient = { + /** + * Receive data as a blob a chunk at a time. + * The handler function that will be fired as stream data is received from an HTTP request. + * @since 0.7 + */ + 'ondatastream': null, + + /** + * Set or get the error handler. + * This error handler will not be called if the HTTP request succeeds but does not return + * a 2xx status code. For catching and dealing with non-2xx HTTP status codes, use + * Titanium.Network.HTTPClient.onload and Titanium.Network.HTTPClient.getStatus(). + * @since 0.8 + */ + 'onerror': null, + + /** + * Set or get the onload handler. + * The handler function that will be fired when the ready-state code of an HTTPClient + * object changes to ready state (DONE) + * @since 0.7 + */ + 'onload': null, + + /** + * Set or get the ready stage change handler. + * The handler function that will be fired when the ready-state code of an HTTPClient + * object changes. + * @since 0.4 + */ + 'onreadystatechange': null, + + /** + * Get the current ready state. + * The ready-state status for the connection. + * @since 0.4 + */ + 'readyState': 0, + + /** + * Get the response as XML from the operation. + * The response of an HTTP request as text. + * @since 0.7 + */ + 'responseText': '', + + /** + * Get the response as blob. + * @since 0.7 + */ + 'responseXML': '', + + /** + * Get the status code of the request. + * The response status code of an HTTP request. + * @since 0.4 + */ + 'status': 0, + + /** + * Get the status text of the request. + * @since 0.4 + */ + 'statusText': '', + + /** + * Aborts an in progress connection. + * @since 0.4 + */ + 'abort': function() { }, + + /** + * Get all response headers. + * @return Array headers + * @since 0.4 + */ + 'getAllResponseHeaders': function() { return new Array(); }, + + /** + * The state of the network operation. + * @return int current operation state + * @since 0.4 + */ + 'getReadyState': function() { return 0; }, + + /** + * The response of an HTTP request as blob. + * @return blob the response text + * @since 0.7 + */ + 'getResponseData': function() { return ''; }, + + /** + * Get the value of a response header. + * Returns the value of a response header. + * @param header (string) Name of header value to retrieve + * @return string the value + * @since 0.4 + */ + 'getResponseHeader': function( header ) { return ''; }, + + /** + * The response of an HTTP request as text. + * @return string the response text + * @since 0.4 + */ + 'getResponseText': function() { return ''; }, + + /** + * The response status code of an HTTP request. + * @return int the response status code + * @since 0.4 + */ + 'getStatus': function() { return 0; }, + + /** + * The response status text of an HTTP Request. + * @return string the response string + * @since 0.4 + */ + 'getStatusText': function() { return ''; }, + + /** + * Open an HTTP connection. + * @param method (string) HTTP method (GET, POST, HEAD) + * @param url (string) Url to perform method on + * @since 0.4 + */ + 'open': function( method, url ) { }, + + /** + * Send data through the HTTP connection. + * @param data (string) zero or more data segments to transmit. + * @since 0.4 + */ + 'send': function( data ) { }, + + /** + * Set a function to be called when the ready state changes same as onreadystatechange property. + * @param f (function) callback for ready state change events + * @since 0.4 + */ + 'setOnReadyStateChange': function( f ) { }, + + /** + * Set a request header for the connection. + * @param name (string) header name + * @param value (string) value to associate with header + * @since 0.4 + */ + 'setRequestHeader': function( name, value ) { } +}; + +/** + * @package Titanium + * @subpackage API + */ +Titanium.API = { + /** + * Log data at the CRITICAL level. + * logs an object with severity "critical" + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'critical': function( msg ) { }, + + /** + * Log data at the DEBUG level. + * logs an object with severity "debug" + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'debug': function( msg ) { }, + + /** + * Log data at the ERROR level. + * logs an object with severity "error" + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'error': function( msg ) { }, + + /** + * Log data at the FATAL level. + * logs an object with severity "fatal" + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'fatal': function( msg ) { }, + + /** + * Log data at the INFO level. + * logs an object with severity "info" + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'info': function( msg ) { }, + + /** + * Log data to the console. + * writes information to the console log/STDERR + * @param severity (int) Severity code from FATAL down to TRACE + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'log': function( severity, msg ) { }, + + /** + * Log data at the NOTICE level. + * logs an object with severity "notice" + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'notice': function( msg ) { }, + + /** + * Log data at the TRACE level. + * logs an object with severity "trace" + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'trace': function( msg ) { }, + + /** + * Log data at the WARN level. + * logs an object with severity "warn" + * @param msg (string) Message to send to the console + * @since 0.4 + */ + 'warn': function( msg ) { } +}; + +/** + * @package Titanium + * @subpackage Accelerometer + */ +Titanium.Accelerometer = { + /** + * Listen for events from the accelerometer. + * add an event listener to be called for a accelerometer event and returns the function to use when removing + * @param eventName (string) The name of the event. This API supports 'update' events. + * @param listener (function) Function that receives an event object on each update. + * @return int id to pass to removeEventListener to cancel the event + * @since 0.4 + */ + 'addEventListener': function( eventName, listener ) { return 0; }, + + /** + * Remove a listener previously set with addEventListener. + * removes an event listener from Accelerometer events. + * @param eventName (string) Name of the event used to register in addEventListener + * @param listenerId (int) Value returned from addEventListener + * @since 0.4 + */ + 'removeEventListener': function( eventName, listenerId ) { } +}; + +/** + * @package Titanium + * @subpackage Analytics + */ +Titanium.Analytics = { + /** + * Send an analytics event associated with the application. + * @param {String} evtType event type + * @param {String} evtName event name + * @param {Object} [data] event data (optional) + * @since 0.4 + */ + 'addEvent': function( evtType, evtName, data ) { }, + + /** + * Send an application feature event. + * @param event (string) name of the event + * @param data (Object) data to send with the event (optional) + * @since 0.7 + */ + 'featureEvent': function( event, data ) { }, + + /** + * Send an application nav event. + * @param from (string) The from string + * @param to (string) The to string + * @param event (string) name of the event (optional) + * @param data (Object) data to send with the event (optional) + * @since 0.7 + */ + 'navEvent': function( from, to, event, data ) { }, + + /** + * Send an application settings event. + * @param event (string) name of the event + * @param data (Object) data to send with the event (optional) + * @since 0.7 + */ + 'settingsEvent': function( event, data ) { }, + + /** + * Send an application timed event. + * @param event (string) name of the event + * @param start (Date) Start date (optional) + * @param stop (Date) End date (optional) + * @param duration (string) duration in seconds (optional) + * @param data (Object) data to send with the event (optional) + * @since 0.7 + */ + 'timedEvent': function( event, start, stop, duration, data ) { }, + + /** + * Send an application user event. + * @param event (string) name of the event + * @param data (Object) data to send with the event (optional) + * @since 0.7 + */ + 'userEvent': function( event, data) { } +}; + +/** + * @package Titanium + * @subpackage App + */ +Titanium.App = { + /** + * Get url for file under Resources. + * get a full path from an application using app: URL + * @param url (string) path portion of the url. + * @return string full url including path. On Android this will normally prefix with file:///android_asset/ + * @since 0.4 + */ + 'appURLToPath': function( url ) { return ''; }, + + /** + * Not implemented yet. + * get a dictionary of application launch arguments or null if none + * @return Object empty object + * @since 0.8 + */ + 'getArguments': function() { return new Object(); }, + + /** + * Get application copyright. + * get the application copyright + * @return string application copyright as stored in tiapp.xml + * @since 0.4 + */ + 'getCopyright': function() { return ''; }, + + /** + * Get description of application. + * get the application description + * @return string description of application as stored in tiapp.xml + * @since 0.4 + */ + 'getDescription': function() { return ''; }, + + /** + * Get the application's globally unique id. + * @return string global unique id as stored in tiapp.xml + * @since 0.4 + */ + 'getGUID': function() { return ''; }, + + /** + * Get the application id. + * @return string the id as stored in tiapp.xml + * @since 0.4 + */ + 'getID': function() { return ''; }, + + /** + * Get the name of the application. + * @return string the name as stored in tiapp.xml + * @since 0.4 + */ + 'getName': function() { return ''; }, + + /** + * Get the publisher. + * get the application publisher + * @return string the publisher name as stored in tiapp.xml + * @since 0.4 + */ + 'getPublisher': function() { return ''; }, + + /** + * Not implemented yet. + * @param stream (string) deploytype (TBD) + * @return string url for analytics + * @since 0.4 + */ + 'getStreamURL': function( stream ) { return ''; }, + + /** + * Get the url to application's external website. + * @return string url to external website as stored in tiapp.xml + * @since 0.4 + */ + 'getURL': function() { return ''; }, + + /** + * Get the application version. + * @return string the application version as stored in tiapp.xml + * @since 0.4 + */ + 'getVersion': function() { return ''; }, + + /** + * Used to control automatic execution of triggerLoad. + * @param load (bool) if true, automatically call triggerLoad. + * @since 0.4 + */ + 'setLoadOnPageEnd': function( load ) { }, + + /** + * (Internal, Android only) Method to signal switching to the webView in the activity. + * Normally called automatically when the page end event fires. + * @since 0.4 + */ + 'triggerLoad': function() { } +}; + +/** + * @package Titanium + * @subpackage App + */ +Titanium.App.Properties = { + /** + * Retrieve a boolean property. + * get value as boolean + * @param name (string) property name + * @param def (bool) default value if no value set for key in name + * @return bool property value or default + * @since 0.4 + */ + 'getBool': function( name, def ) { return true; }, + + /** + * Retrieve a double property. + * get value as double + * @param name (string) property name + * @param def (double) default value if no value set for key in name + * @return double property value or default + * @since 0.4 + */ + 'getDouble': function( name, def ) { return 0.0; }, + + /** + * Retrieve an integer property. + * get value as integer + * @param name (string) property name + * @param def (int) default value if no value set for key in name + * @return int property value or default + * @since 0.4 + */ + 'getInt': function( name, def ) { return 0; }, + + /** + * Retrieve a list. + * get value as a list + * @param name (string) property name + * @param def (list) default value if no value set for key in name + * @return list property value or default + * @since 0.7 + */ + 'getList': function( name, def ) { return []; }, + + /** + * Retrieve a string property. + * get value as string + * @param name (string) property name + * @param def (string) default value if no value set for key in name + * @return string property value or default + * @since 0.4 + */ + 'getString': function( name, def ) { return ''; }, + + /** + * Detect existence of a property. + * check to see if a property exists + * @param name (string) property name + * @return bool true if property with 'name' exists. + * @since 0.7 + */ + 'hasProperty': function( name ) { return true; }, + + /** + * Retrieve a list of property names. + * get a list of property values + * @return list list of property names + * @since 0.7 + */ + 'listProperties': function() { return []; }, + + /** + * Remove a property. + * @param name (string) property name + * @since 0.7 + */ + 'removeProperty': function( name ) { }, + + /** + * Store a boolean property. + * @param name (string) property name + * @param value (bool) property value + * @since 0.4 + */ + 'setBool': function( name, value ) { }, + + /** + * Store an integer property. + * @param name (string) property name + * @param value (int) property value + * @since 0.4 + */ + 'setInt': function( name, value ) { }, + + /** + * Store a list of JSON'able objects. + * @param name (string) property name + * @param value (list) value to store + * @since 0.7 + */ + 'setList': function( name, value ) { }, + + /** + * Store a string property. + * @param name (string) property name + * @param value (string) property value + * @since 0.4 + */ + 'setString': function( name, value ) { } +}; + +/** + * @package Titanium + * @subpackage App + */ +Titanium.App.SystemProperties = { + /** + * Retrieve a boolean property. + * @param name (string) property name + * @param def (bool) default value if no value set for key in name + * @return bool property value or default + * @since 0.4 + */ + 'getBool': function( name, def ) { return true; }, + + /** + * Retrieve a double property. + * @param name (string) property name + * @param def (double) default value if no value set for key in name + * @return double property value or default + * @since 0.4 + */ + 'getDouble': function( name, def ) { return 0.0; }, + + /** + * Retrieve an integer property. + * @param name (string) property name + * @param def (int) default value if no value set for key in name + * @return int property value or default + * @since 0.4 + */ + 'getInt': function( name, def ) { return 0; }, + + /** + * ??? + */ + 'getList': function( name ) { }, + + /** + * Retrieve a string property. + * @param name (string) property name + * @param def (string) default value if no value set for key in name + * @return (string) property value or default + * @since 0.4 + */ + 'getString': function( name, def ) { return ''; }, + + /** + * Detect existence of a property. + * @param name (string) property name + * @return bool true if property with 'name' exists. + * @since 0.7 + */ + 'hasProperty': function( name ) { return true; }, + + /** + * Retrieve a list of property names. + * @return list list of property names + * @since 0.7 + */ + 'listProperties': function() { return []; }, + + /** + * Store a boolean property. + * @param name (string) property name + * @param value (bool) property value + * @since 0.4 + */ + 'setBool': function( name, value ) { }, + + /** + * Store an integer property. + * @param name (string) property name + * @param value (int) property value + * @since 0.4 + */ + 'setInt': function( name, value ) { }, + + /** + * Store a list of JSON'able objects. + * @param name (string) property name + * @param value (list) value to store + * @since 0.7 + */ + 'setList': function( name, value ) { }, + + /** + * Store a string property. + * @param name (string) property name + * @param value (string) property value + * @since 0.4 + */ + 'setString': function( name, value ) { } +}; + +/** + * @package Titanium + * @subpackage Database + */ +Titanium.Database = { + /** + * Install and opens a database. + * Install (if not already installed) and opens a database. + * @param filename (string) Path to existing sqlite database file + * @param name (string) Name of the database. On Android it must not contain path elements. + * @return Titanium.Database.DB a database object, used to interact with the database + * @since 0.8 + */ + 'install': function( filename, name ) { return new Titanium.Database.DB(); }, + + /** + * Opens a database. + * @param name (string) Name of the database. On Android it must not contain path elements. + * @return Titanium.Database.DB a database object, used to interact with the database + * @since 0.4 + */ + 'open': function( name ) { return new Titanium.Database.DB(); } +}; + +/** + * @package Titanium + * @subpackage Database + */ +Titanium.Database.DB = { + /** + * Same as getLastInsertRowId method. + * the id of the last of rows affected by the last execute + * @since 0.4 + */ + 'lastInsertRowId': 0, + + /** + * Same as getRowsAffected method. + * the number of rows affected by the last execute + * @since 0.4 + */ + 'rowsAffected': 0, + + /** + * Close the database. This should be called to prevent resource leaks. + * close an open database + * @since 0.4 + */ + 'close': function() { }, + + /** + * Perform an operation on the database. + * perform a command on a database + * @param sql (string) the SQL text. Multiple statements, separated by semi-colons, are not supported on Android. + * @param args (mixed) one or more arguments appearing after the sql parameter. Must be integer, float, string, or any data converted to string (optional) + * @return Titanium.Database.ResultSet + * @since 0.4 + */ + 'execute': function( sql, args) { return new Titanium.Database.ResultSet(); }, + + /** + * The row id of the last insert operation. + * convenience method for lastInsertRowId + * @return int The id. + * @since 0.4 + */ + 'getLastInsertRowId': function() { return 0; }, + + /** + * The number of rows affected by the last operation. + * convenience method for rowsAffected + * @return int the affected row count. + * @since 0.4 + */ + 'getRowsAffected': function() { return 0; }, + + /** + * Remove this database from the device. This is a destructive operation. + * remove a database + * @since 0.4 + */ + 'remove': function() { } +}; + +/** + * @package Titanium + * @subpackage Database + */ +Titanium.Database.ResultSet = { + /** + * Close an open ResultSet. Should be called to prevent resources from leaking. + * Releases the state associated with the result set + * @since 0.4 + */ + 'close': function() { }, + + /** + * Retrieve the data from a column on the current row. + * Returns the contents of the specified field in the current row + * @param index (int) The zero-based index of the column to retrieve. + * @return string The contents of the column. + * @since 0.4 + */ + 'field': function( index) { return ''; }, + + /** + * Retrieve the contents of a column on the current row using the column name. + * Returns the contents of the specified field in the current row using the name of the field as an identifier + * @param fieldName (string) the column name + * @return string the contents of the column. + * @since 0.4 + */ + 'fieldByName': function( fieldName ) { return ''; }, + + /** + * The number of columns in each row of the current ResultSet. + * Returns the number of fields of the result set + * @return int the number of columns + * @since 0.4 + */ + 'fieldCount': function() { return 0; }, + + /** + * The name of the field at the given column position. + * Returns the name of the specified field in the current result set taken from the SQL statement which was executed + * @param index (int) the zero-based index + * @return string the column name + * @since 0.4 + */ + 'fieldName': function( index ) { return ''; }, + + /** + * The number of rows in the ResultSet. Previously rowCount(). + * @return int the row count + * @since 0.8 + */ + 'getRowCount': function() { return 0; }, + + /** + * Used to determine if operations may be peformed on this row. + * Checks whether you can call data extraction methods + * @return bool True, if it is safe to operate on the row. + * @since 0.4 + */ + 'isValidRow': function() { return true; }, + + /** + * Move to the next row in the ResultSet. + * @return bool True, if the move was successful. + * @since 0.4 + */ + 'next': function() { return true; }, + + /** + * The number of rows in the ResultSet. + * Returns the number of rows of the result set + * @return int the row count + * @since 0.4 + * @deprecated + */ + 'rowCount': function() { } +}; + +/** + * @package Titanium + * @subpackage Filesystem + */ +Titanium.Filesystem = { + /** + * Flag for opening in append mode. + * @constant + * @final + * @since 0.7 + */ + 'MODE_APPEND': 0, + + /** + * Flag for opening in read mode. + * @constant + * @final + * @since 0.7 + */ + 'MODE_READ': 1, + + /** + * Flag for opening in write mode. + * @constant + * @final + * @since 0.7 + */ + 'MODE_WRITE': 2, + + /** + * Creates a temporary directory. + * @return (Titanium.Filesystem.File) a File object referencing a temporary directory. + * @since 0.4 + */ + 'createTempDirectory': function() { return new Titanium.Filesystem.File(); }, + + /** + * Creates a temporary file. + * @return (Titanium.Filesystem.File) a File object referencing a temporary file. + * @since 0.4 + */ + 'createTempFile': function() { return new Titanium.Filesystem.File(); }, + + /** + * Returns a file object pointing to the application's on device data directory. + * @return (Titanium.Filesystem.File) the file object to the application data directory + * @since 0.4 + */ + 'getApplicationDataDirectory': function() { return new Titanium.Filesystem.File(); }, + + /** + * Returns a file object pointing to the application's off device data directory. + * @return (Titanium.Filesystem.File) the file object to the application mass data directory + * @since 0.7.2 + */ + 'getApplicationMassDataDirectory': function() { return new Titanium.Filesystem.File(); }, + + /** + * Returns a file path, optionally joining multiple arguments together in an OS specific way. + * @param arguments (string) one or more path segments to join + * @return (Titanium.Filesystem.File) a File reference the file + * @since 0.4 + */ + 'getFile': function( arguments ) { return new Titanium.Filesystem.File(); }, + + /** + * Returns a file stream, optionally joining multiple arguments together in an OS specific way. + * @param arguments (string) one or more path segments to join + * @return (Titanium.Filesystem.Filestream) a FileStream reference the file + * @since 0.4 + */ + 'getFileStream': function( arguments ) { return new Titanium.Filesystem.Filestream(); }, + + /** + * Returns the line ending for this system. + * @return (string) the end of line character(s) + * @since 0.4 + */ + 'getLineEnding': function() { return ''; }, + + /** + * Returns a file object pointing to the application's Resources. + * @return (Titanium.Filesystem.File) the file object to the application Resources directory + * @since 0.4 + */ + 'getResourcesDirectory': function() { return new Titanium.Filesystem.File(); }, + + /** + * Returns the PATH separator for this system. + * @return (string) the PATH separator + * @since 0.4 + */ + 'getSeparator': function() { return ''; }, + + /** + * Check to see if external media storage exists. + * @return (bool) true if external storage is present; otherwise, false. + * @since 0.4 + */ + 'isExternalStoragePresent': function() { return false; } +}; + +/** + * @package Titanium + * @subpackage Filesystem + */ +Titanium.Filesystem.File = { + /** + * Copies a file to a specified location. + * @param destination (string) destination to copy to + * @return (bool) true if the file was successfully copied; otherwise false. + * @since 0.4 + */ + 'copy': function( destination ) { return true; }, + + /** + * Creates a new directory. + * @since 0.4 + */ + 'createDirectory': function() { }, + + /** + * Returns the created timestamp of a file or directory. + * @return (double) the creation time of the file or directory + * @since 0.4 + */ + 'createTimestamp': function() { return 0.0; }, + + /** + * Deletes a directory. + * @return (bool) true if the file was successfully deleted; otherwise, false. + * @since 0.4 + */ + 'deleteDirectory': function() { return true; }, + + /** + * Deletes a file. + * @return (bool) true if the file was successfully deleted; otherwise, false. + * @since 0.4 + */ + 'deleteFile': function() { return true; }, + + /** + * Checks whether a file or directory exists in the users system. + * @return (bool) true if the file or directory exists; otherwise false. + * @since 0.4 + */ + 'exists': function() { return true; }, + + /** + * Returns the extension of a file. + * @return (string) extension of the file + * @since 0.4 + */ + 'extension': function() { return ''; }, + + /** + * Returns a list containing the names of items in a directory. + * @return (list) a list of File items inside the directory. (Not implemented in Android beta) + * @since 0.4 + */ + 'getDirectoryListing': function() { return []; }, + + /** + * Returns the parent directory of a file or directory. + * @return (Titanium.Filesystem.File) the parent directory + * @since 0.4 + */ + 'getParent': function() { return new Titanium.Filesystem.File(); }, + + /** + * Checks whether a file object references a directory. + * @return (bool) true if the File object references a directory; otherwise, false. + * @since 0.4 + */ + 'isDirectory': function() { return true; }, + + /** + * Checks whether a file is an executable file. + * @return (bool) true if the file is an executable file, false if otherwise + * @since 0.4 + */ + 'isExecutable': function() { return true; }, + + /** + * Checks whether a file object references a file. + * @return (bool) true if the File object references a file; otherwise, false. + * @since 0.4 + */ + 'isFile': function() { return true; }, + + /** + * Checks whether a file or directory is hidden. + * @return (bool) true if the file or directory is hidden, false if otherwise + * @since 0.4 + */ + 'isHidden': function() { return true; }, + + /** + * Checks whether a file or directory is read-only. + * @return (bool) true if the file or directory is read-only, false if otherwise + * @since 0.4 + */ + 'isReadonly': function() { return true; }, + + /** + * Checks whether the File object references a symbolic link. + * @return (bool) true if the File object references a symbolic link, false if otherwise + * @since 0.4 + */ + 'isSymbolicLink': function() { return true; }, + + /** + * Checks whether a file or directory is writeable. + * @return (bool) true if the file or directory is writeable, false if otherwise + * @since 0.4 + */ + 'isWritable': function() { return true; }, + + /** + * Returns the last modified timestamp of a file or directory. + * @return (double) the modification time of the file or directory + * @since 0.4 + */ + 'modificationTimestamp': function() { return 0.0; }, + + /** + * Moves a file to a specified location. + * @param destination (string) destination to move to + * @return (bool) true if the file was successfully moved; otherwise, false + * @since 0.4 + */ + 'move': function( destination ) { return true; }, + + /** + * Returns the full native path of a file or directory. + * @return (string) full native path of the file or directory + * @since 0.4 + */ + 'nativePath': function() { return ''; }, + + /** + * Returns one line (separated by line ending) from a file. + * @return (string) a string of data from the file + * @since 0.4 + */ + 'read': function() { return ''; }, + + /** + * Returns one line (separated by line ending) from a file. + * @return (string) A string of data from the file + * @since 0.4 + */ + 'readline': function() { return ''; }, + + /** + * Renames a file. + * @param destination (string) new name + * @return (bool) true if the file was successfully renamed; otherwise, false + * @since 0.4 + */ + 'rename': function( destination ) { return true; }, + + /** + * Resolves a File object to a file path. + * @param path (string) path to resolve + * @return (Titanium.Filesystem.File) a file object referencing a path. (Not implemented in Android, beta) + * @since 0.4 + */ + 'resolve': function( path ) { return new Titanium.Filesystem.File(); }, + + /** + * Makes the file or directory executable. + * @return (bool) returns true if the operation was successful; otherwise, false + * @since 0.4 + */ + 'setExecutable': function() { return true; }, + + /** + * Makes the file or directory readonly. + * @return (bool) returns true if the operation was successful; otherwise, false + * @since 0.4 + */ + 'setReadonly': function() { return true; }, + + /** + * Makes the file or directory writeable. + * @return (bool) returns true if the operation was successful; otherwise, false + * @since 0.4 + */ + 'setWriteable': function() { return true; }, + + /** + * Returns the size of the file in bytes. + * @return (double) the size of a file or directory in bytes + * @since 0.4 + */ + 'size': function() { return 0.0; }, + + /** + * Returns the space available on the filesystem. + * @return (double) the space available on the filesystem (Not implemented in Android beta) + * @since 0.4 + */ + 'spaceAvailable': function() { return 0.0; }, + + /** + * Get the string representation. + * @return (string) returns string representation of the file or directory + * @since 0.4 + */ + 'toString': function() { return ''; }, + + /** + * Returns the url to a file or directory. + * @return (string) full url of the file or directory + * @since 0.7 + */ + 'toURL': function() { return ''; }, + + /** + * Writes data to the file + * @param data (string) data to write to file + * @param append (bool) true if write should append to file + * @return (bool) returns true if the operation was successful; otherwise, false + * @since 0.4 + */ + 'write': function( data, append ) { return true; } +}; + +/** + * @package Titanium + * @subpackage Filesystem + */ +Titanium.Filesystem.Filestream = { + /** + * Returns the url to a file or directory. + * @return (string) full url of the file or directory + * @since 0.7 + */ + 'toURL': function() { return ''; } +}; + +/** + * @package Titanium + * @subpackage Geolocation + */ +Titanium.Geolocation = { + 'hasCompass': true, + + /** + * Stop watching geolocation events. + * @param watchId (int) The value returned from watchPosition + * @since 0.4 + */ + 'clearWatch': function( watchId ) { }, + + 'forwardGeocoder': function( address, callback ) { }, + + 'getCurrentHeading': function( success, failure ) { }, + + /** + * Query the device for the last known position. On Android, this method does not cause the radio to start. + * @param success (function) Function to be invoked with a position object if the operation is successful + * @param failure (function) Function to be invoked if a failure occurs while retrieving the last position + * @param options (Object) An object that contains options to be used by the method + * @since 0.4 + */ + 'getCurrentPosition': function( success, failure, options ) { }, + + 'reverseGeocoder': function( latitude, longitude, callback ) { }, + + 'watchHeading': function( success, failure ) { }, + + /** + * Register to receive geolocation updates. + * continously query the Geolocation services for location updates + * @param success (function) Function to be invoked with a position object if the operation is successful + * @param failure (function) Function to be invoked if a failure occurs while retrieving the last position + * @param options (Object) An object that contains options to be used by the method + * @return (int) id to pass to clearWatch to stop un-register + * @since 0.4 + */ + 'watchPosition': function( success, failure, options ) { return 0; } +}; + +/** + * @package Titanium + * @subpackage Gesture + */ +Titanium.Gesture = { + /** + * Device is rotated 90 degrees to the left of portrait. + * integer that represents both landscape left or landscape right orientation + * @constant + * @final + * @since 0.4 + */ + 'LANDSCAPE': 3, + + /** + * Device is rotated 90 degrees to the left of portrait. Same as LANDSCAPE. + * integer that represents landscape orientation where the home button is to the left of the screen + * @constant + * @final + * @since 0.4 + */ + 'LANDSCAPE_LEFT': 1, + + /** + * Device is rotated 90 degrees to the right of portrait. Not reported on Android. + * integer that represents landscape orientation where the home button is to the right of the screen + * @constant + * @final + * @since 0.4 + */ + 'LANDSCAPE_RIGHT': 2, + + /** + * Portrait orientation. + * integer that represents portrait orientation + * @constant + * @final + * @since 0.4 + */ + 'PORTRAIT': 0, + + /** + * Not reported on Android. Device rotated 180 degrees from portrait. + * integer that represents an upside-down portrait orientation + * @constant + * @final + * @since 0.4 + */ + 'UPSIDE_PORTRAIT': 4, + + /** + * Listen for Gesture events. currently supported events are 'orientationchange' and 'shake'. + * add an event listener to be called for a gesture event and returns the function to use when removing + * @param eventName (string) A supported gesture event name + * @param listener (function) Function to pass events gesture events to. + * @return (int) id to pass to removeEventListener to stop receiving events. Id is only valid for use with the event name that was used to register the listener + * @since 0.4 + */ + 'addEventListener': function( eventName, listener ) { return 0; }, + + /** + * Helper method to determine if device is in any landscape position. + * indicates whether or not the passed in value is a landscape view. + * @param orientation (int) Obtained via the 'orentationchange' event's 'to' or 'from' property + * @since 0.4 + */ + 'isLandscape': function( orientation ) { }, + + /** + * Helper method to determine if device is in any portrait position. + * indicates whether or not the passed in value is a portrait view. + * @param orientation (int) Obtained via the 'orientationchange' event's 'to' or 'from' property + * @since 0.4 + */ + 'isPortrait': function( orientation ) { }, + + /** + * Remove gesture event listener. + * removes an event listener from gesture events + * @param eventName (string) Event name used to register event. + * @param listenerId (int) Id returned from addEventListener. Ids are only valid for the eventName passed in addEventListener + * @since 0.4 + */ + 'removeEventListener': function( eventName, listenerId ) { } +}; + +/** + * @package Titanium + * @subpackage Map + */ +Titanium.Map = { }; + +/** + * @package Titanium + * @subpackage Media + */ +Titanium.Media = { + /** + * Play an audio alert using the system default notification. + * Causes the system to make an alert noise and/or vibrate + * @since 0.4 + */ + 'beep': function() { }, + + /** + * Creates a Sound object. + * @param url (string) url to sound + * @return (Titanium.Media.Sound) the sound object + * @since 0.4 + */ + 'createSound': function( url ) { return new Titanium.Media.Sound(); }, + + /** + * Start video player. + * Creates a video-playing object + * @param options (Object) hash/dictionary of video player options + * @since 0.4 + */ + 'createVideoPlayer': function( options ) { }, + + /** + * Show a photo browser. On Android the browser allows editing. + * Presents the image picker interface to the user to let them choose an image from their image gallery. + * @since 0.4 + */ + 'openPhotoGallery': function() { }, + + /** + * Start the photo gallery on a specific image. + * @param options (Object) hash/dictionary of viewing options + * @since 0.4 + */ + 'previewImage': function( options ) { }, + + /** + * Start the camera for capturing an image. + * Presents the camera interface to the user to let them take a photo + * @param options (Object) hash/dictionary for camera options + * @since 0.4 + */ + 'showCamera': function( options ) { }, + + /** + * Vibrate the device. + * Causes the system to vibrate. + * @since 0.4 + */ + 'vibrate': function() { } +}; + +/** + * @package Titanium + * @subpackage Media + */ +Titanium.Media.Sound = { + /** + * Add event listener, currently supports 'complete' and 'error' events. + * add an event listener to be called for a Media.Sound event and returns the function to use when removing + * @param eventName (string) Name of event + * @param listener (function) listener for the event in eventName + * @return (int) id to pass to removeEventListener to stop receiving events + * @since 0.4 + */ + 'addEventListener': function( eventName, listener ) { return 0; }, + + /** + * Returns the volume value of a Sound object. + * @return (double) current level for this Sound + * @since 0.4 + */ + 'getVolume': function() { return 0.0; }, + + /** + * Checks whether a Sound object is set to loop. + * @return (bool) true, if the Sound is currently set to loop + * @since 0.4 + */ + 'isLooping': function() { return true; }, + + /** + * Checks whether a Sound object is paused. + * @return (bool) true if the sound is currently paused + * @since 0.4 + */ + 'isPaused': function() { return true; }, + + /** + * Checks whether a Sound object is currently playing. + * @return (bool) true, if the Sound is currently playing + * @since 0.4 + */ + 'isPlaying': function() { return true; }, + + /** + * Pauses a currently playing Sound object. + * @since 0.4 + */ + 'pause': function() { }, + + /** + * Plays the file referenced by a Sound object. + * @since 0.4 + */ + 'play': function() { }, + + /** + * Release native resources associated with this Sound object. + * This should release a Sound object as soon as you are finished with it. + * Invalidates the sound object and frees associated memory. + * @since 0.4 + */ + 'release': function() { }, + + /** + * removes an event listener from Media.Sound events. + * @since 0.4 + */ + 'removeEventListener': function() { }, + + /** + * Reset sound to the beginning. + * Moves the starting point to the beginning. If the music was paused, + * this is the same as pressing stop. If the music was playing, + * the sound will start playing from the start. + * @since 0.4 + */ + 'reset': function() { }, + + /** + * Sets the looping of a Sound object. + * @param loop (bool) if true, Sound will loop until stopped + * @since 0.4 + */ + 'setLooping': function( loop ) { }, + + /** + * Sets the volume value of a Sound object. + * @param v (double) value between 0.0 and 1.0 + * @since 0.4 + */ + 'setVolume': function( v ) { }, + + /** + * Stop the sound and reset to the beginning. + * Stops a currently playing Sound object. + * @since 0.4 + */ + 'stop': function() { } +}; + +/** + * @package Titanium + * @subpackage Media + */ +Titanium.Media.Video = { + 'addEventListener': function() { }, + 'isPaused': function() { }, + 'isPlaying': function() { }, + 'pause': function() { }, + 'play': function() { }, + 'release': function() { }, + 'removeEventListener': function() { }, + 'reset': function() { }, + 'stop': function() { } +}; + +/** + * @package Titanium + * @subpackage UI + */ +Titanium.UI = { + /** + * Full ASCII keyboard. + * A possible value for UI.NativeControl.keyboardType; indicates the + * keyboard will be standard QWERTY keyboard + * @constant + * @final + * @since 0.6 + */ + 'KEYBOARD_ASCII': 0, + + /** + * ASCII keyboard with email keys like '@'. + * A possible value for UI.NativeControl.keyboardType; indicates the + * keyboard will be the standard QWERTY keyboard, but with @ and + * period keys next to the space key + * @constant + * @final + * @since 0.6 + */ + 'KEYBOARD_EMAIL_ADDRESS': 1, + + /** + * Full ASCII keyboard with Numbers and Punctuation visible. + * A possible value for UI.NativeControl.keyboardType; indicates the + * keyboard will be the standard QUERTY keyboard, but displaying + * numbers and punctuation by default + * @constant + * @final + * @since 0.6 + */ + 'KEYBOARD_NUMBERS_PUNCTUATION': 2, + + /** + * Current same as KEYBOARD_NUMBERS_PUNCTUATION. + * A possible value for UI.NativeControl.keyboardType; indicates the + * keyboard will be a 12-key keypad, with a blank key to the left of + * the 0, and delete to the right + * @constant + * @final + * @since 0.6 + */ + 'KEYBOARD_NUMBER_PAD': 3, + + /** + * Phone dialpad keys. + * A possible value for UI.NativeControl.keyboardType; indicates the + * keyboard will be a 12-key keypad, with +*# to the left of the + * 0 key, and delete to the right + * @constant + * @final + * @since 0.6 + */ + 'KEYBOARD_PHONE_PAD': 4, + + /** + * Hybrid map view. + * @constant + * @final + * @since 0.8 + */ + 'MAP_VIEW_HYBRID': 2, + + /** + *Satellite map view. + * @constant + * @final + * @since 0.8 + */ + 'MAP_VIEW_SATELLITE': 1, + + /** + * Standard map view. + * @constant + * @final + * @since 0.8 + */ + 'MAP_VIEW_STANDARD': 0, + + /** + * Displays the Done button. + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Done" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_DONE': 0, + + /** + * Displays the Go button. (Soft keyboard doesn't allow for text change yet) + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Emergency Call" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_EMERGENCY_CALL': 1, + + /** + * Displays the Go button. + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Go" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_GO': 2, + + /** + * Displays the Go button. (Soft keyboard doesn't allow for text change yet) + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Google" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_GOOGLE': 3, + + /** + * Displays the Go button. (Soft keyboard doesn't allow for text change yet) + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Join" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_JOIN': 4, + + /** + * Displays the Next button. + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Next" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_NEXT': 5, + + /** + * Displays the Go button. (Soft keyboard doesn't allow for text change yet) + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Route" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_ROUTE': 6, + + /** + * Displays the Search button. + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Search" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_SEARCH': 7, + + /** + * Displays the Go button. (Soft keyboard doesn't allow for text change yet) + * A possible value for UI.NativeControl.returnKeyType; indicates + * the lower right keyboard button will be labelled "Yahoo" + * @constant + * @final + * @since 0.6 + */ + 'RETURNKEY_YAHOO': 8, + + /** + * Position the row at top if currently above the tableview. Position the row at bottom if currently below the tableview. Don't change if already visible in the tableview. + * @constant + * @final + * @since 0.8 + */ + 'TABLEVIEW_POSITION_ANY': 0, + + /** + * Position the row at the top of the tableview. + * @constant + * @final + * @since 0.8 + */ + 'TABLEVIEW_POSITION_BOTTOM': 3, + + /** + * Position the row in the middle of the tableview. + * @constant + * @final + * @since 0.8 + */ + 'TABLEVIEW_POSITION_MIDDLE': 2, + + /** + * Position the row at the top of the tableview. + * @constant + * @final + * @since 0.8 + */ + 'TABLEVIEW_POSITION_TOP': 1, + + /** + * open the window + * @param {Array} options Options used to configure window before opening. (optional) + * @since 0.8 + */ + 'UserWindow': function( options ) { }, + + /** + * + */ + 'addEventListener': function( eventName, eventHandler ) { }, + + /** + * + */ + 'createActivityIndicator': function( options ) { }, + + /** + * + */ + 'createAlertDialog': function( options ) { }, + + /** + * + */ + 'createButton': function( options ) { }, + + /** + * + */ + 'createCompositeView': function( options ) { }, + + /** + * + */ + 'createEmailDialog': function( options ) { }, + + /** + * + */ + 'createImageView': function( options ) { }, + + /** + * + */ + 'createMapView': function( options ) { }, + + /** + * + */ + 'createMenu': function() { }, + + /** + * + */ + 'createNotification': function( options ) { }, + + /** + * + */ + 'createOptionDialog': function( options ) { }, + + /** + * + */ + 'createProgressBar': function( options ) { }, + + /** + * + */ + 'createScrollableView': function( options ) { }, + + /** + * + */ + 'createSlider': function( options ) { }, + + /** + * + */ + 'createSwitch': function( options ) { }, + + /** + * + */ + 'createTableView': function( options ) { }, + + /** + * + */ + 'createTextArea': function( options ) { }, + + /** + * + */ + 'createTextField': function( options ) { }, + + /** + * + */ + 'createWebView': function( options ) { }, + + /** + * + */ + 'createWindow': function( options ) { }, + + /** + * + */ + 'currentView': function() { }, + + /** + * + */ + 'currentWindow': function() { }, + + /** + * + */ + 'getTabs': function() { }, + + /** + * + */ + 'getTagByName': function( name ) { }, + + /** + * + */ + 'removeEventListener': function( eventName, listenerId ) { }, + + /** + * + */ + 'setActiveTab': function( Tab ) { }, + + /** + * + */ + 'setMenu': function( m ) { } +}; + +/** + * @package Titanium + * @subpackage UI + */ +Titanium.UI.ActivityIndicator = { + 'DETERMINANT': 0, + 'DIALOG': 1, + 'INDETERMINANT': 2, + 'STATUS_BAR': 3, + 'hide': function() { }, + 'setLocation': function( location ) { }, + 'setMax': function( n ) { }, + 'setMessage': function( msg ) { }, + 'setMin': function( n ) { }, + 'setType': function( type ) { }, + 'setValue': function( n ) { }, + 'show': function() { } +}; + +/** + * @package Titanium + * @subpackage UI + */ +Titanium.UI.AlertDialog = { + 'addEventListener': function( eventName, listener ) { }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'setButtonNames': function( names ) { }, + 'setMessage': function( message ) { }, + 'setTitle': function( title ) { }, + 'show': function() { } +}; + +/** + * @package Titanium + * @subpackage UI + */ +Titanium.UI.Android = { }; + +/** + * @package Titanium + * @subpackage UI + */ +Titanium.UI.Android.AnimationStyle = { + 'FADE': 0, + 'HEADLINES': 1, + 'SCALE': 2, + 'SLIDE_FROM_BOTTOM': 3, + 'SLIDE_FROM_LEFT': 4, + 'SLIDE_FROM_RIGHT': 5, + 'SLIDE_FROM_TOP': 6, + 'WINK': 7 +}; + +/** + * @package Titanium + * @subpackage UI + */ +Titanium.UI.Android.SystemIcon = { + 'ACTION': '', + 'ADD': '', + 'BACK': '', + 'BOOKMARKS': '', + 'CAMERA': '', + 'CANCEL': '', + 'COMPOSE': '', + 'DONE': '', + 'EDIT': '', + 'FAST_FORWARD': '', + 'FORWARD': '', + 'HELP': '', + 'HOME': '', + 'NEXT': '', + 'ORGANIZE': '', + 'PAUSE': '', + 'PLAY': '', + 'PREFERENCES': '', + 'PREVIOUS': '', + 'REFRESH': '', + 'REPLY': '', + 'REVERT': '', + 'REWIND': '', + 'SAVE': '', + 'SEARCH': '', + 'SEND': '', + 'SHARE': '', + 'STOP': '', + 'TRASH': '', + 'VIEW': '', + 'ZOOM': '' +}; + +Titanium.UI.Button = { + 'addEventListener': function( eventName, listener ) { }, + 'removeEventListener': function( eventName, listenerId ) { } +}; + +Titanium.UI.CompositeView = { + 'addEventListener': function( eventName, listener ) { }, + 'addView': function( view, layout ) { }, + 'removeEventListener': function( eventName, listenerId ) { } +}; + +Titanium.UI.DatePicker = { + 'MODE_DATE': 0, + 'MODE_TIME': 1, + 'addEventListener': function( eventName, listener ) { }, + 'removeEventListener': function( eventName, listenerId ) { } +}; + +Titanium.UI.EmailDialog = { + 'addAttachment': function() { }, + 'setSubject': function() { }, + 'setMessageBody': function() { }, + 'setBarColor': function() { }, + 'open': function() { } +}; + +Titanium.UI.ImageView = { + 'addEventListener': function( eventName, listener ) { }, + 'removeEventListener': function( eventName, listenerId ) { } +}; + +Titanium.UI.MapView = { + 'addEventListener': function( eventName, listener ) { }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'setCenterCoordinate': function( coordinate ) { }, + 'setRegion': function( coordinate ) { }, + 'setType': function( type ) { } +}; + +Titanium.UI.MenuItem = { + 'addItem': function( label, callback, icon ) { }, + 'addSeparator': function() { }, + 'addSubMenu': function( label, icon ) { }, + 'disable': function() { }, + 'enable': function() { }, + 'getIcon': function() { }, + 'getLabel': function() { }, + 'isEnabled': function() { }, + 'isItem': function() { }, + 'isRoot': function() { }, + 'isSeparator': function() { }, + 'isSubMenu': function() { }, + 'setIcon': function( path ) { }, + 'setLabel': function( label ) { } +}; + +Titanium.UI.Notifier = { + 'hide': function( animate ) { }, + 'setDelay': function( delay ) { }, + 'setIcon': function( iconUrl ) { }, + 'setMessage': function( message ) { }, + 'setTitle': function( title ) { }, + 'show': function( animate, autohide ) { } +}; + +Titanium.UI.OptionDialog = { + 'addEventListener': function( eventName, listener ) { }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'setOptions': function( options ) { }, + 'setTitle': function( title ) { }, + 'show': function() { } +}; + +Titanium.UI.Picker = { + 'addEventListener': function( eventName, listener ) { }, + 'removeEventListener': function( eventName, listenerId ) { } +}; + +Titanium.UI.ScrollableView = { + 'addEventListener': function( eventName, listener ) { }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'scrollToView': function( view ) { }, + 'setShowPagingControl': function( view ) { }, + 'setViews': function( views ) { } +}; + +Titanium.UI.SearchBar = { + 'blur': function() { }, + 'focus': function() { } +}; + +Titanium.UI.Slider = { + 'value': 0, + 'addEventListener': function( eventName, listener ) { }, + 'getValue': function() { return 0; }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'setValue': function( value ) { } +}; + +Titanium.UI.Switch = { + 'value': true, + 'addEventListener': function( eventName, listener ) { }, + 'getValue': function() { return true; }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'setValue': function( value ) { } +}; + +Titanium.UI.TableView = { + '_data': '', + 'UpdateRow': function( index, options ) { }, + 'addEventListener': function( eventName, listener ) { }, + 'appendRow': function( rowData, options ) { }, + 'deleteRow': function( index ) { }, + 'getIndexByName': function( name ) { }, + 'getName': function() { }, + 'getRowCount': function() { }, + 'insertRowAfter': function( index, options ) { }, + 'insertRowBefore': function( index, options ) { }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'scrollToIndex': function( index ) { }, + 'setBarColor': function( color ) { }, + 'setData': function( data ) { }, + 'setRowHeight': function( rowHeight ) { } +}; + +Titanium.UI.TextArea = { + 'addEventListener': function( eventName, listener ) { }, + 'blur': function() { }, + 'focus': function() { }, + 'getValue': function() { return ''; }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'setValue': function( value ) { } +}; + +Titanium.UI.TextField = { + 'value': '', + 'addEventListener': function( eventName, listener ) { }, + 'blur': function() { }, + 'focus': function() { }, + 'getValue': function() { return ''; }, + 'removeEventListener': function( eventName, listenerId ) { }, + 'setValue': function( value ) { } +}; diff --git a/assets/tmobile_germany.ipcc b/assets/tmobile_germany.ipcc new file mode 100644 index 0000000000000000000000000000000000000000..1566f17aeadc5b4f66d864c4ba5f689d9d648308 GIT binary patch literal 6670 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 F{|9p9R*C=s literal 0 HcmV?d00001 diff --git a/know-how/hardware/apple-iphone/_posts/2009-04-26-flash-in-safari.md b/know-how/hardware/apple-iphone/_posts/2009-04-26-flash-in-safari.md new file mode 100644 index 0000000..e108b40 --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-04-26-flash-in-safari.md @@ -0,0 +1,19 @@ +--- +title: Flash in Safari +layout: default +created: 2009-04-23 23:34:27 +0200 +updated: 2009-04-26 22:23:01 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - safari + - flash +--- +(Found [here](http://www.gizmodo.com.au/2008/12/flash_for_iphone_comes_via_jailbroken_imobilecinema_app-2.html).) + +You need to have a [jailbroken]({% post_url 2009-06-20-jailbreak %}) iPhone for this. + +Add the repository `http://d.imobilecinema.com/` to Cydia and find the **iMobileCinema**. After installing it, you should be able to watch Flash movies in Safari (most of the times). diff --git a/know-how/hardware/apple-iphone/_posts/2009-05-16-appulous.md b/know-how/hardware/apple-iphone/_posts/2009-05-16-appulous.md new file mode 100644 index 0000000..ffa00fb --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-05-16-appulous.md @@ -0,0 +1,32 @@ +--- +title: Appulous +layout: default +created: 2009-04-20 20:39:02 +0200 +updated: 2009-05-16 11:11:42 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - hacking + - apps +--- +* **Homepage:** [appulo.us](http://appulo.us/appdb/) + +Appulous is a **special** AppStore for [jailbroken]({% post_url 2009-06-20-jailbreak %}) iPhones. The problem of the +original AppStore is that you can't test the applications. You are mostly dependent on the reviews - if there are some. + +Appulous lets you test drive most applications from the AppStore. + +To install it, add the following source to *Cydia*: `http://cydia.hackulo.us` . Then install the **Installous** package +using Cydia. + +*(If you decide to keep an application, buy it from the original AppStore. The developer deserves it.)* + +

+Apps installed via Installous are mostly wiped upon a sync with iTunes. To fix this, buy them.[^1] +

+ + +[^1]: or search for how to disable the killswitch via *SBSettings* diff --git a/know-how/hardware/apple-iphone/_posts/2009-05-24-firmware-unpacking.md b/know-how/hardware/apple-iphone/_posts/2009-05-24-firmware-unpacking.md new file mode 100644 index 0000000..b3a0552 --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-05-24-firmware-unpacking.md @@ -0,0 +1,136 @@ +--- +title: Firmware Unpacking +layout: default +created: 2009-05-20 02:17:15 +0200 +updated: 2009-05-24 23:27:24 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - firmware + - hacking +--- +Preparations +============ + +You'll need the following tools: + +* [genpass.c](http://www.theiphonewiki.com/wiki/index.php?title=GenPass) +* [vfdecrypt-linux.tar.gz](http://code.google.com/p/iphone-elite/downloads/list) +* [Xpwn](http://www.zdziarski.com/iphone-forensics/v2.x-Base/Xpwn/) +* [OpenSSL 0.9.8h sources](http://www.openssl.org/source/openssl-0.9.8h.tar.gz) + +Now compile the `genpass.c`: + +1. untar `openssl-0.9.8h.tar.gz` and rename the directory to just `openssl` +1. compile OpenSSL: + + cd openssl/ + ./config && make + +1. now go one directory up (I assume this is where you put the `genpass.c`) and compile it: + + gcc genpass.c openssl/libcrypto.a -o genpass -I openssl/include + +1. the `vfdecrypt-linux.tar.gz` comes with a precompiled binary. If you want to compile it on your own, do it like this: + + gcc vfdecrypt.c ../openssl/libcrypto.a -I ../openssl/include/ -o vfdecrypt + + +Unpacking the ipsw file +======================= + +The ***iP**hone **S**oft**w**are* `.ipsw` files are normal ZIP files. You can extract them with e.g. *IZArc*. The archives +contain several files and some disk images: the iPhone OS itself, an Upgrade image and a Restore image. These 3 interesting +files for the iPhone OS 3.0 BETA 5 are named like this (output of `unzip -l`): + +~~~ +Archive: iPhone1,2_3.0_7A312g_Restore.ipsw + Length Date Time Name + -------- ---- ---- ---- +208347136 05-04-09 13:09 018-4965-005.dmg + 13086064 05-04-09 13:00 018-4970-005.dmg + 13086064 05-04-09 13:00 018-4972-005.dmg +~~~ + +The larger one is the iPhone OS image, the other two are the two loader images (upgrade/restore). + + +Decrypt a loader image +====================== + +You need an *initialization vector* and a *key* for decrypting this. For now, these are posted +on [theiphonewiki.com](http://www.theiphonewiki.com/wiki/index.php?title=VFDecrypt_Keys:_3.x#iPhone_3G_5). + +Do this using the **Xpwntool**: + + ./xpwntool 018-4972-005.dmg ramdisk.dmg -iv 5508FD2D20F22048D4BC1780A0B1CAFF -k 198FEAFD04973FC8B07A052BE75B9288 + + +Find encryption key for iPhoneOS +================================ + +The key might be already posted on [theiphonewiki.com](http://www.theiphonewiki.com/wiki/index.php?title=VFDecrypt_Keys:_3.x#iPhone_3G_5), +so maybe we don't need this step. + +Use the compiled `genpass.c` to extract the encryption key from the decrypted loader image: + + ./genpass s5l8900x ./ramdisk.dmg 018-4965-005.dmg + +This will give something like this: + +~~~ +passphrase: fcdf5fbe3bdcaeff0c3de34430ffb473ac34cb0b55efdc087e70aa7c558a1055 +not block 0 +not block 1 +not block 2 +not block 3 +not block 4 +not block 5 +vfdecryptk: f7b1edb0ee9196a1393dccdc8d090051308b84ab322bf860cb1d3ca566ef2e29752fa79a +~~~ + + +Decrypt iPhoneOS +================ + +This was a bit tricky as the syntax for `vfdecrypt` was wrong in all other manuals and even in the syntax help of `vfdecrypt` itself. + +Run this: + + ./vfdecrypt -i018-4965-005.dmg -kf7b1edb0ee9196a1393dccdc8d090051308b84ab322bf860cb1d3ca566ef2e29752fa79a -odmg.dmg + +(Note the missing *\* between the parameter's name and value.) + +This will give you a file `dmg.dmg` which is the decrypted iPhoneOS image. + + +Uncompress iPhoneOS image +========================= + +Since the `dmg.dmg` (199 MiB) is a compressed image, you can't mount it directly in Linux. You first have to unpack it. +There's a tool `dmg` among the **Xpwntools**. So use it like this: + + ./dmg extract dmg.dmg dmg-raw.dmg + +You'll get a 441 MiB file `dmg-raw.dmg`. + + +Mount iPhoneOS +============== + +To go exploring the iPhoneOS files, you can now mount the uncompressed image like this: + + sudo mount -o loop -t hfsplus ./dmg-raw.dmg /mnt/iphoneimage + +(Make sure that `/mnt/iphoneimage` exists and is an empty folder.) + + +Links +===== + +* [mail-archive.com](http://www.mail-archive.com/linux4nano-dev@gna.org/msg00209.html) --- technical explanation +* [tungchingkai.blogspot.com](http://tungchingkai.blogspot.com/2009/04/how-to-decrypt-iphone-os-30-beta.html) --- how to decrypt the firmware file +* [theiphonewiki.com](http://www.theiphonewiki.com/wiki/index.php?title=VFDecrypt_Keys:_3.x#iPhone_3G_5) --- several encryption keys for iPhone firmware files diff --git a/know-how/hardware/apple-iphone/_posts/2009-05-27-crashing-apps.md b/know-how/hardware/apple-iphone/_posts/2009-05-27-crashing-apps.md new file mode 100644 index 0000000..f484f3f --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-05-27-crashing-apps.md @@ -0,0 +1,20 @@ +--- +title: Crashing Applications +layout: default +created: 2009-05-27 09:48:31 +0200 +updated: 2009-05-27 09:48:31 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - crashing +--- +If you have to problem that some apps crash directly after running them, i.e. you see the app "popup" but it +immediately disappears leaving you back at the home screen, it might be a problem with Apple's DRM. This can +occur if a Sync with iTunes is aborted or the connection was lost. + +I found the solution between the comments on [iphonehacks.com](http://www.iphonehacks.com/2008/07/app-crash-fix.html#comment-6a00d83534e7f169e2010534da1d1c970c): +Just download **any** (free) app from the AppStore - might also be some app you already bought but deleted +from the phone. After the app is installed, all other apps should work fine again. diff --git a/know-how/hardware/apple-iphone/_posts/2009-05-30-google-calendars.md b/know-how/hardware/apple-iphone/_posts/2009-05-30-google-calendars.md new file mode 100644 index 0000000..5cd7ede --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-05-30-google-calendars.md @@ -0,0 +1,33 @@ +--- +title: Google Calendars +layout: default +created: 2009-05-30 23:11:26 +0200 +updated: 2009-05-30 23:11:26 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - google + - calendar +--- +If you want to sync your iPhone primarily with an Exchange server of your company but do want to have your (private) Google Calendars with you, you can add them as CalDAV calendars (since iPhone OS 3.0). + +Go to *Settings* → *Mail, Contacts, Calendars* → *Add Account…* → *Other* → *Add CalDAV Account*: + +* enter the following: + * **Server:** `www.google.com` + * **User Name:** `@gmail.com` + * **Password:** *``* +* touch *Next*, this will create an entry with your default (first) Google Calendar + +If you want to add another calendar, repeat the above steps and do this to change to another calendar: + +* after adding the calendar touch the new entry (called *"Google"*) +* touch *Advanced Settings* +* edit the *Account URL*, the default one looks like `https://www.google.com:443/calendar/dav/%40gmail.com/user`: + * replace `%40gmail.com` by the Calendar ID of the other calendar + * you will find this ID in the settings of the specific Google Calendar, it is in the section **Calendar Address**, it looks like this: `2et3hcu26nrtli1r5r1slvus84@group.calendar.google.com` + * you might have to replace the `@` by `%40` +* go back and open the Calendar app to download the calendar data diff --git a/know-how/hardware/apple-iphone/_posts/2009-06-20-carrier-settings.md b/know-how/hardware/apple-iphone/_posts/2009-06-20-carrier-settings.md new file mode 100644 index 0000000..3b63f80 --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-06-20-carrier-settings.md @@ -0,0 +1,69 @@ +--- +title: Carrier Settings +layout: default +created: 2009-06-20 21:20:46 +0200 +updated: 2009-06-20 21:20:46 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - settings +--- +To enable MMS and Tethering, you might have to install a carrier-specific file for your carrier. + +* **T-Mobile Germany:** [24100.net](http://www.24100.net/2009/03/t-mobile-germany-vodafone-germany-iphone-os-30-mms/) +* the same file with more features enabled (see next section): [Download here]({{ site.url }}/assets/tmobile_germany.ipcc) + + +Details +======= + +If you look at the `.ipcc`-file you'll notice that it's a standard ZIP archive. Inside you'll find a folder `Payload` +and a folder with your carrier's name. There you'll find a file `carrier.list` along some others. It is an XML file +with all the features for your carrier. Some interesting snippets: + +{% highlight xml %} + AllowEDGEEditing + + AllowMMSCEditing + + AllowMMSEditing + +... + ShowCallForwarded + + ShowCallForwarding + + ShowTTY + +... + SupportMMS + +... + SupportsNITZ + +{% endhighlight %} + +You can upload the `.ipcc` file using the Developer version of iTunes 8.2.0.10[^1]. Or you can upload the file to a +webserver and download it to your phone. There's also the possibility of creating a single merged XML file which then +must be sent using the MIME type `application/x-apple-aspen-config`. + + +MMS Settings +============ + +The carrier file for T-Mobile Germany doesn't contain the MMS settings. So go to *Settings* → *General* → *Network* +→ *Cellular Data Network* and input the following under the **MMS** section: + +* **APN:** `mms.t-d1.de` +* **Username:** `t-mobile` +* **Password:** `mms` +* **MMSC:** `mms.t-mobile.de/servlets/mms` +* **MMS Proxy:** `172.28.23.131:8008` +* **MMS Max Message Size:** 300 +* **MMS UA Prof URL:** *\* + + +[^1]: Or change the shortcut to iTunes so that it reads: `...\iTunes.exe" /setPrefInt carrier-testing 1`, Mac users run `defaults write com.apple.iTunes carrier-testing -bool TRUE` diff --git a/know-how/hardware/apple-iphone/_posts/2009-06-20-hidden-features.md b/know-how/hardware/apple-iphone/_posts/2009-06-20-hidden-features.md new file mode 100644 index 0000000..4502775 --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-06-20-hidden-features.md @@ -0,0 +1,91 @@ +--- +title: Hidden Features +layout: default +created: 2009-06-20 21:18:27 +0200 +updated: 2009-06-20 21:19:17 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - features +--- +There are some hidden options which you have to enable via modifying some file. +(see [here](http://www.funkyspacemonkey.com/iphone-os-30-episode-iii-howto-enable-battery-percentage-toggle-settings) +and [here](http://www.funkyspacemonkey.com/iphone-os-30-episode-iihowto-enable-videorecording-interface-iphone-2g3g).) + +Enable a feature +================ + +For this you have to have [ssh-access]({% post_url 2009-04-26-ssh-access %}) enabled!! + +1. `ssh` into the iPhone (remember: the `root`-password is **`alpine`**) +1. `cd` to `/System/Library/CoreServices/Springboard.app/` +1. run this command: `plutil -c xml1 M68AP.plist` (this will convert the binary-XML to plaintext) +1. now use `nano`, `mcedit` or `vim` to edit the file +1. find the **capabilites** dictionary right at the top of the file +1. add the following two key/value-pair: + {% highlight xml %} +gas-gauge-battery + +{% endhighlight %} +1. save the file +1. run `plutil -c binary1 M68AP.plist` to convert the file back into binary-XML format +1. logout +1. reboot(=respring) the iPhone + + +Features Explained +================== + +accessibility +------------- + +This will add a new settings menu below *General* (right below *International*). It is empty on iPhone 3G. + + +gas-gauge-battery +----------------- + +This will enable a new setting under *General* → *Usage* to enable a percentage field left of the battery icon. + + +video-camera +------------ + +This will enable a new photo <=> video switch in the camera interface. + +

+Enabling this feature will make the camera **unusable**! You won't be able to take normal photos with this feature enabled. (as of BETA 5) +

+ + +voice-control +------------- + +This will add a new settings menu below *General* → *International*. It is empty on iPhone 3G. + + +More Features +============= + +In the file `/System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices` there are various more feature codes listed - here's a screendump: + +~~~ +...device-name-localized...device-name.still-camera....cameraRestriction...telepho +ny...sms.video-camera....auto-focus-camera...wifi....accelerometer...magnetometer. +...gps.location-services...microphone..opengles-1..opengles-2..volume-buttons..rin +ger-switch...piezo-clicker...bluetooth...unified-ipod....youtube.youtubePlugin...g +reen-tea...not-green-tea...international-settings..stand-alone-contacts....delay-s +leep-for-headset-click...launch-applications-while-animating.load-thumbnails-while +-scrolling.sensitive-ui....apple-internal-install..all-features....nike-ipod...app +licationInstallation.voice-control...proximity-sensor....gas-gauge-battery...acces +sibility...mms.encrypted-data-partition....encode-aac..fcc-logos-via-software..tel +ephony-maximum-generation....hiccough-interval...application-display-identifiers.t +v-out-settings.screen-dimensions...main-screen-width...main-screen-height..main-sc +reen-scale...main-screen-orientation.explicitContentRestriction..volume-limit-rest +riction....inAppPurchasesRestriction...enforce-shutter-click...enforce-googlemail. +~~~ + +Anyone tried `nike-ipod` or enabling the `magnetometer` on a 3G? Also what could `green-tea` be? diff --git a/know-how/hardware/apple-iphone/_posts/2009-08-01-firmware-3-beta.md b/know-how/hardware/apple-iphone/_posts/2009-08-01-firmware-3-beta.md new file mode 100644 index 0000000..6c0675e --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-08-01-firmware-3-beta.md @@ -0,0 +1,96 @@ +--- +title: Firmware 3.0 BETA without registration +layout: default +created: 2009-05-14 17:17:58 +0200 +updated: 2009-08-01 20:03:23 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - firmware + - hacking +--- +There is a way to install and activate the most recent BETA firmware without registering the device's UDID as a developer. + +What you'll need: + +* [iTunes 8.2](http://www.iphoneheat.com/2009/05/download-iphone-os-30-beta-5-7a312g-and-itunes-82-b10/) +* [iPhoneOS 3.0 BETA firmware file](http://www.iphoneheat.com/2009/03/download-iphone-firmware-files-all-at-one-place/) +* [iUtilities](http://blog.alltechrelated.com/2008/10/24/iutilities-usefully-theme-windows-application/) or [DiskAid](http://www.digidna.net/diskaid/) +* [QuickPwn](http://www.quickpwn.com/2009/05/quickpwn-3-0-beta-5.html) for the specific firmware version +* maybe the carrier-specific features file + + +Steps +===== + +1. Install iTunes 8.2 +1. Maybe make a backup of your iPhone +1. Hold Shift and click the *Restore* button (MAC users: try holding while clicking) +1. Select the iPhone OS 3.0 firmware file +1. Wait until the firmware is installed (~15min) + * Your iPhone will need activation after bootup, but since your UDID isn't registered at Apple, iTunes will deny the activation + * the trick is to make iTunes think, there's a 2.2.1 firmware on your phone which it will activate without any problems +1. Jailbreak the phone using *QuickPwn* (make sure, the *Activate** option is **unchecked**!!) +1. now use *iUtilities* or *DiskAid*: + * **iUtilities:** Click the *String Editor* tab and find the section *System Version* + * enter **2.2.1** into the first box and **5H11** into the second one + * click *Go* + * **DiskAid:** Open DiskAid, set the starting node to *Root* in the bottom left + * navigate to `/System/Libraries/Core Services` and find the file `SystemVersion.plist` + * open this file (or copy to PC and open there) with an editor (e.g. notepad.exe) + * change the *ProductBuildVersion* to **5H11** and change the *ProductVersion* to **2.2.1**. Make sure that *ReleaseType* is **Public** + * save the file (or drag from PC back into *DiskAid*) +1. reboot your iPhone (hold Home and Power until the slider appears) +1. launch iTunes and it will activate your iPhone +1. now you might revert the changes made by *iUtilities* or *DiskAid*, see the table below: + +| Device | Version | Build | Note | +|:------:|:-------:|:------:|:---------------| +| 3G | 2.2.1 | 5H11 | | +| 3G | 3.0 | 7A238j | BETA 1 | +| 3G | 3.0 | 7A259g | BETA 2 | +| 3G | 3.0 | 7A280f | BETA 3 | +| 3G | 3.0 | 7A300g | BETA 4 | +| 3G | 3.0 | 7A312g | BETA 5 | +| 3G | 3.0 | 7A341 | Final / Gold Master | +| 3G | 3.1 | 7C97d | BETA 1 | +| 3G | 3.1 | 7C106c | BETA 2 | +| 3G | 3.1 | 7C116a | BETA 3 | + + +SystemVersion.plist +=================== + +In case you didn't make a backup copy, the file looks like this: + +{% highlight xml %} + + + + + ProductBuildVersion + 7A312g + ProductCopyright + 1983-2009 Apple Inc. + ProductName + iPhone OS + ProductVersion + 3.0 + ReleaseType + Beta + + +{% endhighlight %} + + +Links +===== + +* [facepunch.com](http://www.facepunch.com/showthread.php?t=732296) +* [alltechrelated.com](http://blog.alltechrelated.com/2009/05/13/guide-how-to-bypass-the-udid-registration-for-os-30/) +* [hackint0sh.org](http://www.hackint0sh.org/forum/f201/72220.htm) + +*[UDID]: Unique Device IDentifier diff --git a/know-how/hardware/apple-iphone/_posts/2009-11-30-emojis.md b/know-how/hardware/apple-iphone/_posts/2009-11-30-emojis.md new file mode 100644 index 0000000..fd022fc --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2009-11-30-emojis.md @@ -0,0 +1,41 @@ +--- +title: Emojis +layout: default +created: 2009-11-30 16:00:28 +0100 +updated: 2009-11-30 22:21:44 +0100 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - emojis +--- +[Emojis](http://en.wikipedia.org/wiki/Emoji) is the Japanese term for emoticons. Every mobile phone in the +Japanese area has a fixed set of emoticons included and they are all compatible between different +manufacturers of mobile phones. + +Apple chose to include them as well, but didn't use the defacto-standard encoding for them but decided to +encode them in the private use area. So the emoticons are only compatible between iPhones. Read more about +it at [inner.geek.nz](http://inner.geek.nz/archives/2009/02/06/the-truth-about-iphone-emoji/). + + +Enable the Emoji keyboard +========================= + +To use the Emojis, the iPhone has a special keyboard. But because of the incompatibility, the keyboard is +only available for *SoftBank Mobile* customers. But there exist some programs in the AppStore to enable +the keyboard regardless of the SIM card. + +But don't get ripped off. You don't have to pay for e.g. +[iEmoji](http://appshopper.com/utilities/iemoji-get-your-emoji) - which is totally useless after the +keyboard has been enabled. + +Just get [Spell Number](http://appshopper.com/utilities/spell-number) for free, start it and enter the +magical number `91929394.59`. After that, go to *Settings* → *General* → *Keyboard* → *International* → *Japanese* +and enable the **Emoji keyboard**. Done. + +

To be able to use Emojis while writing mails, you have to reboot your iPhone.

+ +You can find these instructions with pictures +at [maketecheasier.com](http://maketecheasier.com/enable-emoji-icons-on-your-iphone-for-free/2009/02/11). diff --git a/know-how/hardware/apple-iphone/_posts/2010-03-30-iphone-vs-android.md b/know-how/hardware/apple-iphone/_posts/2010-03-30-iphone-vs-android.md new file mode 100644 index 0000000..3a543e0 --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2010-03-30-iphone-vs-android.md @@ -0,0 +1,36 @@ +--- +title: iPhone vs. Android +layout: default +created: 2010-03-07 12:06:49 +0100 +updated: 2010-03-30 13:22:47 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - android + - comparison +--- +| iPhone | Android (esp. Nexus One) | +|:------------------------------------------|:--------------------------------------------------------------| +| It's from *Apple*. | It's **NOT** from *Apple*. (or: It's from *Google*.) | +| can change keyboard layout on the fly | keyboard language related to GUI language (not independently configurable!), but different input methods (not only keyboards) downloadable/switchable on the fly | +| ~150.000 Apps (most are gimmicks though) | ~30.000 Apps and growing, some well-known web-based services still missing as a native App | +| Apple decides which apps get onto the phone/in the AppStore | very loose controlled Market store
can install apps via USB or web download, even from Linux | +| only syncs with one single *iTunes*, i.e. no Linux support at all, no sync at multiple places | supports USB HDD mode where you can use the microSD-card like a flash disk | +| can sync with local software (e.g. Outlook) via iTunes | syncs mostly with Google services or Exchange, but custom apps available for ActiveSync, SyncML, Outlook, etc. | +| supports Push Notifications via Apple servers | Push Notifications are a bit complicated and not native (e.g. IBM MQTT) **but** can use Jabber/XMPP messages via *Google Talk* for notifications | +| Tethering depends on network carrier / paid | Tethering via different methods from free to $30 | +| cheap iPhone OS upgrades in the future (OS2 → OS3 for iPod Touch was $9.95), new versions still support (almost) all old devices | Android updates depend on cell phone maker | +| Apple forbids downgrades of software, even from 3.1.3 to 3.1.2 is not possible --- even when they have broken a feature | You even get the [instructions](http://developer.htc.com/adp.html) from them... | +| you are limited to those service providers *Apple* cooperates with ("exclusive contracts") | open for all network service providers | +| can't replace/change battery | spare batteries are available | +| Apple's sense of *security* is not the best: [h-online.com](http://www.h-online.com/security/news/item/Mac-OS-X-safer-but-less-secure-957981.html) | | +| [iPhone's Headset](http://www.howtomobile.com/apple-iphone/how-to-use-the-iphone-stereo-headset/) has only 1 button (push once to Play/Pause; push twice to Skip Track) | [Android Headset](http://www.google.com/support/android/bin/static.py?page=guide.cs&guide=27201&topic=27212&answer=168441#1084954) has 3 buttons (Last Track; Play/Pause; Next Track) | +| only one App can be used at a time | Multitasking! | +| Apps are limited to their own files (+Pictures/Camera), i.e. you can't access file stored with a different App | Apps have access to all files in your Home directory, i.e. Images, Music, etc. | +| somewhat sloppy (3G) | blazing fast | +| can only have App icons on the Home screen, nothing else is configurable
up to 11 pages with 110 Apps (more can be run by searching) | Home screen can have Widgets, Icons, Subfolders (for more Icons) and you can change the wallpaper (even to an animated "Live Wallpaper")
5 pages, but folders allow for more Apps; also "All Apps at once" view integrated; searching is also available | +| syncs fine with Exchange | doesn't sync Exchange calendars | +| have to check Inboxes of each mail acct | Unified inbox available | diff --git a/know-how/hardware/apple-iphone/_posts/2010-04-02-develop-apps.md b/know-how/hardware/apple-iphone/_posts/2010-04-02-develop-apps.md new file mode 100644 index 0000000..b2fad76 --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2010-04-02-develop-apps.md @@ -0,0 +1,39 @@ +--- +title: Develop iOS Apps +layout: default +created: 2009-04-20 22:07:23 +0200 +updated: 2010-04-02 18:07:54 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - development +--- +real Apps +========= + +* XCode +* [appcelerator](http://appcelerator.com/) (write in JavaScript, but gets natively compiled to standalone apps) + * currently my weapon of choice for iPhone+Android development, needs a Mac with XCode though for the iPhone part + * see [appcelerator Titanium Framework]({% post_url 2010-06-08-appcelerator-titanium %}) + + +Pseudo-Apps +=========== + +*Pseudo-Apps* is what I call the apps which are actually a bunch of HTML pages with JavaScript and some JavaScript-API +for accessing the iPhone internal features. These open in a WebKit-control so that they are basically some spiced up websites. + +* [PhoneGAP](http://phonegap.com/) (HTML/JavaScript/CSS, gets compiled and can be offered through AppStore; standalone apps) + * [nachbaur.com](http://blog.nachbaur.com/2009/04/native-ui-controls-in-phonegap-coming.html) native UI controls in PhoneGap +* [Big Five](http://www.big5apps.com/) (HTML/JavaScript/CSS, runs off the web → slow when switching pages, needs Big5-Launcher) + + +Web-Apps +======== + +* [iUI](http://joehewitt.com/files/iphone/navigation.html) iPhone navigation emulated using JavaScript and CSS ([Google Code project](http://code.google.com/p/iui/)) +* [CiUI](http://www.clientcide.com/cnet-js-standards/ciui-cnet-iphone-ui/) similar to iUI +* [Moousture](http://neofreeman.freepgs.com/Moousture/iphone.html) finger-gesture control diff --git a/know-how/hardware/apple-iphone/_posts/2010-05-17-airvideo-server-linux.md b/know-how/hardware/apple-iphone/_posts/2010-05-17-airvideo-server-linux.md new file mode 100644 index 0000000..439e2cf --- /dev/null +++ b/know-how/hardware/apple-iphone/_posts/2010-05-17-airvideo-server-linux.md @@ -0,0 +1,83 @@ +--- +title: AirVideo Server under Linux +layout: default +created: 2010-02-16 21:28:54 +0100 +updated: 2010-05-17 14:45:34 +0200 +toc: false +tags: + - know-how + - hardware + - apple + - iphone + - airvideo + - multimedia +--- +*[AirVideo](http://www.inmethod.com/air-video/)* is a Client/Server-Mediaplayer, which allows you to stream videos +directly from your PC to your iPhone. Its server software started as Windows-/Mac-only but now there's also a Linux +server module available, too. + +All details are explained in [their user forums](http://www.inmethod.com/forum/posts/list/34.page). + + +Compile the special FFmpeg under Ubuntu +======================================= + +1. download the customized version of *FFmpeg* from: + (use the 2.2.5 version!) and unpack it to some directory +1. install the following packages: [libmp3lame-dev](apt://libmp3lame-dev), [libfaad-dev](apt://libfaad-dev), + [libx264-dev](apt://libx264-dev) (`0.svn20100115-0.0~kkstemp1` from [Stéphane Marguet's PPA](https://launchpad.net/~stemp/+archive/ppa)!), + [mpeg4ip-server](apt://mpeg4ip-server), [git-core](apt://git-core), [pkg-config](apt://pkg-config) + 1. change to the directory to where you have unpacked *FFmpeg* + 1. run: +{% highlight bash %} +$ ./configure --enable-pthreads --disable-shared --enable-static --enable-gpl --enable-libx264 --enable-libmp3lame --enable-libfaad --disable-decoder=aac +$ make +{% endhighlight %} +1. after the build is complete, download the `AirVideoServerLinux.jar` and `test.properties` from [this posting](http://www.inmethod.com/forum/posts/list/60/34.page#3935) (**UPDATE:** [Newer version](http://www.inmethod.com/forum/posts/list/120/34.page#5252)) +1. modify the `test.properties` and fix the paths to the 3 tools and your video directory: + * `path.ffmpeg` should point to your just compiled `ffmpeg`-binary + * `path.mp4creator` is `/usr/bin/mp4creator` + * `path.faac` is `/usr/bin/faac` + * `folders` format is: *\*`:`*\*`,`*\*`:`*\*`,`…`,`*\*`:`*\* + * leave the other options as they are +1. finally you can run: +{% highlight bash %} +java -jar AirVideoServerLinux.jar test.properties +{% endhighlight %} +1. manually add the server (by its IP!) to *AirVideo* on your iPhone +1. Have fun! + + +Autostart AirVideoServer +======================== + +To autostart *AirVideoServer* upon bootup, you can use [UpStart](http://upstart.ubuntu.com/) which is the default +way in *Karmic Koala*. + +Just create a file `/etc/init/airvideo.conf` with these contents: + +~~~ +start on runlevel [2345] +stop on shutdown +respawn + +exec sudo -H -n -u mbirth /usr/bin/java -jar /opt/AirVideoServer/AirVideoServerLinux.jar /opt/AirVideoServer/test.properties +~~~ + +This will tell *UpStart* to run the server process as user `mbirth` upon reaching one of the runlevels 2-5 and stop the +server when the system shuts down. `respawn` tells it to restart the server if it crashed. + +You can also control it manually by doing + + sudo start airvideo + +or + + sudo stop airvideo + + +Bonjour Announcement +==================== + +*jcheshire* pointed out how to add *AirVideo* to the [avahi-daemon](apt://avahi-daemon), so that it is automatically +recognized by the clients. Read more in the [AirVideo forums](http://www.inmethod.com/forum/posts/list/165/34.page#6907). diff --git a/know-how/software/_posts/2010-06-08-appcelerator-titanium.md b/know-how/software/_posts/2010-06-08-appcelerator-titanium.md new file mode 100644 index 0000000..5743c71 --- /dev/null +++ b/know-how/software/_posts/2010-06-08-appcelerator-titanium.md @@ -0,0 +1,91 @@ +--- +title: appcelerator Titanium Framework +layout: default +created: 2010-04-02 18:06:40 +0200 +updated: 2010-06-08 09:53:45 +0200 +toc: true +tags: + - know-how + - software + - framework + - appcelerator + - titanium +--- +* **Homepage:** +* **API Docs:** + + +Generate JSDoc file for your IDE +================================ + +To get auto-completion for the Titanium framework, you have to let your IDE know of all available methods and +properties. Most IDEs can do this by parsing a JavaScript file. If you add JSDoc tags to it, you will even have +descriptions, parameter hints, etc. + +For more information about JSDoc, take a look at these links: + +* +* +* + +My very first try was with the 0.8.3 API and I created a JSDoc tagged JavaScript file by hand. The file is still +available here: [titanium.js]({{ site.url }}/assets/titanium.js) + +Now there's a file [apicoverage.json](http://github.com/appcelerator/titanium_mobile/blob/master/site_scons/apicoverage.json) +available from the *Titanium Mobile* Git repository which contains names and descriptions of all the functions. +You just have to get this into JavaScript code for your IDE to understand. + +I wrote a Python3 script, which parses the JSON of the `apicoverage.json` file and generates a dummy JavaScript +file for your IDE. To get that file, first run: + + wget -N http://github.com/appcelerator/titanium_mobile/raw/master/site_scons/apicoverage.json + +After that, download this script, put it into the same directory and on Linux make it executable (`chmod a+x genapidoc.py`): + + * [genapidoc.py]({{ site.url }}/assets/genapidoc.py) + +Now you only have to run this command: + + genapidoc.py > Titanium.js + +or on Windows run this (make sure you installed [Python 3.x.x](http://python.org/download/)): + + python.exe genapidoc.py > Titanium.js + + +Problems in Linux +================= + +Doesn't start on Lucid +---------------------- + +If *Titanium Developer* doesn't start on *Ubuntu Lucid* complaining about `/usr/lib/libgtk-x11-2.0.so.0`, go +to `$TITANIUM/runtime/linux/1.0.0` and delete the files `libgobject*`, `libglib*`, `libgio*` and `libgthread*`. +Maybe repeat that in older versions of the Runtime. + +See [support.appcelerator.net](http://support.appcelerator.net/discussions/support/2361-titanium-developer-10-wont-start-on-ubuntu-1004). + + +Can't install to device +----------------------- + +If you can't install apps to your device connected via USB, check the list of attached devices running the following +command (from the Android SDK): + +~~~ +$ ./adb devices +List of devices attached +???????????? no permissions +~~~ + +If you get a device listed as `???????????? no permissions`, do the following: + +~~~ +$ sudo ./adb kill-server +$ sudo ./adb start-server +$ ./adb devices +List of devices attached +HT9CVPxxxxxx device +~~~ + +See [this thread](http://www.google.com/support/forum/p/android/thread?tid=08945730bbd7b22b&hl=en) for details.