Compare commits

..

14 Commits

Author SHA1 Message Date
Andrew Grieve
d29eb84010 Tagging 2.4.0rc2 2013-01-30 09:51:40 -05:00
Joe Bowser
381ce535bf Merge branch 'puritytool' 2013-01-29 15:20:21 -08:00
Andrew Grieve
2e20bb0639 [CB-2293] Fix typo bufferSize->bytesRead.
Also adds a log statement to print out amount uploaded when an
IOException is thrown.
2013-01-29 13:47:15 -05:00
Joe Bowser
56cd24797e Fix for CB-2284. 401s are appearing when we hit them 2013-01-25 16:39:02 -08:00
Joe Bowser
431ca99c23 Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/cordova-android 2013-01-25 14:41:26 -08:00
Joe Bowser
6ced2ff293 CB-2292: Added a check for width and height. You can't scale nothing because you can't divide by zero. 2013-01-25 14:41:14 -08:00
Joe Bowser
31055bb303 Update to purity, adding better touch support 2013-01-25 14:39:44 -08:00
Fil Maj
24a53e39dd hey new line 2013-01-23 18:31:30 -08:00
Fil Maj
2ab113b695 Removing notice about incubation in the readme. 2013-01-23 12:21:49 -08:00
Fil Maj
9a0481a750 tweaking readme 2013-01-23 12:17:42 -08:00
Fil Maj
09035eb4c4 Setting template AndroidManifest values for version to 1.0 and code to 1. 2013-01-23 12:13:07 -08:00
Joe Bowser
1adf268e71 Updates to tests, including the use of Purity 2013-01-22 15:18:21 -08:00
Joe Bowser
23f57ad5a7 Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/cordova-android into puritytool 2013-01-21 14:59:04 -08:00
Joe Bowser
66f15fdd37 Adding purity to the test suite. Purity is a test class that may be renamed later 2013-01-18 15:00:02 -08:00
17 changed files with 818 additions and 466 deletions

View File

@@ -1,16 +1,12 @@
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.
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, applications written with web technology: HTML, CSS and JavaScript.
Apache Cordova is a project at The Apache Software Foundation (ASF).
Apache Cordova is an effort undergoing incubation at The Apache
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
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
---

View File

@@ -1 +1 @@
2.4.0rc1
2.4.0rc2

View File

@@ -18,7 +18,7 @@
under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
package="__PACKAGE__" android:versionName="1.1" android:versionCode="5" android:hardwareAccelerated="true">
package="__PACKAGE__" android:versionName="1.0" android:versionCode="1" android:hardwareAccelerated="true">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"

View File

@@ -33,7 +33,7 @@
<p class="event received">Device is Ready</p>
</div>
</div>
<script type="text/javascript" src="cordova-2.4.0rc1.js"></script>
<script type="text/javascript" src="cordova-2.4.0rc2.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();

View File

@@ -18,7 +18,7 @@
under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
package="org.apache.cordova" android:versionName="1.1" android:versionCode="5">
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"

View File

@@ -1,6 +1,8 @@
// commit 71223711fb1591b1255d871140d959fd9095f0c3
// Platform: android
// File generated at :: Mon Jan 21 2013 13:45:08 GMT-0800 (PST)
// commit e784eee3ce02dbd475e3c3f70031668f1706f2ec
// File generated at :: Wed Jan 30 2013 09:20:09 GMT-0500 (EST)
/*
Licensed to the Apache Software Foundation (ASF) under one

View File

@@ -19,7 +19,7 @@
<html>
<head>
<title></title>
<script src="cordova-2.4.0rc1.js"></script>
<script src="cordova-2.4.0rc2.js"></script>
</head>
<body>

View File

@@ -10,7 +10,7 @@
# Indicates whether an apk should be generated for each density.
split.density=false
# Project target.
target=android-17
target=Google Inc.:Google APIs:17
apk-configurations=
renderscript.opt.level=O0
android.library=true

View File

@@ -571,7 +571,13 @@ public class CameraLauncher extends CordovaPlugin implements MediaScannerConnect
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);
//CB-2292: WTF? Why is the width null?
if(options.outWidth == 0 || options.outHeight == 0)
{
return null;
}
// determine the correct aspect ratio
int[] widthHeight = calculateAspectRatio(options.outWidth, options.outHeight);

View File

@@ -230,6 +230,10 @@ public class CordovaWebViewClient extends WebViewClient {
AuthenticationToken token = this.getAuthenticationToken(host, realm);
if (token != null) {
handler.proceed(token.getUserName(), token.getPassword());
}
else {
// Handle 401 like we'd normally do!
super.onReceivedHttpAuthRequest(view, handler, host, realm);
}
}

View File

@@ -39,7 +39,7 @@ import android.telephony.TelephonyManager;
public class Device extends CordovaPlugin {
public static final String TAG = "Device";
public static String cordovaVersion = "2.4.0rc1"; // Cordova version
public static String cordovaVersion = "2.4.0rc2"; // Cordova version
public static String platform = "Android"; // Device OS
public static String uuid; // Device UUID

View File

@@ -215,6 +215,8 @@ public class FileTransfer extends CordovaPlugin {
HttpURLConnection conn = null;
HostnameVerifier oldHostnameVerifier = null;
SSLSocketFactory oldSocketFactory = null;
int totalBytes = 0;
int fixedLength = -1;
try {
// Create return object
FileUploadResult result = new FileUploadResult();
@@ -320,7 +322,6 @@ public class FileTransfer extends CordovaPlugin {
int stringLength = extraBytes.length + midParams.length() + tailParams.length() + fileNameBytes.length;
Log.d(LOG_TAG, "String Length: " + stringLength);
int fixedLength = -1;
if (sourceInputStream instanceof FileInputStream) {
fixedLength = (int) ((FileInputStream)sourceInputStream).getChannel().size() + stringLength;
progress.setLengthComputable(true);
@@ -363,13 +364,12 @@ public class FileTransfer extends CordovaPlugin {
// read file and write it into form...
int bytesRead = sourceInputStream.read(buffer, 0, bufferSize);
long totalBytes = 0;
long prevBytesRead = 0;
while (bytesRead > 0) {
totalBytes += bytesRead;
result.setBytesSent(totalBytes);
dos.write(buffer, 0, bufferSize);
dos.write(buffer, 0, bytesRead);
if (totalBytes > prevBytesRead + 102400) {
prevBytesRead = totalBytes;
Log.d(LOG_TAG, "Uploaded " + totalBytes + " of " + fixedLength + " bytes");
@@ -436,6 +436,7 @@ public class FileTransfer extends CordovaPlugin {
} catch (IOException e) {
JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);
Log.e(LOG_TAG, error.toString(), e);
Log.e(LOG_TAG, "Failed after uploading " + totalBytes + " of " + fixedLength + " bytes.");
context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);

View File

@@ -18,7 +18,7 @@
under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
package="org.apache.cordova.test" android:versionName="1.1" android:versionCode="5">
package="org.apache.cordova.test" android:versionName="1.0" android:versionCode="1">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"

File diff suppressed because it is too large Load Diff

View File

@@ -21,14 +21,72 @@ package org.apache.cordova.test;
*/
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.test.util.Purity;
import org.apache.cordova.test.actions.iframe;
import android.app.Activity;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.test.TouchUtils;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class IFrameTest extends ActivityInstrumentationTestCase2<iframe> {
public class IFrameTest extends ActivityInstrumentationTestCase2 {
public IFrameTest() {
super("org.apache.cordova.test",iframe.class);
}
private Instrumentation mInstr;
private Activity testActivity;
private FrameLayout containerView;
private LinearLayout innerContainer;
private CordovaWebView testView;
private TouchUtils touch;
private Purity touchTool;
public IFrameTest() {
super("org.apache.cordova.test",iframe.class);
}
protected void setUp() throws Exception {
super.setUp();
mInstr = this.getInstrumentation();
testActivity = this.getActivity();
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
innerContainer = (LinearLayout) containerView.getChildAt(0);
testView = (CordovaWebView) innerContainer.getChildAt(0);
touch = new TouchUtils();
touchTool = new Purity(testActivity, getInstrumentation());
}
public void testIframeDest()
{
testView.sendJavascript("loadUrl('http://maps.google.com/maps?output=embed');");
sleep(3000);
testView.sendJavascript("loadUrl('index2.html')");
sleep(1000);
String url = testView.getUrl();
assertTrue(url.endsWith("index.html"));
}
public void testIframeHistory()
{
testView.sendJavascript("loadUrl('http://maps.google.com/maps?output=embed');");
sleep(3000);
testView.sendJavascript("loadUrl('index2.html')");
sleep(1000);
String url = testView.getUrl();
testView.backHistory();
sleep(1000);
assertTrue(url.endsWith("index.html"));
}
private void sleep(int timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
fail("Unexpected Timeout");
}
}
}

View File

@@ -21,15 +21,55 @@ package org.apache.cordova.test;
*/
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.test.util.Purity;
import org.apache.cordova.test.actions.jqmtabbackbutton;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class JQMTabTest extends ActivityInstrumentationTestCase2<jqmtabbackbutton> {
public JQMTabTest(Class<jqmtabbackbutton> activityClass) {
super(activityClass);
// TODO Auto-generated constructor stub
private Instrumentation mInstr;
private jqmtabbackbutton testActivity;
private FrameLayout containerView;
private LinearLayout innerContainer;
private CordovaWebView testView;
private Purity touchTool;
public JQMTabTest()
{
super("org.apache.cordova.test.activity", jqmtabbackbutton.class);
}
protected void setUp() throws Exception {
super.setUp();
mInstr = this.getInstrumentation();
testActivity = this.getActivity();
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
innerContainer = (LinearLayout) containerView.getChildAt(0);
testView = (CordovaWebView) innerContainer.getChildAt(0);
touchTool = new Purity(testActivity, getInstrumentation());
}
public void testTouch()
{
sleep(5000);
int viewportHeight = touchTool.getViewportHeight() - 40;
int viewportWidth = touchTool.getViewportWidth();
touchTool.touch(50, viewportHeight);
sleep(10000);
}
private void sleep(int timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
fail("Unexpected Timeout");
}
}
}

View File

@@ -0,0 +1,171 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
/*
* Purity is a small set of Android utility methods that allows us to simulate touch events on
* Android applications. This is important for simulating some of the most annoying tests.
*/
package org.apache.cordova.test.util;
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Picture;
import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.webkit.WebView;
public class Purity {
Instrumentation inst;
int width, height;
float density;
Bitmap state;
boolean fingerDown = false;
public Purity(Context ctx, Instrumentation i)
{
inst = i;
DisplayMetrics display = ctx.getResources().getDisplayMetrics();
density = display.density;
width = display.widthPixels;
height = display.heightPixels;
}
/*
* WebKit doesn't give you real pixels anymore, this is done for subpixel fonts to appear on
* iOS and Android. However, Android automation requires real pixels
*/
private int getRealCoord(int coord)
{
return (int) (coord * density);
}
public int getViewportWidth()
{
return (int) (width/density);
}
public int getViewportHeight()
{
return (int) (height/density);
}
public void touch(int x, int y)
{
int realX = getRealCoord(x);
int realY = getRealCoord(y);
long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
if(!fingerDown)
{
MotionEvent downEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, realX, realY, 0);
inst.sendPointerSync(downEvent);
}
MotionEvent upEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, realX, realY, 0);
inst.sendPointerSync(upEvent);
}
public void touchStart(int x, int y)
{
int realX = getRealCoord(x);
int realY = getRealCoord(y);
long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, realX, realY, 0);
inst.sendPointerSync(event);
fingerDown = true;
}
//Move from the touch start
public void touchMove(int x, int y)
{
if(!fingerDown)
touchStart(x,y);
else
{
int realX = getRealCoord(x);
int realY = getRealCoord(y);
long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, realX, realY, 0);
inst.sendPointerSync(event);
}
}
public void touchEnd(int x, int y)
{
if(!fingerDown)
{
touch(x, y);
}
else
{
int realX = getRealCoord(x);
int realY = getRealCoord(y);
long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, realX, realY, 0);
inst.sendPointerSync(event);
fingerDown = false;
}
}
public void setBitmap(WebView view)
{
Picture p = view.capturePicture();
state = Bitmap.createBitmap(p.getWidth(), p.getHeight(), Bitmap.Config.ARGB_8888);
}
public boolean checkRenderView(WebView view)
{
if(state == null)
{
setBitmap(view);
return false;
}
else
{
Picture p = view.capturePicture();
Bitmap newState = Bitmap.createBitmap(p.getWidth(), p.getHeight(), Bitmap.Config.ARGB_8888);
boolean result = newState.equals(state);
newState.recycle();
return result;
}
}
public void clearBitmap()
{
if(state != null)
state.recycle();
}
protected void finalize()
{
clearBitmap();
}
}