From b106d2cae8419d4a82d1c37499ef19422a4f59de Mon Sep 17 00:00:00 2001 From: macdonst Date: Thu, 5 Jan 2012 01:49:48 +0800 Subject: [PATCH 1/7] Proved generating sqlite database path to open database without permission error --- framework/src/com/phonegap/Storage.java | 40 +++++++------------------ 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/framework/src/com/phonegap/Storage.java b/framework/src/com/phonegap/Storage.java index fc74dc12..516f6b42 100755 --- a/framework/src/com/phonegap/Storage.java +++ b/framework/src/com/phonegap/Storage.java @@ -18,17 +18,22 @@ */ package com.phonegap; +import java.io.File; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.phonegap.api.Plugin; import com.phonegap.api.PluginResult; + +import android.content.Context; import android.database.Cursor; import android.database.sqlite.*; /** - * This class implements the HTML5 database support for Android 1.X devices. It - * is not used for Android 2.X, since HTML5 database is built in to the browser. + * This class implements the HTML5 database support to work around a bug for + * Android 3.0 devices. It is not used for other versions of Android, since + * HTML5 database is built in to the browser. */ public class Storage extends Plugin { @@ -64,11 +69,7 @@ public class Storage extends Plugin { String result = ""; try { - // TODO: Do we want to allow a user to do this, since they could get - // to other app databases? - if (action.equals("setStorage")) { - this.setStorage(args.getString(0)); - } else if (action.equals("openDatabase")) { + if (action.equals("openDatabase")) { this.openDatabase(args.getString(0), args.getString(1), args.getString(2), args.getLong(3)); } else if (action.equals("executeSql")) { @@ -118,21 +119,6 @@ public class Storage extends Plugin { // LOCAL METHODS // -------------------------------------------------------------------------- - /** - * Set the application package for the database. Each application saves its - * database files in a directory with the application package as part of the - * file name. - * - * For example, application "com.phonegap.demo.Demo" would save its database - * files in "/data/data/com.phonegap.demo/databases/" directory. - * - * @param appPackage - * The application package. - */ - public void setStorage(String appPackage) { - this.path = "/data/data/" + appPackage + "/databases/"; - } - /** * Open database. * @@ -155,12 +141,10 @@ public class Storage extends Plugin { // If no database path, generate from application package if (this.path == null) { - Package pack = this.ctx.getClass().getPackage(); - String appPackage = pack.getName(); - this.setStorage(appPackage); + this.path = this.ctx.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath(); } - this.dbName = this.path + db + ".db"; + this.dbName = this.path + File.pathSeparator + db + ".db"; this.myDb = SQLiteDatabase.openOrCreateDatabase(this.dbName, null); } @@ -249,9 +233,7 @@ public class Storage extends Plugin { } // Let JavaScript know that there are no more rows - this.sendJavascript("droiddb.completeQuery('" + tx_id + "', " + result - + ");"); - + this.sendJavascript("droiddb.completeQuery('" + tx_id + "', " + result + ");"); } } From 1d5af102c7f4e602f712fed7fdf59410b66002d5 Mon Sep 17 00:00:00 2001 From: macdonst Date: Thu, 5 Jan 2012 03:29:08 +0800 Subject: [PATCH 2/7] Camera default destination should be FILE_URI --- framework/assets/js/camera.js | 2 +- framework/src/com/phonegap/CameraLauncher.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/assets/js/camera.js b/framework/assets/js/camera.js index 17af89d7..e1467c63 100755 --- a/framework/assets/js/camera.js +++ b/framework/assets/js/camera.js @@ -127,7 +127,7 @@ Camera.prototype.getPicture = function(successCallback, errorCallback, options) options.maxResolution = 0; } if (options.destinationType === null || typeof options.destinationType === "undefined") { - options.destinationType = Camera.DestinationType.DATA_URL; + options.destinationType = Camera.DestinationType.FILE_URI; } if (options.sourceType === null || typeof options.sourceType === "undefined") { options.sourceType = Camera.PictureSourceType.CAMERA; diff --git a/framework/src/com/phonegap/CameraLauncher.java b/framework/src/com/phonegap/CameraLauncher.java index dd619a24..f9257857 100755 --- a/framework/src/com/phonegap/CameraLauncher.java +++ b/framework/src/com/phonegap/CameraLauncher.java @@ -101,7 +101,7 @@ public class CameraLauncher extends Plugin { try { if (action.equals("takePicture")) { int srcType = CAMERA; - int destType = DATA_URL; + int destType = FILE_URI; this.targetHeight = 0; this.targetWidth = 0; this.encodingType = JPEG; From e96ae9180034fc2c3b81276dfa444a5abaa3710e Mon Sep 17 00:00:00 2001 From: Olivier Brand Date: Wed, 4 Jan 2012 13:47:44 -0800 Subject: [PATCH 3/7] Added authentication framework --- .../src/com/phonegap/AuthenticationToken.java | 49 +++++++ framework/src/com/phonegap/DroidGap.java | 129 ++++++++++++++++-- 2 files changed, 170 insertions(+), 8 deletions(-) create mode 100644 framework/src/com/phonegap/AuthenticationToken.java diff --git a/framework/src/com/phonegap/AuthenticationToken.java b/framework/src/com/phonegap/AuthenticationToken.java new file mode 100644 index 00000000..a01acf1a --- /dev/null +++ b/framework/src/com/phonegap/AuthenticationToken.java @@ -0,0 +1,49 @@ +package com.phonegap; + +/** + * The Class AuthenticationToken defines the principal and credentials to be used for authenticating a web resource + */ +public class AuthenticationToken { + private String principal; + private String credentials; + + /** + * Gets the principal. + * + * @return the principal + */ + public String getPrincipal() { + return principal; + } + + /** + * Sets the principal. + * + * @param principal + * the new principal + */ + public void setPrincipal(String principal) { + this.principal = principal; + } + + /** + * Gets the credentials. + * + * @return the credentials + */ + public String getCredentials() { + return credentials; + } + + /** + * Sets the credentials. + * + * @param credentials + * the new credentials + */ + public void setCredentials(String credentials) { + this.credentials = credentials; + } + + +} diff --git a/framework/src/com/phonegap/DroidGap.java b/framework/src/com/phonegap/DroidGap.java index f9065676..6c13f11d 100755 --- a/framework/src/com/phonegap/DroidGap.java +++ b/framework/src/com/phonegap/DroidGap.java @@ -18,16 +18,18 @@ */ package com.phonegap; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.Stack; -import java.util.regex.Pattern; -import java.util.regex.Matcher; -import java.util.Iterator; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.json.JSONArray; import org.json.JSONException; +import org.xmlpull.v1.XmlPullParserException; import android.app.AlertDialog; import android.app.ProgressDialog; @@ -55,6 +57,7 @@ import android.view.Window; import android.view.WindowManager; import android.webkit.ConsoleMessage; import android.webkit.GeolocationPermissions.Callback; +import android.webkit.HttpAuthHandler; import android.webkit.JsPromptResult; import android.webkit.JsResult; import android.webkit.SslErrorHandler; @@ -67,11 +70,10 @@ import android.webkit.WebViewClient; import android.widget.EditText; import android.widget.LinearLayout; +import com.phonegap.api.IPlugin; import com.phonegap.api.LOG; import com.phonegap.api.PhonegapActivity; -import com.phonegap.api.IPlugin; import com.phonegap.api.PluginManager; -import org.xmlpull.v1.XmlPullParserException; /** * This class is the main Android activity that represents the PhoneGap @@ -199,6 +201,9 @@ public class DroidGap extends PhonegapActivity { // (this is not the color for the webview, which is set in HTML) private int backgroundColor = Color.BLACK; + /** The authorization tokens. */ + private Hashtable authenticationTokens = new Hashtable(); + /* * The variables below are used to cache some of the activity properties. */ @@ -215,6 +220,88 @@ public class DroidGap extends PhonegapActivity { // when another application (activity) is started. protected boolean keepRunning = true; + /** + * Sets the authentication token. + * + * @param authenticationToken + * the authentication token + * @param host + * the host + * @param realm + * the realm + */ + public void setAuthenticationToken(AuthenticationToken authenticationToken, String host, String realm) { + + if(host == null) { + host = ""; + } + + if(realm == null) { + realm = ""; + } + + authenticationTokens.put(host.concat(realm), authenticationToken); + } + + /** + * Removes the authentication token. + * + * @param host + * the host + * @param realm + * the realm + * @return the authentication token or null if did not exist + */ + public AuthenticationToken removeAuthenticationToken(String host, String realm) { + return authenticationTokens.remove(host.concat(realm)); + } + + /** + * Gets the authentication token. + * + * In order it tries: + * 1- host + realm + * 2- host + * 3- realm + * 4- no host, no realm + * + * @param host + * the host + * @param realm + * the realm + * @return the authentication token + */ + public AuthenticationToken getAuthenticationToken(String host, String realm) { + AuthenticationToken token = null; + + token = authenticationTokens.get(host.concat(realm)); + + if(token == null) { + // try with just the host + token = authenticationTokens.get(host); + + // Try the realm + if(token == null) { + token = authenticationTokens.get(realm); + } + + // if no host found, just query for default + if(token == null) { + token = authenticationTokens.get(""); + } + } + + return token; + } + + /** + * Clear all authentication tokens. + */ + public void clearAuthenticationTokens() { + authenticationTokens.clear(); + } + + /** * Called when the activity is first created. * @@ -1344,6 +1431,32 @@ public class DroidGap extends PhonegapActivity { return true; } + /** + * On received http auth request. + * The method reacts on all registered authentication tokens. There is one and only one authentication token for any host + realm combination + * + * @param view + * the view + * @param handler + * the handler + * @param host + * the host + * @param realm + * the realm + */ + @Override + public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, + String realm) { + + // get the authentication token + AuthenticationToken token = getAuthenticationToken(host,realm); + + if(token != null) { + handler.proceed(token.getPrincipal(), token.getCredentials()); + } + } + + @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { From 36bca7d6094bc1d7c9efa37c377f1f760b617407 Mon Sep 17 00:00:00 2001 From: Olivier Brand Date: Thu, 5 Jan 2012 08:26:54 -0800 Subject: [PATCH 4/7] Renamed crdentials/principals to userName/password --- .../src/com/phonegap/AuthenticationToken.java | 44 ++++++++++--------- framework/src/com/phonegap/DroidGap.java | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/framework/src/com/phonegap/AuthenticationToken.java b/framework/src/com/phonegap/AuthenticationToken.java index a01acf1a..9b759aad 100644 --- a/framework/src/com/phonegap/AuthenticationToken.java +++ b/framework/src/com/phonegap/AuthenticationToken.java @@ -1,49 +1,51 @@ package com.phonegap; /** - * The Class AuthenticationToken defines the principal and credentials to be used for authenticating a web resource + * The Class AuthenticationToken defines the userName and password to be used for authenticating a web resource */ public class AuthenticationToken { - private String principal; - private String credentials; + private String userName; + private String password; /** - * Gets the principal. + * Gets the user name. * - * @return the principal + * @return the user name */ - public String getPrincipal() { - return principal; + public String getUserName() { + return userName; } /** - * Sets the principal. + * Sets the user name. * - * @param principal - * the new principal + * @param userName + * the new user name */ - public void setPrincipal(String principal) { - this.principal = principal; + public void setUserName(String userName) { + this.userName = userName; } /** - * Gets the credentials. + * Gets the password. * - * @return the credentials + * @return the password */ - public String getCredentials() { - return credentials; + public String getPassword() { + return password; } /** - * Sets the credentials. + * Sets the password. * - * @param credentials - * the new credentials + * @param password + * the new password */ - public void setCredentials(String credentials) { - this.credentials = credentials; + public void setPassword(String password) { + this.password = password; } + + } diff --git a/framework/src/com/phonegap/DroidGap.java b/framework/src/com/phonegap/DroidGap.java index 6c13f11d..378f4f44 100755 --- a/framework/src/com/phonegap/DroidGap.java +++ b/framework/src/com/phonegap/DroidGap.java @@ -1452,7 +1452,7 @@ public class DroidGap extends PhonegapActivity { AuthenticationToken token = getAuthenticationToken(host,realm); if(token != null) { - handler.proceed(token.getPrincipal(), token.getCredentials()); + handler.proceed(token.getUserName(), token.getPassword()); } } From e9eb08486af832afc650df016cb17347858dd671 Mon Sep 17 00:00:00 2001 From: Jukka Zitting Date: Thu, 5 Jan 2012 21:33:26 +0100 Subject: [PATCH 5/7] README.md: Replace "PhoneGap" with "Cordova" and add incubation disclaimer (This is a test commit to for checking the git push problem by Bryce) --- README.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 59431ec0..15e0ae27 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,16 @@ -PhoneGap Android +Cordova Android === -PhoneGap Android is an Android application library that allows for PhoneGap based projects to be built for the Android Platform. PhoneGap based applications are, at the core, an application written with web technology: HTML, CSS and JavaScript. +Cordova Android is an Android application library that allows for Cordova based projects to be built for the Android Platform. Cordova based applications are, at the core, an application written with web technology: HTML, CSS and JavaScript. + +Apache Cordova is an effort undergoing incubation at The Apache +Software Foundation (ASF), sponsored by the name of Apache Incubator. +Incubation is required of all newly accepted projects until a further +review indicates that the infrastructure, communications, and decision +making process have stabilized in a manner consistent with other +successful ASF projects. While incubation status is not necessarily +a reflection of the completeness or stability of the code, it does +indicate that the project has yet to be fully endorsed by the ASF. Requires --- @@ -10,21 +19,21 @@ Requires - Apache ANT - Android SDK [http://developer.android.com](http://developer.android.com) -PhoneGap Android Developer Tools +Cordova Android Developer Tools --- -The PhoneGap developer tooling is split between general tooling and project level tooling. +The Cordova developer tooling is split between general tooling and project level tooling. General Commands - ./bin/create [path package activity] ... create the ./example app or a phonegap android project + ./bin/create [path package activity] ... create the ./example app or a cordova android project ./bin/bench ............................ generate a bench proj ./bin/autotest ......................... test the cli tools ./bin/test ............................. run mobile-spec Project Commands -These commands live in a generated PhoneGap Android project. +These commands live in a generated Cordova Android project. ./phonegap/debug [path] ..................... install to first device ./phonegap/emulate .......................... start avd (emulator) named default @@ -52,12 +61,12 @@ Running the [callback/callback-test](http://github.com/callback/callback-test) t ./bin/test -Creating a new PhoneGap Android Project +Creating a new Cordova Android Project --- ./bin/create ~/Desktop/myapp com.phonegap.special MyApp -Importing a PhoneGap Android Project into Eclipse +Importing a Cordova Android Project into Eclipse ---- 1. File > New > Project... From 4bba9ac5a00aa313ada3bc27bb35c01c3685808d Mon Sep 17 00:00:00 2001 From: Jukka Zitting Date: Thu, 5 Jan 2012 21:39:18 +0100 Subject: [PATCH 6/7] Minor incubation disclaimer fix. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15e0ae27..1f615532 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Cordova Android Cordova Android is an Android application library that allows for Cordova based projects to be built for the Android Platform. Cordova based applications are, at the core, an application written with web technology: HTML, CSS and JavaScript. Apache Cordova is an effort undergoing incubation at The Apache -Software Foundation (ASF), sponsored by the name of Apache Incubator. +Software Foundation (ASF), sponsored by the Apache Incubator project. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other From 58774addadda57313a2ea621ffdadd7fdf5e5388 Mon Sep 17 00:00:00 2001 From: macdonst Date: Sat, 7 Jan 2012 05:26:26 +0800 Subject: [PATCH 7/7] CB-145: Android contact.save() crashes for native contacts. --- .../src/com/phonegap/ContactAccessorSdk5.java | 79 +++++++++---------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/framework/src/com/phonegap/ContactAccessorSdk5.java b/framework/src/com/phonegap/ContactAccessorSdk5.java index 9e9cee20..47a8111f 100644 --- a/framework/src/com/phonegap/ContactAccessorSdk5.java +++ b/framework/src/com/phonegap/ContactAccessorSdk5.java @@ -819,50 +819,49 @@ public class ContactAccessorSdk5 extends ContactAccessor { public String save(JSONObject contact) { AccountManager mgr = AccountManager.get(mApp); Account[] accounts = mgr.getAccounts(); - Account account = null; + String accountName = null; + String accountType = null; - if (accounts.length == 1) - account = accounts[0]; - else if (accounts.length > 1) { - for(Account a : accounts){ - if(a.type.contains("eas")&& a.name.matches(EMAIL_REGEXP)) /*Exchange ActiveSync*/ - { - account = a; - break; - } - } - if(account == null){ - for(Account a : accounts){ - if(a.type.contains("com.google") && a.name.matches(EMAIL_REGEXP)) /*Google sync provider*/ - { - account = a; - break; - } - } - } - if(account == null){ - for(Account a : accounts){ - if(a.name.matches(EMAIL_REGEXP)) /*Last resort, just look for an email address...*/ - { - account = a; - break; - } - } - } + if (accounts.length == 1) { + accountName = accounts[0].name; + accountType = accounts[0].type; } - - if(account == null) { - return null; + else if (accounts.length > 1) { + for(Account a : accounts) { + if(a.type.contains("eas")&& a.name.matches(EMAIL_REGEXP)) /*Exchange ActiveSync*/ { + accountName = a.name; + accountType = a.type; + break; + } + } + if(accountName == null){ + for(Account a : accounts){ + if(a.type.contains("com.google") && a.name.matches(EMAIL_REGEXP)) /*Google sync provider*/ { + accountName = a.name; + accountType = a.type; + break; + } + } + } + if(accountName == null){ + for(Account a : accounts){ + if(a.name.matches(EMAIL_REGEXP)) /*Last resort, just look for an email address...*/ { + accountName = a.name; + accountType = a.type; + break; + } + } + } } String id = getJsonString(contact, "id"); // Create new contact if (id == null) { - return createNewContact(contact, account); + return createNewContact(contact, accountType, accountName); } // Modify existing contact else { - return modifyContact(id, contact, account); + return modifyContact(id, contact, accountType, accountName); } } @@ -873,7 +872,7 @@ public class ContactAccessorSdk5 extends ContactAccessor { * @param contact the contact to be saved * @param account the account to be saved under */ - private String modifyContact(String id, JSONObject contact, Account account) { + private String modifyContact(String id, JSONObject contact, String accountType, String accountName) { // Get the RAW_CONTACT_ID which is needed to insert new values in an already existing contact. // But not needed to update existing values. int rawId = (new Integer(getJsonString(contact,"rawId"))).intValue(); @@ -883,8 +882,8 @@ public class ContactAccessorSdk5 extends ContactAccessor { //Add contact type ops.add(ContentProviderOperation.newUpdate(ContactsContract.RawContacts.CONTENT_URI) - .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type) - .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, account.name) + .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType) + .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName) .build()); // Modify name @@ -1427,14 +1426,14 @@ public class ContactAccessorSdk5 extends ContactAccessor { * @param contact the contact to be saved * @param account the account to be saved under */ - private String createNewContact(JSONObject contact, Account account) { + private String createNewContact(JSONObject contact, String accountType, String accountName) { // Create a list of attributes to add to the contact database ArrayList ops = new ArrayList(); //Add contact type ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) - .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type) - .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, account.name) + .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType) + .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName) .build()); // Add name