am 705a3ee: AI 147793: cleanup broken links and delete all innacurate in
Merge commit '705a3ee3975877460c124d98eda12ae16dadd1a6' into donut
* commit '705a3ee3975877460c124d98eda12ae16dadd1a6':
AI 147793: cleanup broken links and delete all innacurate info in apidemo pages
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b25c15b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*~
diff --git a/apps/Fallback/res/values-es-rUS/strings.xml b/apps/Fallback/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..0ce5751
--- /dev/null
+++ b/apps/Fallback/res/values-es-rUS/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="appTitle">"Fallback"</string>
+ <string name="title">"Acción no admitida"</string>
+ <string name="error">"Esa acción no se admite actualmente."</string>
+</resources>
diff --git a/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java b/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
index db6385c..56f43a4 100644
--- a/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
+++ b/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
@@ -38,9 +38,7 @@
// Enable the GPS.
// Not needed since this SDK will contain the Settings app.
- LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, LocationManager.GPS_PROVIDER);
- locationManager.updateProviders();
// enable install from non market
Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1);
diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
index 00fb40c..5e9f07c 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -130,7 +130,8 @@
float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT];
MonkeyEventSource mEventSource;
-
+ private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
+
/**
* Monitor operations happening in the system.
*/
@@ -222,14 +223,14 @@
return 1;
}
}
-
+
/**
* Run the procrank tool to insert system status information into the debug report.
*/
private void reportProcRank() {
commandLineReport("procrank", "procrank");
}
-
+
/**
* Run "cat /data/anr/traces.txt". Wait about 5 seconds first, to let the asynchronous
* report writing complete.
@@ -362,7 +363,7 @@
if (mScriptFileName != null) {
// script mode, ignore other options
- mEventSource = new MonkeySourceScript(mScriptFileName);
+ mEventSource = new MonkeySourceScript(mScriptFileName, mThrottle);
mEventSource.setVerbose(mVerbose);
} else {
// random source by default
@@ -401,7 +402,9 @@
signalPersistentProcesses();
}
+ mNetworkMonitor.start();
int crashedAtCycle = runMonkeyCycles();
+ mNetworkMonitor.stop();
synchronized (this) {
if (mRequestAnrTraces) {
@@ -423,6 +426,7 @@
try {
mAm.setActivityWatcher(null);
+ mNetworkMonitor.unregister(mAm);
} catch (RemoteException e) {
// just in case this was latent (after mCount cycles), make sure
// we report it
@@ -442,6 +446,9 @@
System.out.print(" flips=");
System.out.println(mDroppedFlipEvents);
}
+
+ // report network stats
+ mNetworkMonitor.dump();
if (crashedAtCycle < mCount - 1) {
System.err.println("** System appears to have crashed at event "
@@ -602,6 +609,7 @@
try {
mAm.setActivityWatcher(new ActivityWatcher());
+ mNetworkMonitor.register(mAm);
} catch (RemoteException e) {
System.err.println("** Failed talking with activity manager!");
return false;
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
index 7176073..d926be8 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
@@ -51,6 +51,14 @@
}
/**
+ * @return true if it is safe to throttle after this event, and false otherwise.
+ */
+ public boolean isThrottlable() {
+ return true;
+ }
+
+
+ /**
* a method for injecting event
* @param iwm wires to current window manager
* @param iam wires to current activity manager
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEventQueue.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEventQueue.java
new file mode 100644
index 0000000..dfe389a
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEventQueue.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.monkey;
+
+import java.util.LinkedList;
+
+/**
+ * class for keeping a monkey event queue
+ */
+@SuppressWarnings("serial")
+public class MonkeyEventQueue extends LinkedList<MonkeyEvent> {
+
+ private long mThrottle;
+
+ public MonkeyEventQueue(long throttle) {
+ super();
+ mThrottle = throttle;
+ }
+
+ @Override
+ public void addLast(MonkeyEvent e) {
+ super.add(e);
+ if (e.isThrottlable()) {
+ super.add(new MonkeyThrottleEvent(mThrottle));
+ }
+ }
+}
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
index c1e0ffc..877ebb5 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
@@ -92,6 +92,11 @@
}
@Override
+ public boolean isThrottlable() {
+ return (getAction() == KeyEvent.ACTION_UP);
+ }
+
+ @Override
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
if (verbose > 1) {
String note;
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
index 2657061..81c64b4 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
@@ -20,6 +20,7 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.view.IWindowManager;
+import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -124,6 +125,11 @@
}
@Override
+ public boolean isThrottlable() {
+ return (getAction() == KeyEvent.ACTION_UP);
+ }
+
+ @Override
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
String note;
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyNetworkMonitor.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyNetworkMonitor.java
new file mode 100644
index 0000000..e8d9812
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyNetworkMonitor.java
@@ -0,0 +1,105 @@
+/**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.commands.monkey;
+
+import android.app.IActivityManager;
+import android.app.IIntentReceiver;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.SystemClock;
+
+/**
+ * Class for monitoring network connectivity during monkey runs.
+ */
+public class MonkeyNetworkMonitor extends IIntentReceiver.Stub {
+ private static final boolean LDEBUG = false;
+ private final IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+ private long mCollectionStartTime; // time we started collecting data
+ private long mEventTime; // time of last event (connect, disconnect, etc.)
+ private int mLastNetworkType = -1; // unknown
+ private long mWifiElapsedTime = 0; // accumulated time spent on wifi since start()
+ private long mMobileElapsedTime = 0; // accumulated time spent on mobile since start()
+ private long mElapsedTime = 0; // amount of time spent between start() and stop()
+
+ public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
+ boolean ordered) throws RemoteException {
+ NetworkInfo ni = (NetworkInfo) intent.getParcelableExtra(
+ ConnectivityManager.EXTRA_NETWORK_INFO);
+ if (LDEBUG) System.out.println("Network state changed: "
+ + "type=" + ni.getType() + ", state=" + ni.getState());
+ updateNetworkStats();
+ if (NetworkInfo.State.CONNECTED == ni.getState()) {
+ if (LDEBUG) System.out.println("Network connected");
+ mLastNetworkType = ni.getType();
+ } else if (NetworkInfo.State.DISCONNECTED == ni.getState()) {
+ if (LDEBUG) System.out.println("Network not connected");
+ mLastNetworkType = -1; // unknown since we're disconnected
+ }
+ mEventTime = SystemClock.elapsedRealtime();
+ }
+
+ private void updateNetworkStats() {
+ long timeNow = SystemClock.elapsedRealtime();
+ long delta = timeNow - mEventTime;
+ switch (mLastNetworkType) {
+ case ConnectivityManager.TYPE_MOBILE:
+ if (LDEBUG) System.out.println("Adding to mobile: " + delta);
+ mMobileElapsedTime += delta;
+ break;
+ case ConnectivityManager.TYPE_WIFI:
+ if (LDEBUG) System.out.println("Adding to wifi: " + delta);
+ mWifiElapsedTime += delta;
+ break;
+ default:
+ if (LDEBUG) System.out.println("Unaccounted for: " + delta);
+ break;
+ }
+ mElapsedTime = timeNow - mCollectionStartTime;
+ }
+
+ public void start() {
+ mWifiElapsedTime = 0;
+ mMobileElapsedTime = 0;
+ mElapsedTime = 0;
+ mEventTime = mCollectionStartTime = SystemClock.elapsedRealtime();
+ }
+
+ public void register(IActivityManager am) throws RemoteException {
+ if (LDEBUG) System.out.println("registering Receiver");
+ am.registerReceiver(null, this, filter, null);
+ }
+
+ public void unregister(IActivityManager am) throws RemoteException {
+ if (LDEBUG) System.out.println("unregistering Receiver");
+ am.unregisterReceiver(this);
+ }
+
+ public void stop() {
+ updateNetworkStats();
+ }
+
+ public void dump() {
+ System.out.println("## Network stats: elapsed time=" + mElapsedTime + "ms ("
+ + mMobileElapsedTime + "ms mobile, "
+ + mWifiElapsedTime + "ms wifi, "
+ + (mElapsedTime - mMobileElapsedTime - mWifiElapsedTime) + "ms not connected)");
+ }
+ }
\ No newline at end of file
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
index 902d8e8..5f9c10f 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
@@ -31,7 +31,7 @@
/**
* monkey event queue
*/
-public class MonkeySourceRandom implements MonkeyEventSource{
+public class MonkeySourceRandom implements MonkeyEventSource {
/** Key events that move around the UI. */
private static final int[] NAV_KEYS = {
KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
@@ -168,7 +168,7 @@
private float[] mFactors = new float[FACTORZ_COUNT];
private ArrayList<ComponentName> mMainApps;
private int mEventCount = 0; //total number of events generated so far
- private LinkedList<MonkeyEvent> mQ = new LinkedList<MonkeyEvent>();
+ private MonkeyEventQueue mQ;
private Random mRandom;
private int mVerbose = 0;
private long mThrottle = 0;
@@ -203,7 +203,7 @@
mRandom = new SecureRandom();
mRandom.setSeed((seed == 0) ? -1 : seed);
mMainApps = MainApps;
- mThrottle = throttle;
+ mQ = new MonkeyEventQueue(throttle);
}
/**
@@ -336,7 +336,6 @@
downAt, MotionEvent.ACTION_UP, x, y, 0);
e.setIntermediateNote(false);
mQ.addLast(e);
- addThrottle();
}
/**
@@ -387,7 +386,6 @@
e.setIntermediateNote(false);
mQ.addLast(e);
}
- addThrottle();
}
/**
@@ -420,13 +418,11 @@
MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
mRandom.nextInt(mMainApps.size())));
mQ.addLast(e);
- addThrottle();
return;
} else if (cls < mFactors[FACTOR_FLIP]) {
MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
mKeyboardOpen = !mKeyboardOpen;
mQ.addLast(e);
- addThrottle();
return;
} else {
lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
@@ -437,8 +433,6 @@
e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
mQ.addLast(e);
-
- addThrottle();
}
public boolean validate() {
@@ -472,8 +466,4 @@
mQ.removeFirst();
return e;
}
-
- private void addThrottle() {
- mQ.addLast(new MonkeyThrottleEvent(MonkeyEvent.EVENT_TYPE_THROTTLE, mThrottle));
- }
}
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
index aadda9f..869af2c 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
@@ -35,18 +35,19 @@
* type= raw events
* count= 10
* speed= 1.0
+ * start data >>
* captureDispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314,
* 0.06666667,0,0.0,0.0,65539,0)
* captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
* captureDispatchFlip(true)
* ...
*/
-public class MonkeySourceScript implements MonkeyEventSource{
+public class MonkeySourceScript implements MonkeyEventSource {
private int mEventCountInScript = 0; //total number of events in the file
private int mVerbose = 0;
private double mSpeed = 1.0;
private String mScriptFileName;
- private LinkedList<MonkeyEvent> mQ = new LinkedList<MonkeyEvent>();
+ private MonkeyEventQueue mQ;
private static final String HEADER_TYPE = "type=";
private static final String HEADER_COUNT = "count=";
@@ -80,12 +81,14 @@
// a line at the end of the header
private static final String STARTING_DATA_LINE = "start data >>";
private boolean mFileOpened = false;
+
FileInputStream mFStream;
DataInputStream mInputStream;
BufferedReader mBufferReader;
- public MonkeySourceScript(String filename) {
+ public MonkeySourceScript(String filename, long throttle) {
mScriptFileName = filename;
+ mQ = new MonkeyEventQueue(throttle);
}
/**
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyThrottleEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyThrottleEvent.java
index 3d7d48a..0b4e6b6 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyThrottleEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyThrottleEvent.java
@@ -16,11 +16,10 @@
package com.android.commands.monkey;
+import java.util.List;
+
import android.app.IActivityManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
import android.view.IWindowManager;
-import android.view.MotionEvent;
/**
@@ -29,8 +28,8 @@
public class MonkeyThrottleEvent extends MonkeyEvent {
private long mThrottle;
- public MonkeyThrottleEvent(int type, long throttle) {
- super(type);
+ public MonkeyThrottleEvent(long throttle) {
+ super(MonkeyEvent.EVENT_TYPE_THROTTLE);
mThrottle = throttle;
}
diff --git a/docs/copyright-templates/asm.txt b/docs/copyright-templates/asm.txt
new file mode 100644
index 0000000..95a9022
--- /dev/null
+++ b/docs/copyright-templates/asm.txt
@@ -0,0 +1,13 @@
+; Copyright (C) 2009 The Android Open Source Project
+;
+; Licensed 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.
diff --git a/docs/copyright-templates/bash.txt b/docs/copyright-templates/bash.txt
new file mode 100644
index 0000000..ecf510e
--- /dev/null
+++ b/docs/copyright-templates/bash.txt
@@ -0,0 +1,15 @@
+#!/bin/bash
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed 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.
diff --git a/docs/copyright-templates/bsd/c.txt b/docs/copyright-templates/bsd/c.txt
new file mode 100644
index 0000000..c574b4a
--- /dev/null
+++ b/docs/copyright-templates/bsd/c.txt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
diff --git a/docs/copyright-templates/c.txt b/docs/copyright-templates/c.txt
new file mode 100644
index 0000000..7cd7083
--- /dev/null
+++ b/docs/copyright-templates/c.txt
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
diff --git a/docs/copyright-templates/java.txt b/docs/copyright-templates/java.txt
new file mode 100644
index 0000000..7cd7083
--- /dev/null
+++ b/docs/copyright-templates/java.txt
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
diff --git a/docs/copyright-templates/make.txt b/docs/copyright-templates/make.txt
new file mode 100644
index 0000000..e4b376e
--- /dev/null
+++ b/docs/copyright-templates/make.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed 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.
diff --git a/docs/copyright-templates/plain.txt b/docs/copyright-templates/plain.txt
new file mode 100644
index 0000000..4549ecb
--- /dev/null
+++ b/docs/copyright-templates/plain.txt
@@ -0,0 +1,13 @@
+Copyright (C) 2009 The Android Open Source Project
+
+Licensed 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.
diff --git a/docs/copyright-templates/sh.txt b/docs/copyright-templates/sh.txt
new file mode 100644
index 0000000..e53137d
--- /dev/null
+++ b/docs/copyright-templates/sh.txt
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed 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.
diff --git a/docs/copyright-templates/xml.txt b/docs/copyright-templates/xml.txt
new file mode 100644
index 0000000..2a9d2b6
--- /dev/null
+++ b/docs/copyright-templates/xml.txt
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed 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.
+-->
diff --git a/docs/howto_SDK_git_cygwin.txt b/docs/howto_SDK_git_cygwin.txt
new file mode 100644
index 0000000..078062b
--- /dev/null
+++ b/docs/howto_SDK_git_cygwin.txt
@@ -0,0 +1,168 @@
+Copyright (C) 2009 The Android Open Source Project
+
+Licensed 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.
+
+
+Subject: How to get the android source code using Cygwin and Git
+Date: 2009/04/27
+
+
+
+Table of content:
+ 1- Goals and Requirements
+ 2- Getting the code, the simple way
+ 3- SSH issues
+ 4- Advanced Tricks
+
+
+-------------------------
+1- Goals and Requirements
+-------------------------
+
+This document explains how to checkout the Android source from the git
+repositories under Windows.
+
+As stated in development/docs/howto_build_SDK.txt, one can't build the whole
+Android source code under Windows. You can only build a the SDK tools for
+Windows.
+
+There are a number of caveats in checking out the code from Git under Windows.
+This document tries to explain them.
+
+First you will need to meet the following requirements:
+- You must have Cygwin installed.
+ See http://www.cygwin.com/
+
+- You must install Cyginw using the "Unix / Binary" mode.
+ If you don't do that, git will fail to properly compute some SHA1 keys.
+
+- You need the "git" and "curl" packages to checkout the code.
+ If you plan to contribute, you might want to get "gitk" also.
+
+ Note: if you want to build the SDK, check the howto_build_SDK.txt file
+ for a list of extra required packages.
+
+
+-----------------------------------
+2- Getting the code, the simple way
+-----------------------------------
+
+Out of the box, "repo" and "git" will work just fine under Cygwin:
+
+ $ repo init -u git://android.git.kernel.org/platform/manifest.git
+ $ repo sync
+
+And you're done. You can build as explained in howto_build_SDK.txt and ignore
+the rest of this document.
+
+
+-------------
+3- SSH issues
+-------------
+
+If you maintain your own private repository using an SSH server, you might get
+some "mux/ssh" errors. In this case try this:
+
+ $ repo init -u ssh://my.private.ssh.repo/platform/manifest.git
+ $ export GIT_SSH=ssh
+ $ repo sync
+
+
+------------------
+4- Advanced Tricks
+------------------
+
+There are two remaining issues with the default repo/git options:
+
+A- If you plan on contributing, you will notice that even after a fresh "repo
+sync" some projects are marked as having modified files. This happens on the
+"bionic" and the "external/iptables" project. The issue is that they have files
+which have the same name yet differ only by their case-sensitivity. Since the
+Windows filesystem is not case-sensitive, this confuses Git.
+
+Solution: we can simply ignore these projects as they are not needed to build
+the Windows SDK.
+
+To do this you just need to create a file .repo/local_manifest.xml that
+provides a list of projects to ignore:
+
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest>
+ <remove-project name="platform/bionic" />
+ <remove-project name="platform/external/iptables" />
+</manifest>
+
+
+B- The other issue is that by default repo maintains around 100+ git projects.
+However most of these are not needed to build the Windows SDK. We can easily
+reduce this list to around 70 projects, which will make your repo syncs a lot
+faster.
+
+Solution: Simply ignore all projects bionic, bootable/*, hardware/* and most
+external projects. For external, we still need a handful of projects for the
+SDK -- things like the emulator or sqlite can be quite useful :-)
+
+Here's a script that takes care of all these details. It performs the repo
+init, creates the appropriate local_manifest.xml and does a repo sync as
+needed:
+
+------------
+#!/bin/bash
+
+set -e # fail on errors
+
+URL=git://android.git.kernel.org/platform/manifest.git
+BRANCH=donut
+
+# repo init if there's no .repo directory
+if [[ ! -d .repo ]]; then
+ repo init -u $URL -b $BRANCH
+fi
+
+# create a local_manifest to exclude projects not useful to the Windows SDK
+L=.repo/local_manifest.xml
+if [[ ! -f $L ]]; then
+ M=.repo/manifest.xml
+
+ cat > $L <<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest>
+EOF
+
+ for i in $(sed -sn '/external\/\(apache\|expat\|g\|libpng\|pr\|qemu\|sqlite\|tag\|zlib\)/d;/\(bionic\|bootable\|cts\|external\|hardware\).* name/s/^.*name="\([^"]\+\)".*/\1/p' $M) ; do
+ echo "Ignore project $i"
+ echo " <remove-project name=\"$i\" />" >> $L
+ done
+
+ cat >> $L <<EOF2
+</manifest>
+EOF2
+fi
+
+[[ $URL != ${URL/ssh/} ]] && export GIT_SSH=ssh
+repo sync
+------------
+
+
+Simply extract this to a "my_sync.sh" file and try the following:
+ $ mkdir android_src
+ $ cd android_src
+ $ chmod +x mysync.sh
+ $ ./mysync.sh
+
+
+-end-
+
+
+
+
diff --git a/emulator/qtools/coverage.cpp b/emulator/qtools/coverage.cpp
index fb1fe52..790f721 100644
--- a/emulator/qtools/coverage.cpp
+++ b/emulator/qtools/coverage.cpp
@@ -137,7 +137,7 @@
continue;
if (strcmp(psym->name, ".plt") == 0)
continue;
- char *ksym = " ";
+ const char *ksym = " ";
if (psym->region->flags & region_type::kIsKernelRegion)
ksym = "k";
printf("%s %s %s\n", ksym, psym->name, psym->region->path);
diff --git a/emulator/qtools/post_trace.cpp b/emulator/qtools/post_trace.cpp
index 99525fb..becfc2b 100644
--- a/emulator/qtools/post_trace.cpp
+++ b/emulator/qtools/post_trace.cpp
@@ -137,7 +137,7 @@
double insn_per_sec = 0;
if (elapsed_secs != 0)
insn_per_sec = num_dynamic_insn / elapsed_secs;
- char *suffix = "";
+ const char *suffix = "";
if (insn_per_sec >= 1000000) {
insn_per_sec /= 1000000.0;
suffix = "M";
diff --git a/emulator/qtools/profile_pid.cpp b/emulator/qtools/profile_pid.cpp
index aa37847..589abe9 100644
--- a/emulator/qtools/profile_pid.cpp
+++ b/emulator/qtools/profile_pid.cpp
@@ -76,7 +76,7 @@
sum_time += pstate->cpu_time;
double per = 100.0 * pstate->cpu_time / total_time;
double sum_per = 100.0 * sum_time / total_time;
- char *print_flags = "";
+ const char *print_flags = "";
if ((pstate->flags & ProcessState::kCalledExec) == 0)
print_flags = "T";
if (pstate->name == NULL)
diff --git a/emulator/qtools/profile_trace.cpp b/emulator/qtools/profile_trace.cpp
index 9d14a03..0b056cc 100644
--- a/emulator/qtools/profile_trace.cpp
+++ b/emulator/qtools/profile_trace.cpp
@@ -118,7 +118,7 @@
double per = 100.0 * sym->elapsed / total;
double sum_per = 100.0 * sum / total;
double secs = 1.0 * sym->elapsed / kMHz;
- char *ksym = " ";
+ const char *ksym = " ";
if (sym->region->flags & region_type::kIsKernelRegion)
ksym = "k";
printf("%12.2f %11lld %6.2f %6.2f %s %s\n",
diff --git a/emulator/qtools/q2dm.cpp b/emulator/qtools/q2dm.cpp
index 7f987dc..74dbaeb 100644
--- a/emulator/qtools/q2dm.cpp
+++ b/emulator/qtools/q2dm.cpp
@@ -208,7 +208,7 @@
if (pStack == NULL) {
pStack = new CallStackType(event.pid, kNumStackFrames, trace);
stacks[event.pid] = pStack;
- char *name = trace->GetProcessName(event.pid);
+ const char *name = trace->GetProcessName(event.pid);
dmtrace->addThread(event.pid, name);
}
@@ -267,7 +267,6 @@
}
}
-
dmtrace->close();
delete dmtrace;
delete trace;
diff --git a/emulator/qtools/read_addr.cpp b/emulator/qtools/read_addr.cpp
index 38fc62a..1c8c20f 100644
--- a/emulator/qtools/read_addr.cpp
+++ b/emulator/qtools/read_addr.cpp
@@ -20,7 +20,7 @@
if (trace->ReadAddr(&time, &addr, &flags))
break;
- char *op = "ld";
+ const char *op = "ld";
if (flags == 1)
op = "st";
printf("%lld 0x%08x %s\n", time, addr, op);
diff --git a/emulator/qtools/trace_reader.cpp b/emulator/qtools/trace_reader.cpp
index b38c0b4..d2af64f 100644
--- a/emulator/qtools/trace_reader.cpp
+++ b/emulator/qtools/trace_reader.cpp
@@ -131,7 +131,7 @@
delete decoder_;
}
-void BBReader::Open(char *filename)
+void BBReader::Open(const char *filename)
{
// Initialize the class variables
memset(&nextrec_, 0, sizeof(TimeRec));
@@ -268,7 +268,7 @@
delete decoder_;
}
-void InsnReader::Open(char *filename)
+void InsnReader::Open(const char *filename)
{
prev_time_ = 0;
time_diff_ = 0;
@@ -310,7 +310,7 @@
}
// Returns true if there is an error opening the file
-bool AddrReader::Open(char *filename, char *suffix)
+bool AddrReader::Open(const char *filename, const char *suffix)
{
struct stat stat_buf;
@@ -367,7 +367,7 @@
delete decoder_;
}
-void ExcReader::Open(char *filename)
+void ExcReader::Open(const char *filename)
{
prev_time_ = 0;
prev_recnum_ = 0;
@@ -421,7 +421,7 @@
delete decoder_;
}
-void PidReader::Open(char *filename)
+void PidReader::Open(const char *filename)
{
prev_time_ = 0;
@@ -561,7 +561,7 @@
delete decoder_;
}
-bool MethodReader::Open(char *filename)
+bool MethodReader::Open(const char *filename)
{
struct stat stat_buf;
@@ -686,8 +686,8 @@
delete[] static_filename_;
}
-void TraceReaderBase::ReadTraceHeader(FILE *fstream, char *filename,
- char *tracename, TraceHeader *header)
+void TraceReaderBase::ReadTraceHeader(FILE *fstream, const char *filename,
+ const char *tracename, TraceHeader *header)
{
int rval = fread(header, sizeof(TraceHeader), 1, fstream);
if (rval != 1) {
@@ -721,7 +721,7 @@
}
-void TraceReaderBase::Open(char *filename)
+void TraceReaderBase::Open(const char *filename)
{
char *fname;
FILE *fstream;
@@ -840,7 +840,7 @@
}
}
-void TraceReaderBase::ParseDexList(char *filename)
+void TraceReaderBase::ParseDexList(const char *filename)
{
struct stat stat_buf;
static const int kBufSize = 4096;
diff --git a/emulator/qtools/trace_reader.h b/emulator/qtools/trace_reader.h
index 4123014..f73f17a 100644
--- a/emulator/qtools/trace_reader.h
+++ b/emulator/qtools/trace_reader.h
@@ -165,7 +165,7 @@
uint32_t flags;
int argc;
char **argv;
- char *name;
+ const char *name;
int nregions; // num regions in use
int max_regions; // max regions allocated
region_type **regions;
@@ -189,7 +189,7 @@
ProcessState *GetCurrentProcess() { return current_; }
ProcessState *GetProcesses(int *num_procs);
ProcessState *GetNextProcess();
- char *GetProcessName(int pid);
+ const char *GetProcessName(int pid);
void SetRoot(const char *root) { root_ = root; }
void SetDemangle(bool demangle) { demangle_ = demangle; }
bool ReadMethodSymbol(MethodRec *method_record,
@@ -276,11 +276,14 @@
hash_entry_type *ptr;
for (ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
region_type *region = ptr->value;
- int nsymbols = region->nsymbols;
- for (int ii = 0; ii < nsymbols; ii++) {
- delete[] region->symbols[ii].name;
+ // If the symbols are not shared with another region, then delete them.
+ if ((region->flags & region_type::kSharedSymbols) == 0) {
+ int nsymbols = region->nsymbols;
+ for (int ii = 0; ii < nsymbols; ii++) {
+ delete[] region->symbols[ii].name;
+ }
+ delete[] region->symbols;
}
- delete[] region->symbols;
delete[] region->path;
// Do not delete the region itself here. Each region
@@ -422,7 +425,7 @@
}
template<class T>
-char* TraceReader<T>::GetProcessName(int pid)
+const char* TraceReader<T>::GetProcessName(int pid)
{
if (pid < 0 || pid >= kNumPids || processes_[pid] == NULL)
return "(unknown)";
@@ -1165,8 +1168,6 @@
} else {
region->nsymbols = existing_region->nsymbols;
region->symbols = existing_region->symbols;
- region->path = existing_region->path;
- delete[] event->path;
region->flags |= region_type::kSharedSymbols;
}
diff --git a/emulator/qtools/trace_reader_base.h b/emulator/qtools/trace_reader_base.h
index 281d085..416c3d1 100644
--- a/emulator/qtools/trace_reader_base.h
+++ b/emulator/qtools/trace_reader_base.h
@@ -83,7 +83,7 @@
friend class BBReader;
- void Open(char *filename);
+ void Open(const char *filename);
void Close();
void WriteHeader(TraceHeader *header);
inline bool ReadBB(BBEvent *event);
@@ -120,10 +120,10 @@
private:
int FindNumInsns(uint64_t bb_num, uint64_t bb_start_time);
- void ReadTraceHeader(FILE *fstream, char *filename,
- char *tracename, TraceHeader *header);
+ void ReadTraceHeader(FILE *fstream, const char *filename,
+ const char *tracename, TraceHeader *header);
PidEvent *FindMmapDexFileEvent();
- void ParseDexList(char *filename);
+ void ParseDexList(const char *filename);
char *static_filename_;
FILE *static_fstream_;
@@ -159,7 +159,7 @@
public:
explicit BBReader(TraceReaderBase *trace);
~BBReader();
- void Open(char *filename);
+ void Open(const char *filename);
void Close();
bool ReadBB(BBEvent *event);
@@ -193,7 +193,7 @@
InsnReader();
~InsnReader();
- void Open(char *filename);
+ void Open(const char *filename);
void Close();
uint64_t ReadInsnTime(uint64_t min_time);
@@ -209,7 +209,7 @@
AddrReader();
~AddrReader();
- bool Open(char *filename, char *suffix);
+ bool Open(const char *filename, const char *suffix);
void Close();
bool ReadAddr(uint64_t *time, uint32_t *addr);
@@ -225,7 +225,7 @@
ExcReader();
~ExcReader();
- void Open(char *filename);
+ void Open(const char *filename);
void Close();
bool ReadExc(uint64_t *time, uint32_t *current_pc,
uint64_t *recnum, uint32_t *target_pc,
@@ -243,7 +243,7 @@
PidReader();
~PidReader();
- void Open(char *filename);
+ void Open(const char *filename);
void Close();
bool ReadPidEvent(struct PidEvent *event);
void Dispose(struct PidEvent *event);
@@ -258,7 +258,7 @@
MethodReader();
~MethodReader();
- bool Open(char *filename);
+ bool Open(const char *filename);
void Close();
bool ReadMethod(MethodRec *method_record);
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index a53718e..d353d31 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -1104,6 +1104,13 @@
</intent-filter>
</activity>
+ <activity android:name=".view.Animation3" android:label="Views/Animation/Interpolators">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".view.LayoutAnimation1" android:label="Views/Layout Animation/1. Grid Fade">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/samples/ApiDemos/res/layout/animation_3.xml b/samples/ApiDemos/res/layout/animation_3.xml
new file mode 100644
index 0000000..4d1474c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_3.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:padding="10dip"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false">
+
+ <TextView
+ android:id="@+id/target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="26sp"
+ android:text="@string/animation_3_text"/>
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="20dip"
+ android:layout_marginBottom="5dip"
+ android:text="@string/animation_2_instructions" />
+
+ <Spinner
+ android:id="@+id/spinner"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 0cafe14..29bbcec 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -476,6 +476,7 @@
<string name="animation_2_text_3">a chance to be better.</string>
<string name="animation_2_text_4">— Albert Camus</string>
<string name="animation_2_instructions">Select an animation:</string>
+ <string name="animation_3_text">Interpolators</string>
<string name="autocomplete_1_instructions">Type in the text field for auto-completion.</string>
<string name="autocomplete_1_country">Country:</string>
<string name="autocomplete_1_focus">Give me Focus</string>
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java
new file mode 100644
index 0000000..c492e3f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import static android.opengl.GLES10.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+import android.os.SystemClock;
+
+import com.example.android.apis.R;
+
+/**
+ * A GLSurfaceView.Renderer that uses the Android-specific
+ * android.opengl.GLESXXX static OpenGL ES APIs. The static APIs
+ * expose more of the OpenGL ES features than the
+ * javax.microedition.khronos.opengles APIs, and also
+ * provide a programming model that is closer to the C OpenGL ES APIs, which
+ * may make it easier to reuse code and documentation written for the
+ * C OpenGL ES APIs.
+ *
+ */
+public class StaticTriangleRenderer implements GLSurfaceView.Renderer{
+
+ public StaticTriangleRenderer(Context context) {
+ mContext = context;
+ mTriangle = new Triangle();
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ /*
+ * By default, OpenGL enables features that improve quality
+ * but reduce performance. One might want to tweak that
+ * especially on software renderer.
+ */
+ glDisable(GL_DITHER);
+
+ /*
+ * Some one-time OpenGL initialization can be made here
+ * probably based on features of this particular context
+ */
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT,
+ GL_FASTEST);
+
+ glClearColor(.5f, .5f, .5f, 1);
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+
+ /*
+ * Create our texture. This has to be done each time the
+ * surface is created.
+ */
+
+ int[] textures = new int[1];
+ glGenTextures(1, textures, 0);
+
+ mTextureID = textures[0];
+ glBindTexture(GL_TEXTURE_2D, mTextureID);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D,
+ GL_TEXTURE_MAG_FILTER,
+ GL_LINEAR);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+ GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+ GL_CLAMP_TO_EDGE);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+ GL_REPLACE);
+
+ InputStream is = mContext.getResources()
+ .openRawResource(R.drawable.robot);
+ Bitmap bitmap;
+ try {
+ bitmap = BitmapFactory.decodeStream(is);
+ } finally {
+ try {
+ is.close();
+ } catch(IOException e) {
+ // Ignore.
+ }
+ }
+
+ GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
+ bitmap.recycle();
+ }
+
+ public void onDrawFrame(GL10 gl) {
+ /*
+ * By default, OpenGL enables features that improve quality
+ * but reduce performance. One might want to tweak that
+ * especially on software renderer.
+ */
+ glDisable(GL_DITHER);
+
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+ GL_MODULATE);
+
+ /*
+ * Usually, the first thing one might want to do is to clear
+ * the screen. The most efficient way of doing this is to use
+ * glClear().
+ */
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /*
+ * Now we're ready to draw some 3D objects
+ */
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, mTextureID);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+ GL_REPEAT);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+ GL_REPEAT);
+
+ long time = SystemClock.uptimeMillis() % 4000L;
+ float angle = 0.090f * ((int) time);
+
+ glRotatef(angle, 0, 0, 1.0f);
+
+ mTriangle.draw(gl);
+ }
+
+ public void onSurfaceChanged(GL10 gl, int w, int h) {
+ glViewport(0, 0, w, h);
+
+ /*
+ * Set our projection matrix. This doesn't have to be done
+ * each time we draw, but usually a new projection needs to
+ * be set when the viewport is resized.
+ */
+
+ float ratio = (float) w / h;
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustumf(-ratio, ratio, -1, 1, 3, 7);
+ }
+
+ private Context mContext;
+ private Triangle mTriangle;
+ private int mTextureID;
+
+ static class Triangle {
+ public Triangle() {
+
+ // Buffers to be passed to gl*Pointer() functions
+ // must be direct, i.e., they must be placed on the
+ // native heap where the garbage collector cannot
+ // move them.
+ //
+ // Buffers with multi-byte datatypes (e.g., short, int, float)
+ // must have their byte order set to native order
+
+ ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 3 * 4);
+ vbb.order(ByteOrder.nativeOrder());
+ mFVertexBuffer = vbb.asFloatBuffer();
+
+ ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
+ tbb.order(ByteOrder.nativeOrder());
+ mTexBuffer = tbb.asFloatBuffer();
+
+ ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 2);
+ ibb.order(ByteOrder.nativeOrder());
+ mIndexBuffer = ibb.asShortBuffer();
+
+ // A unit-sided equilateral triangle centered on the origin.
+ float[] coords = {
+ // X, Y, Z
+ -0.5f, -0.25f, 0,
+ 0.5f, -0.25f, 0,
+ 0.0f, 0.559016994f, 0
+ };
+
+ for (int i = 0; i < VERTS; i++) {
+ for(int j = 0; j < 3; j++) {
+ mFVertexBuffer.put(coords[i*3+j] * 2.0f);
+ }
+ }
+
+ for (int i = 0; i < VERTS; i++) {
+ for(int j = 0; j < 2; j++) {
+ mTexBuffer.put(coords[i*3+j] * 2.0f + 0.5f);
+ }
+ }
+
+ for(int i = 0; i < VERTS; i++) {
+ mIndexBuffer.put((short) i);
+ }
+
+ mFVertexBuffer.position(0);
+ mTexBuffer.position(0);
+ mIndexBuffer.position(0);
+ }
+
+ public void draw(GL10 gl) {
+ glFrontFace(GL_CCW);
+ glVertexPointer(3, GL_FLOAT, 0, mFVertexBuffer);
+ glEnable(GL_TEXTURE_2D);
+ glTexCoordPointer(2, GL_FLOAT, 0, mTexBuffer);
+ glDrawElements(GL_TRIANGLE_STRIP, VERTS,
+ GL_UNSIGNED_SHORT, mIndexBuffer);
+ }
+
+ private final static int VERTS = 3;
+
+ private FloatBuffer mFVertexBuffer;
+ private FloatBuffer mTexBuffer;
+ private ShortBuffer mIndexBuffer;
+ }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
index e5b06f4..7d7cd4a 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
@@ -27,7 +27,7 @@
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(this);
mGLView.setEGLConfigChooser(false);
- mGLView.setRenderer(new TriangleRenderer(this));
+ mGLView.setRenderer(new StaticTriangleRenderer(this));
setContentView(mGLView);
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java b/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
new file mode 100644
index 0000000..11fc9ed
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+
+public class Animation3 extends Activity implements AdapterView.OnItemSelectedListener {
+ private static final String[] INTERPOLATORS = {
+ "Accelerate", "Decelerate", "Accelerate/Decelerate",
+ "Anticipate", "Overshoot", "Anticipate/Overshoot",
+ "Bounce"
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.animation_3);
+
+ Spinner s = (Spinner) findViewById(R.id.spinner);
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, INTERPOLATORS);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ s.setAdapter(adapter);
+ s.setOnItemSelectedListener(this);
+ }
+
+ public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ final View target = findViewById(R.id.target);
+ final View targetParent = (View) target.getParent();
+
+ Animation a = new TranslateAnimation(0.0f,
+ targetParent.getWidth() - target.getWidth() - targetParent.getPaddingLeft() -
+ targetParent.getPaddingRight(), 0.0f, 0.0f);
+ a.setDuration(1000);
+ a.setStartOffset(300);
+ a.setRepeatMode(Animation.RESTART);
+ a.setRepeatCount(Animation.INFINITE);
+
+ switch (position) {
+ case 0:
+ a.setInterpolator(AnimationUtils.loadInterpolator(this,
+ android.R.anim.accelerate_interpolator));
+ break;
+ case 1:
+ a.setInterpolator(AnimationUtils.loadInterpolator(this,
+ android.R.anim.decelerate_interpolator));
+ break;
+ case 2:
+ a.setInterpolator(AnimationUtils.loadInterpolator(this,
+ android.R.anim.accelerate_decelerate_interpolator));
+ break;
+ case 3:
+ a.setInterpolator(AnimationUtils.loadInterpolator(this,
+ android.R.anim.anticipate_interpolator));
+ break;
+ case 4:
+ a.setInterpolator(AnimationUtils.loadInterpolator(this,
+ android.R.anim.overshoot_interpolator));
+ break;
+ case 5:
+ a.setInterpolator(AnimationUtils.loadInterpolator(this,
+ android.R.anim.anticipate_overshoot_interpolator));
+ break;
+ case 6:
+ a.setInterpolator(AnimationUtils.loadInterpolator(this,
+ android.R.anim.bounce_interpolator));
+ break;
+ }
+
+ target.startAnimation(a);
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ }
+}
\ No newline at end of file
diff --git a/testrunner/run_command.py b/testrunner/run_command.py
index 6b72b77..5336f33 100755
--- a/testrunner/run_command.py
+++ b/testrunner/run_command.py
@@ -3,37 +3,37 @@
#
# Copyright 2007, The Android Open Source Project
#
-# Licensed 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
+# Licensed 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
+# 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
+# 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.
# System imports
import os
import signal
import subprocess
-import time
import threading
+import time
# local imports
-import logger
import errors
+import logger
_abort_on_error = False
def SetAbortOnError(abort=True):
- """Sets behavior of RunCommand to throw AbortError if command process returns
+ """Sets behavior of RunCommand to throw AbortError if command process returns
a negative error code"""
global _abort_on_error
_abort_on_error = abort
-
+
def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True):
"""Spawns a subprocess to run the given shell command, and checks for
timeout_time. If return_output is True, the output of the command is returned
@@ -42,7 +42,7 @@
result = None
while True:
try:
- result = RunOnce(cmd, timeout_time=timeout_time,
+ result = RunOnce(cmd, timeout_time=timeout_time,
return_output=return_output)
except errors.WaitForResponseTimedOutError:
if retry_count == 0:
@@ -59,13 +59,13 @@
pid = []
global _abort_on_error
error_occurred = False
-
+
def Run():
if return_output:
output_dest = subprocess.PIPE
else:
# None means direct to stdout
- output_dest = None
+ output_dest = None
pipe = subprocess.Popen(
cmd,
executable='/bin/bash',
@@ -83,9 +83,9 @@
so.append("ERROR")
error_occurred = True
if pipe.returncode < 0:
- logger.SilentLog("Error: %s was terminated by signal %d" %(cmd,
+ logger.SilentLog("Error: %s was terminated by signal %d" %(cmd,
pipe.returncode))
- error_occurred = True
+ error_occurred = True
t = threading.Thread(target=Run)
t.start()
@@ -113,5 +113,26 @@
if _abort_on_error and error_occurred:
raise errors.AbortError
-
+
return "".join(so)
+
+
+def RunHostCommand(binary, valgrind=False):
+ """Run a command on the host (opt using valgrind).
+
+ Runs the host binary. Does not capture any output but it
+ returns the exit code. The command can be run under valgrind.
+
+ Args:
+ binary: basename of the file to be run. It is expected to be under
+ out/host/linux-x86/bin.
+ valgrind: If True the command will be run under valgrind.
+
+ Returns:
+ The command exit code (int)
+ """
+ full_path = os.path.join("out", "host", "linux-x86", "bin", binary)
+ if not valgrind:
+ return subprocess.call(full_path)
+ else:
+ return subprocess.call(["/usr/bin/valgrind", "-q", full_path])
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index 243da77..f87d451 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -23,6 +23,7 @@
import glob
import optparse
import os
+import re
from sets import Set
import sys
@@ -43,7 +44,7 @@
# file path to android core platform tests, relative to android build root
# TODO move these test data files to another directory
- _CORE_TEST_PATH = os.path.join("development", "testrunner",
+ _CORE_TEST_PATH = os.path.join("development", "testrunner",
_TEST_FILE_NAME)
# vendor glob file path patterns to tests, relative to android
@@ -58,7 +59,8 @@
def __init__(self):
# disable logging of timestamp
- logger.SetTimestampLogging(False)
+ self._root_path = android_build.GetTop()
+ logger.SetTimestampLogging(False)
def _ProcessOptions(self):
"""Processes command-line options."""
@@ -137,8 +139,6 @@
if self._options.verbose:
logger.SetVerbose(True)
- self._root_path = android_build.GetTop()
-
self._known_tests = self._ReadTests()
self._coverage_gen = coverage.CoverageGenerator(
@@ -172,22 +172,30 @@
"""Prints out set of defined tests."""
print "The following tests are currently defined:"
for test in self._known_tests:
- print test.GetName()
+ print "%-15s %s" % (test.GetName(), test.GetDescription())
def _DoBuild(self):
logger.SilentLog("Building tests...")
target_set = Set()
+ extra_args_set = Set()
for test_suite in self._GetTestsToRun():
- self._AddBuildTarget(test_suite.GetBuildPath(), target_set)
+ self._AddBuildTarget(test_suite, target_set, extra_args_set)
if target_set:
if self._options.coverage:
self._coverage_gen.EnableCoverageBuild()
- self._AddBuildTarget(self._coverage_gen.GetEmmaBuildPath(), target_set)
+ self._AddBuildTargetPath(self._coverage_gen.GetEmmaBuildPath(),
+ target_set)
target_build_string = " ".join(list(target_set))
- logger.Log("mmm %s" % target_build_string)
- cmd = 'ONE_SHOT_MAKEFILE="%s" make -C "%s" files' % (target_build_string,
- self._root_path)
+ extra_args_string = " ".join(list(extra_args_set))
+ # log the user-friendly equivalent make command, so developers can
+ # replicate this step
+ logger.Log("mmm %s %s" % (target_build_string, extra_args_string))
+ # mmm cannot be used from python, so perform a similiar operation using
+ # ONE_SHOT_MAKEFILE
+ cmd = 'ONE_SHOT_MAKEFILE="%s" make -C "%s" files %s' % (
+ target_build_string, self._root_path, extra_args_string)
+
if self._options.preview:
# in preview mode, just display to the user what command would have been
# run
@@ -197,11 +205,18 @@
logger.Log("Syncing to device...")
self._adb.Sync()
- def _AddBuildTarget(self, build_dir, target_set):
+ def _AddBuildTarget(self, test_suite, target_set, extra_args_set):
+ build_dir = test_suite.GetBuildPath()
+ if self._AddBuildTargetPath(build_dir, target_set):
+ extra_args_set.add(test_suite.GetExtraMakeArgs())
+
+ def _AddBuildTargetPath(self, build_dir, target_set):
if build_dir is not None:
build_file_path = os.path.join(build_dir, "Android.mk")
if os.path.isfile(os.path.join(self._root_path, build_file_path)):
target_set.add(build_file_path)
+ return True
+ return False
def _GetTestsToRun(self):
"""Get a list of TestSuite objects to run, based on command line args."""
@@ -261,6 +276,52 @@
if coverage_file is not None:
logger.Log("Coverage report generated at %s" % coverage_file)
+ def _RunNativeTest(self, test_suite):
+ """Run the provided *native* test suite.
+
+ The test_suite must contain a build path where the native test files are.
+ Each test's name must start with 'test_' and have a .cc or .cpp extension.
+ A successful test must return 0. Any other value will be considered
+ as an error.
+
+ Args:
+ test_suite: TestSuite to run
+ """
+ # find all test files, convert unicode names to ascii, take the basename
+ # and drop the .cc/.cpp extension.
+ file_pattern = os.path.join(test_suite.GetBuildPath(), "test_*")
+ logger.SilentLog("Scanning %s" % test_suite.GetBuildPath())
+ file_list = []
+ for f in map(str, glob.glob(file_pattern)):
+ f = os.path.basename(f)
+ f = re.split(".[cp]+$", f)[0]
+ logger.SilentLog("Found %s" % f)
+ file_list.append(f)
+
+ # Run on the host
+ logger.Log("\nRunning on host")
+ for f in file_list:
+ if run_command.RunHostCommand(f) != 0:
+ logger.Log("%s... failed" % f)
+ else:
+ if run_command.RunHostCommand(f, valgrind=True) == 0:
+ logger.Log("%s... ok\t\t[valgrind: ok]" % f)
+ else:
+ logger.Log("%s... ok\t\t[valgrind: failed]" % f)
+
+ # Run on the device
+ logger.Log("\nRunning on target")
+ for f in file_list:
+ full_path = "/system/bin/%s" % f
+
+ # Single quotes are needed to prevent the shell splitting it.
+ status = self._adb.SendShellCommand("'%s >/dev/null 2>&1;echo -n $?'" %
+ full_path)
+ logger.Log("%s... %s" % (f, status == "0" and "ok" or "failed"))
+
+ # Cleanup
+ self._adb.SendShellCommand("rm %s" % full_path)
+
def RunTests(self):
"""Main entry method - executes the tests according to command line args."""
try:
@@ -278,7 +339,10 @@
self._DoBuild()
for test_suite in self._GetTestsToRun():
- self._RunTest(test_suite)
+ if test_suite.IsNative():
+ self._RunNativeTest(test_suite)
+ else:
+ self._RunTest(test_suite)
except KeyboardInterrupt:
logger.Log("Exiting...")
except errors.AbortError:
diff --git a/testrunner/test_defs.py b/testrunner/test_defs.py
index 949ad6e..2cdcfa8 100644
--- a/testrunner/test_defs.py
+++ b/testrunner/test_defs.py
@@ -38,7 +38,14 @@
[class=""]
[coverage_target=""]
[build_path=""]
- [continuous]
+ [continuous=false]
+ [description=""]
+ />
+ <test-native
+ name=""
+ build_path=""
+ [continuous=false]
+ [description=""]
/>
<test ...
</test-definitions>
@@ -48,13 +55,17 @@
# tag/attribute constants
_TEST_TAG_NAME = "test"
+ _TEST_NATIVE_TAG_NAME = "test-native"
def __init__(self):
# dictionary of test name to tests
self._testname_map = {}
def __iter__(self):
- return iter(self._testname_map.values())
+ ordered_list = []
+ for k in sorted(self._testname_map):
+ ordered_list.append(self._testname_map[k])
+ return iter(ordered_list)
def Parse(self, file_path):
"""Parse the test suite data from from given file path.
@@ -87,6 +98,12 @@
test = self._ParseTestSuite(suite_element)
self._AddTest(test)
+ suite_elements = doc.getElementsByTagName(self._TEST_NATIVE_TAG_NAME)
+
+ for suite_element in suite_elements:
+ test = self._ParseNativeTestSuite(suite_element)
+ self._AddTest(test)
+
def _ParseTestSuite(self, suite_element):
"""Parse the suite element.
@@ -96,6 +113,17 @@
test = TestSuite(suite_element)
return test
+ def _ParseNativeTestSuite(self, suite_element):
+ """Parse the native test element.
+
+ Returns:
+ a TestSuite object, populated with parsed data
+ Raises:
+ ParseError if some required attribute is missing.
+ """
+ test = TestSuite(suite_element, native=True)
+ return test
+
def _AddTest(self, test):
"""Adds a test to this TestManifest.
@@ -129,13 +157,28 @@
_TARGET_ATTR = "coverage_target"
_BUILD_ATTR = "build_path"
_CONTINUOUS_ATTR = "continuous"
+ _DESCRIPTION_ATTR = "description"
+ _EXTRA_MAKE_ARGS_ATTR = "extra_make_args"
_DEFAULT_RUNNER = "android.test.InstrumentationTestRunner"
- def __init__(self, suite_element):
- """Populates this instance's data from given suite xml element."""
+ def __init__(self, suite_element, native=False):
+ """Populates this instance's data from given suite xml element.
+ Raises:
+ ParseError if some required attribute is missing.
+ """
+ self._native = native
self._name = suite_element.getAttribute(self._NAME_ATTR)
- self._package = suite_element.getAttribute(self._PKG_ATTR)
+
+ if self._native:
+ # For native runs, _BUILD_ATTR is required
+ if not suite_element.hasAttribute(self._BUILD_ATTR):
+ logger.Log("Error: %s is missing required build_path attribute" %
+ self._name)
+ raise errors.ParseError
+ else:
+ self._package = suite_element.getAttribute(self._PKG_ATTR)
+
if suite_element.hasAttribute(self._RUNNER_ATTR):
self._runner = suite_element.getAttribute(self._RUNNER_ATTR)
else:
@@ -156,6 +199,15 @@
self._continuous = suite_element.getAttribute(self._CONTINUOUS_ATTR)
else:
self._continuous = False
+ if suite_element.hasAttribute(self._DESCRIPTION_ATTR):
+ self._description = suite_element.getAttribute(self._DESCRIPTION_ATTR)
+ else:
+ self._description = ""
+ if suite_element.hasAttribute(self._EXTRA_MAKE_ARGS_ATTR):
+ self._extra_make_args = suite_element.getAttribute(
+ self._EXTRA_MAKE_ARGS_ATTR)
+ else:
+ self._extra_make_args = ""
def GetName(self):
return self._name
@@ -184,6 +236,18 @@
"""Returns true if test is flagged as being part of the continuous tests"""
return self._continuous
+ def IsNative(self):
+ """Returns true if test is a native one."""
+ return self._native
+
+ def GetDescription(self):
+ """Returns a description if available, an empty string otherwise."""
+ return self._description
+
+ def GetExtraMakeArgs(self):
+ """Returns the extra make args if available, an empty string otherwise."""
+ return self._extra_make_args
+
def Parse(file_path):
"""Parses out a TestDefinitions from given path to xml file.
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 87159fd..dd56db1 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -17,32 +17,67 @@
<!--
This file contains standard test definitions for the Android platform
-Tests are defined by <test> tags with the following attributes
+Java tests are defined by <test> tags and native ones (C/C++) are defined by
+<test-native> tags.
-name package [class runner build_path coverage_target continuous]
+JAVA/application tests:
+=======================
+ The java <test> element has the following attributes
-Where:
-name: Self-descriptive name used to uniquely identify the test
-build_path: File system path, relative to Android build root, to this package's
- Android.mk file. If omitted, build/sync step for this test will be skipped
-package: Android application package that contains the tests
-class: Optional. Fully qualified Java test class to run.
-runner: Fully qualified InstrumentationTestRunner to execute. If omitted,
- will default to android.test.InstrumentationTestRunner
-coverage_target: Build name of Android package this test targets - these targets
- are defined in the coverage_targets.xml file. Used as basis for code
- coverage metrics. If omitted, code coverage will not be supported for this
- test
-continuous: Optional boolean. Default is false. Set to true if tests are known
- to be reliable, and should be included in a continuous test system. false if
- they are under development.
+ name package [class runner build_path coverage_target continuous description]
-These attributes map to the following commands:
-(if class is defined)
- adb shell am instrument -w <package>/<runner>
-(else)
- adb shell am instrument -w -e class <class> <package>/<runner>
+ Where:
+ name: Self-descriptive name used to uniquely identify the test
+ build_path: File system path, relative to Android build root, to this
+ package's Android.mk file. If omitted, build/sync step for this test will
+ be skipped.
+ package: Android application package that contains the tests
+ class: Optional. Fully qualified Java test class to run.
+ runner: Fully qualified InstrumentationTestRunner to execute. If omitted,
+ will default to android.test.InstrumentationTestRunner.
+ coverage_target: Build name of Android package this test targets - these
+ targets are defined in the coverage_targets.xml file. Used as basis for
+ code coverage metrics. If omitted, code coverage will not be supported for
+ this test.
+ continuous: Optional boolean. Default is false. Set to true if tests are known
+ to be reliable, and should be included in a continuous test system. false if
+ they are under development.
+ description: Optional string. Default is empty. Short description (typically
+ less than 60 characters) about this test.
+
+ These attributes map to the following commands:
+ (if class is defined)
+ adb shell am instrument -w <package>/<runner>
+ (else)
+ adb shell am instrument -w -e class <class> <package>/<runner>
+
+Native tests:
+=============
+ The <test-native> element has the following attributes
+
+ name build_path [continuous description]
+
+ Where:
+ name: Self-descriptive name used to uniquely identify the test
+ build_path: File system path, relative to Android build root, to this
+ package's Android.mk file. By convention the name of a test starts with
+ 'test_'.
+ continuous: Optional boolean. Default is false. Set to true if tests are known
+ to be reliable, and should be included in a continuous test system.
+ false if they are under development.
+ description: Optional string. Default is empty. Short description (typically
+ less than 60 characters) about this test.
+ extra_make_args: Optional string. Default is empty. Some test module require
+ extra make arguments to build. This string is append to the make command.
+
+ These attributes map to the following commands:
+ make <build_path>/Android.mk <extra_make_args>
+ adb sync
+ for test_prog in <tests built>; do
+ adb shell "/system/bin/${test_prog} >/dev/null 2>&1;echo \$?"
+ adb shell "rm /system/bin/${test_prog}"
+ done
-->
<test-definitions version="1">
@@ -222,4 +257,11 @@
coverage_target="Settings" />
-->
+<!-- native tests -->
+<test-native name="libstdcpp"
+ build_path="system/extras/tests/bionic/libstdc++"
+ description="Bionic libstdc++."
+ extra_make_args="BIONIC_TESTS=1" />
+
+
</test-definitions>
diff --git a/tools/androidprefs/.gitignore b/tools/androidprefs/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/androidprefs/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/anttasks/.gitignore b/tools/anttasks/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/anttasks/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/apkbuilder/.gitignore b/tools/apkbuilder/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/apkbuilder/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/ddms/.gitignore b/tools/ddms/.gitignore
new file mode 100644
index 0000000..6d833a0
--- /dev/null
+++ b/tools/ddms/.gitignore
@@ -0,0 +1,4 @@
+app/bin
+libs/ddmlib/bin
+libs/ddmuilib/bin
+
diff --git a/tools/ddms/app/src/com/android/ddms/Main.java b/tools/ddms/app/src/com/android/ddms/Main.java
index d63b884..d545ed9 100644
--- a/tools/ddms/app/src/com/android/ddms/Main.java
+++ b/tools/ddms/app/src/com/android/ddms/Main.java
@@ -78,7 +78,7 @@
// the "ping" argument means to check in with the server and exit
// the application name and version number must also be supplied
if (args.length >= 3 && args[0].equals("ping")) {
- SdkStatsService.ping(args[1], args[2]);
+ SdkStatsService.ping(args[1], args[2], null);
return;
} else if (args.length > 0) {
Log.e("ddms", "Unknown argument: " + args[0]);
@@ -86,7 +86,7 @@
}
// ddms itself is wanted: send a ping for ourselves
- SdkStatsService.ping("ddms", VERSION); //$NON-NLS-1$
+ SdkStatsService.ping("ddms", VERSION, null); //$NON-NLS-1$
DebugPortManager.setProvider(DebugPortProvider.getInstance());
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
index 795bf88..0957171 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
@@ -194,6 +194,7 @@
HandleThread.register(monitorThread);
HandleHeap.register(monitorThread);
HandleWait.register(monitorThread);
+ HandleProfiling.register(monitorThread);
}
/**
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
index 5752b86..5111638 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
@@ -32,6 +32,7 @@
public static final int CHUNK_HPEN = type("HPEN");
public static final int CHUNK_HPSG = type("HPSG");
public static final int CHUNK_HPGC = type("HPGC");
+ public static final int CHUNK_HPDU = type("HPDU");
public static final int CHUNK_REAE = type("REAE");
public static final int CHUNK_REAQ = type("REAQ");
public static final int CHUNK_REAL = type("REAL");
@@ -98,6 +99,8 @@
client.update(Client.CHANGE_HEAP_DATA);
} else if (type == CHUNK_HPSG) {
handleHPSG(client, data);
+ } else if (type == CHUNK_HPDU) {
+ handleHPDU(client, data);
} else if (type == CHUNK_REAQ) {
handleREAQ(client, data);
client.update(Client.CHANGE_HEAP_ALLOCATION_STATUS);
@@ -221,6 +224,44 @@
}
/**
+ * Sends an HPDU request to the client.
+ *
+ * We will get an HPDU response when the heap dump has completed. On
+ * failure we get a generic failure response.
+ *
+ * @param fileName name of output file (on device)
+ */
+ public static void sendHPDU(Client client, String fileName)
+ throws IOException {
+ ByteBuffer rawBuf = allocBuffer(4 + fileName.length() * 2);
+ JdwpPacket packet = new JdwpPacket(rawBuf);
+ ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+ buf.putInt(fileName.length());
+ putString(buf, fileName);
+
+ finishChunkPacket(packet, CHUNK_HPDU, buf.position());
+ Log.d("ddm-heap", "Sending " + name(CHUNK_HPDU) + " '" + fileName +"'");
+ client.sendAndConsume(packet, mInst);
+ }
+
+ /*
+ * Handle notification of completion of a HeaP DUmp.
+ */
+ private void handleHPDU(Client client, ByteBuffer data) {
+ byte result;
+
+ result = data.get();
+
+ if (result == 0) {
+ Log.i("ddm-heap", "Heap dump request has finished");
+ // TODO: stuff
+ } else {
+ Log.w("ddm-heap", "Heap dump request failed (check device log)");
+ }
+ }
+
+ /**
* Sends a REAE (REcent Allocation Enable) request to the client.
*/
public static void sendREAE(Client client, boolean enable)
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
index 5ba5aeb..fb9697c 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
@@ -20,11 +20,12 @@
import java.nio.ByteBuffer;
/**
- * Handle the "hello" chunk (HELO).
+ * Handle the "hello" chunk (HELO) and feature discovery.
*/
final class HandleHello extends ChunkHandler {
public static final int CHUNK_HELO = ChunkHandler.type("HELO");
+ public static final int CHUNK_FEAT = ChunkHandler.type("FEAT");
private static final HandleHello mInst = new HandleHello();
@@ -65,6 +66,8 @@
if (type == CHUNK_HELO) {
assert isReply;
handleHELO(client, data);
+ } else if (type == CHUNK_FEAT) {
+ handleFEAT(client, data);
} else {
handleUnknownChunk(client, type, data, isReply, msgId);
}
@@ -126,5 +129,37 @@
+ " ID=0x" + Integer.toHexString(packet.getId()));
client.sendAndConsume(packet, mInst);
}
+
+ /**
+ * Handle a reply to our FEAT request.
+ */
+ private static void handleFEAT(Client client, ByteBuffer data) {
+ int featureCount;
+ int i;
+
+ featureCount = data.getInt();
+ for (i = 0; i < featureCount; i++) {
+ int len = data.getInt();
+ String feature = getString(data, len);
+
+ Log.d("ddm-hello", "Feature: " + feature);
+ }
+ }
+
+ /**
+ * Send a FEAT request to the client.
+ */
+ public static void sendFEAT(Client client) throws IOException {
+ ByteBuffer rawBuf = allocBuffer(0);
+ JdwpPacket packet = new JdwpPacket(rawBuf);
+ ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+ // no data
+
+ finishChunkPacket(packet, CHUNK_FEAT, buf.position());
+ Log.d("ddm-heap", "Sending " + name(CHUNK_FEAT));
+ client.sendAndConsume(packet, mInst);
+ }
+
}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java
new file mode 100644
index 0000000..e8e8103
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Handle heap status updates.
+ */
+final class HandleProfiling extends ChunkHandler {
+
+ public static final int CHUNK_MPRS = type("MPRS");
+ public static final int CHUNK_MPRE = type("MPRE");
+ public static final int CHUNK_MPRQ = type("MPRQ");
+
+ private static final HandleProfiling mInst = new HandleProfiling();
+
+ private HandleProfiling() {}
+
+ /**
+ * Register for the packets we expect to get from the client.
+ */
+ public static void register(MonitorThread mt) {
+ mt.registerChunkHandler(CHUNK_MPRE, mInst);
+ mt.registerChunkHandler(CHUNK_MPRQ, mInst);
+ }
+
+ /**
+ * Client is ready.
+ */
+ @Override
+ public void clientReady(Client client) throws IOException {}
+
+ /**
+ * Client went away.
+ */
+ @Override
+ public void clientDisconnected(Client client) {}
+
+ /**
+ * Chunk handler entry point.
+ */
+ @Override
+ public void handleChunk(Client client, int type, ByteBuffer data,
+ boolean isReply, int msgId) {
+
+ Log.d("ddm-prof", "handling " + ChunkHandler.name(type));
+
+ if (type == CHUNK_MPRE) {
+ handleMPRE(client, data);
+ } else if (type == CHUNK_MPRQ) {
+ handleMPRQ(client, data);
+ } else {
+ handleUnknownChunk(client, type, data, isReply, msgId);
+ }
+ }
+
+ /**
+ * Send a MPRS (Method PRofiling Start) request to the client.
+ *
+ * @param fileName is the name of the file to which profiling data
+ * will be written (on the device); it will have ".trace"
+ * appended if necessary
+ * @param bufferSize is the desired buffer size in bytes (8MB is good)
+ * @param flags should be zero
+ */
+ public static void sendMPRS(Client client, String fileName, int bufferSize,
+ int flags) throws IOException {
+
+ ByteBuffer rawBuf = allocBuffer(3*4 + fileName.length() * 2);
+ JdwpPacket packet = new JdwpPacket(rawBuf);
+ ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+ buf.putInt(bufferSize);
+ buf.putInt(flags);
+ buf.putInt(fileName.length());
+ putString(buf, fileName);
+
+ finishChunkPacket(packet, CHUNK_MPRS, buf.position());
+ Log.d("ddm-prof", "Sending " + name(CHUNK_MPRS) + " '" + fileName
+ + "', size=" + bufferSize + ", flags=" + flags);
+ client.sendAndConsume(packet, mInst);
+ }
+
+ /**
+ * Send a MPRE (Method PRofiling End) request to the client.
+ */
+ public static void sendMPRE(Client client) throws IOException {
+ ByteBuffer rawBuf = allocBuffer(0);
+ JdwpPacket packet = new JdwpPacket(rawBuf);
+ ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+ // no data
+
+ finishChunkPacket(packet, CHUNK_MPRE, buf.position());
+ Log.d("ddm-prof", "Sending " + name(CHUNK_MPRE));
+ client.sendAndConsume(packet, mInst);
+ }
+
+ /**
+ * Handle notification that method profiling has finished writing
+ * data to disk.
+ */
+ private void handleMPRE(Client client, ByteBuffer data) {
+ byte result;
+
+ result = data.get();
+
+ if (result == 0) {
+ Log.i("ddm-prof", "Method profiling has finished");
+ } else {
+ Log.w("ddm-prof", "Method profiling has failed (check device log)");
+ }
+
+ // TODO: stuff
+ }
+
+ /**
+ * Send a MPRQ (Method PRofiling Query) request to the client.
+ */
+ public static void sendMPRQ(Client client) throws IOException {
+ ByteBuffer rawBuf = allocBuffer(0);
+ JdwpPacket packet = new JdwpPacket(rawBuf);
+ ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+ // no data
+
+ finishChunkPacket(packet, CHUNK_MPRQ, buf.position());
+ Log.d("ddm-prof", "Sending " + name(CHUNK_MPRQ));
+ client.sendAndConsume(packet, mInst);
+ }
+
+ /**
+ * Receive response to query.
+ */
+ private void handleMPRQ(Client client, ByteBuffer data) {
+ byte result;
+
+ result = data.get();
+
+ if (result == 0) {
+ Log.i("ddm-prof", "Method profiling is not running");
+ } else {
+ Log.i("ddm-prof", "Method profiling is running");
+ }
+ }
+}
+
diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
index e7cffea..1c4a043 100644
--- a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
+++ b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
@@ -2,7 +2,7 @@
<feature
id="com.android.ide.eclipse.adt"
label="Android Development Tools"
- version="0.9.0.qualifier"
+ version="0.9.1.qualifier"
provider-name="The Android Open Source Project"
plugin="com.android.ide.eclipse.adt">
diff --git a/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
index 00805e4..ae3944b 100644
--- a/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
+++ b/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
@@ -2,7 +2,7 @@
<feature
id="com.android.ide.eclipse.ddms"
label="Android DDMS"
- version="0.9.0.qualifier"
+ version="0.9.1.qualifier"
provider-name="The Android Open Source Project">
<description>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
index 2a3a74f..b88f071 100644
--- a/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
+++ b/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
@@ -2,7 +2,7 @@
<feature
id="com.android.ide.eclipse.tests"
label="ADT Tests"
- version="0.9.0.qualifier"
+ version="0.9.1.qualifier"
provider-name="The Android Open Source Project">
<copyright>
diff --git a/tools/eclipse/plugins/.gitignore b/tools/eclipse/plugins/.gitignore
new file mode 100644
index 0000000..2842bb1
--- /dev/null
+++ b/tools/eclipse/plugins/.gitignore
@@ -0,0 +1,52 @@
+com.android.ide.eclipse.adt/bin
+com.android.ide.eclipse.ddms/bin
+com.android.ide.eclipse.tests/bin
+
+com.android.ide.eclipse.adt/androidprefs.jar
+com.android.ide.eclipse.adt/jarutils.jar
+com.android.ide.eclipse.adt/kxml2-2.3.0.jar
+com.android.ide.eclipse.adt/layoutlib_api.jar
+com.android.ide.eclipse.adt/layoutlib_utils.jar
+com.android.ide.eclipse.adt/ninepatch.jar
+com.android.ide.eclipse.adt/sdklib.jar
+com.android.ide.eclipse.adt/sdkstats.jar
+com.android.ide.eclipse.adt/sdkuilib.jar
+com.android.ide.eclipse.ddms/icons/add.png
+com.android.ide.eclipse.ddms/icons/backward.png
+com.android.ide.eclipse.ddms/icons/clear.png
+com.android.ide.eclipse.ddms/icons/d.png
+com.android.ide.eclipse.ddms/icons/debug-attach.png
+com.android.ide.eclipse.ddms/icons/debug-error.png
+com.android.ide.eclipse.ddms/icons/debug-wait.png
+com.android.ide.eclipse.ddms/icons/delete.png
+com.android.ide.eclipse.ddms/icons/device.png
+com.android.ide.eclipse.ddms/icons/down.png
+com.android.ide.eclipse.ddms/icons/e.png
+com.android.ide.eclipse.ddms/icons/edit.png
+com.android.ide.eclipse.ddms/icons/empty.png
+com.android.ide.eclipse.ddms/icons/emulator.png
+com.android.ide.eclipse.ddms/icons/forward.png
+com.android.ide.eclipse.ddms/icons/gc.png
+com.android.ide.eclipse.ddms/icons/halt.png
+com.android.ide.eclipse.ddms/icons/heap.png
+com.android.ide.eclipse.ddms/icons/i.png
+com.android.ide.eclipse.ddms/icons/importBug.png
+com.android.ide.eclipse.ddms/icons/load.png
+com.android.ide.eclipse.ddms/icons/pause.png
+com.android.ide.eclipse.ddms/icons/play.png
+com.android.ide.eclipse.ddms/icons/pull.png
+com.android.ide.eclipse.ddms/icons/push.png
+com.android.ide.eclipse.ddms/icons/save.png
+com.android.ide.eclipse.ddms/icons/thread.png
+com.android.ide.eclipse.ddms/icons/up.png
+com.android.ide.eclipse.ddms/icons/v.png
+com.android.ide.eclipse.ddms/icons/w.png
+com.android.ide.eclipse.ddms/icons/warning.png
+com.android.ide.eclipse.ddms/libs/jcommon-1.0.12.jar
+com.android.ide.eclipse.ddms/libs/jfreechart-1.0.9-swt.jar
+com.android.ide.eclipse.ddms/libs/jfreechart-1.0.9.jar
+com.android.ide.eclipse.ddms/src/com/android/ddmlib
+com.android.ide.eclipse.ddms/src/com/android/ddmuilib
+com.android.ide.eclipse.tests/kxml2-2.3.0.jar
+com.android.ide.eclipse.tests/unittests/com/android/ddmlib
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
index a24fc87..9898b97 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
@@ -5,7 +5,7 @@
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="lib" path="jarutils.jar"/>
<classpathentry kind="lib" path="androidprefs.jar"/>
- <classpathentry kind="lib" path="sdkstats.jar"/>
+ <classpathentry kind="lib" path="sdkstats.jar" sourcepath="/SdkStatsService"/>
<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
<classpathentry kind="lib" path="layoutlib_api.jar"/>
<classpathentry kind="lib" path="layoutlib_utils.jar"/>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
index 8092f3a..7d52bb6 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: Android Development Toolkit
Bundle-SymbolicName: com.android.ide.eclipse.adt;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.9.1.qualifier
Bundle-ClassPath: .,
jarutils.jar,
androidprefs.jar,
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
index 19cd509..6022a20 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
@@ -98,7 +98,7 @@
<wizard
canFinishEarly="false"
category="com.android.ide.eclipse.wizards.category"
- class="com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileWizard"
+ class="com.android.ide.eclipse.editors.wizards.NewXmlFileWizard"
finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
hasPages="true"
icon="icons/android.png"
@@ -220,7 +220,7 @@
value="com.android.ide.eclipse.adt.AndroidNature">
</filter>
<action
- class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileWizardAction"
+ class="com.android.ide.eclipse.adt.project.NewXmlFileWizardAction"
enablesFor="1"
id="com.android.ide.eclipse.adt.project.NewXmlFileWizardAction"
label="New Resource File..."
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
index b5cee81..8ef0f2c 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
@@ -31,7 +31,6 @@
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.adt.ui.EclipseUiHelper;
import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.SdkStatsHelper;
import com.android.ide.eclipse.common.StreamHelper;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.common.project.ExportHelper;
@@ -51,6 +50,7 @@
import com.android.ide.eclipse.editors.xml.XmlEditor;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
+import com.android.sdkstats.SdkStatsService;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
@@ -983,13 +983,7 @@
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
-
- // get the version of the plugin
- String versionString = (String) getBundle().getHeaders().get(
- Constants.BUNDLE_VERSION);
- Version version = new Version(versionString);
-
- SdkStatsHelper.pingUsageServer("adt", version); //$NON-NLS-1$
+ pingUsageServer(); //$NON-NLS-1$
return Status.OK_STATUS;
} catch (Throwable t) {
@@ -1389,4 +1383,22 @@
public static synchronized OutputStream getErrorStream() {
return sPlugin.mAndroidConsoleErrorStream;
}
+
+ /**
+ * Pings the usage start server.
+ * @param pluginName the name of the plugin to appear in the stats
+ * @param pluginVersion the {@link Version} of the plugin.
+ */
+ private void pingUsageServer() {
+ // get the version of the plugin
+ String versionString = (String) getBundle().getHeaders().get(
+ Constants.BUNDLE_VERSION);
+ Version version = new Version(versionString);
+
+ versionString = String.format("%1$d.%2$d.%3$d", version.getMajor(), //$NON-NLS-1$
+ version.getMinor(), version.getMicro());
+
+ SdkStatsService.ping("adt", versionString, getDisplay()); //$NON-NLS-1$
+ }
+
}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
index 47ea3e7..2121fa6 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
@@ -907,6 +907,21 @@
AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
return false;
+ } catch (Exception e) {
+ // try to catch other exception to actually display an error. This will be useful
+ // if we get an NPE or something so that we can at least notify the user that something
+ // went wrong (otherwise the build appears to succeed but the zip archive is not closed
+ // and therefore invalid.
+ String msg = e.getMessage();
+ if (msg == null) {
+ msg = e.getClass().getCanonicalName();
+ }
+
+ msg = String.format("Unknown error: %1$s", msg);
+ AdtPlugin.printErrorToConsole(javaProject.getProject(), msg);
+ markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);
+ return false;
+
} finally {
if (fos != null) {
try {
@@ -943,7 +958,8 @@
IPath path = resource.getFullPath();
// check the extension.
- if (path.getFileExtension().equalsIgnoreCase(AndroidConstants.EXT_NATIVE_LIB)) {
+ String ext = path.getFileExtension();
+ if (ext != null && ext.equalsIgnoreCase(AndroidConstants.EXT_NATIVE_LIB)) {
// remove the first segment to build the path inside the archive.
path = path.removeFirstSegments(rootSegmentCount);
@@ -954,7 +970,8 @@
// writes the file in the apk.
jarBuilder.writeFile(resource.getLocation().toFile(), apkPath.toString());
}
- } else if (resource.getType() == IResource.FOLDER) {
+ } else if (resource.getType() == IResource.FOLDER &&
+ checkFolderForPackaging((IFolder)resource)) {
IResource[] members = ((IFolder)resource).members();
for (IResource member : members) {
writeNativeLibraries(rootSegmentCount, jarBuilder, member);
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
index df023b8..e56f27e 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
@@ -271,8 +271,7 @@
// if there was some XML errors, we just return w/o doing
// anything since we've put some markers in the files anyway.
if (dv != null && dv.mXmlError) {
- AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
- Messages.Xml_Error);
+ AdtPlugin.printErrorToConsole(project, Messages.Xml_Error);
// This interrupts the build. The next builders will not run.
stopBuild(Messages.Xml_Error);
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/SdkStatsHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/SdkStatsHelper.java
deleted file mode 100644
index 345c663..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/SdkStatsHelper.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.common;
-
-import com.android.sdkstats.SdkStatsService;
-
-import org.osgi.framework.Version;
-
-/**
- * Helper class to access the ping usage stat server.
- */
-public class SdkStatsHelper {
-
- /**
- * Pings the usage start server.
- * @param pluginName the name of the plugin to appear in the stats
- * @param pluginVersion the {@link Version} of the plugin.
- */
- public static void pingUsageServer(String pluginName, Version pluginVersion) {
- String versionString = String.format("%1$d.%2$d.%3$d", pluginVersion.getMajor(),
- pluginVersion.getMinor(), pluginVersion.getMicro());
-
- SdkStatsService.ping(pluginName, versionString);
- }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
index 3b5c823..cd02e27 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
@@ -334,10 +334,12 @@
value = getAttributeValue(attributes, ATTRIBUTE_MIN_SDK_VERSION,
true /* hasNamespace */);
- try {
- mApiLevelRequirement = Integer.parseInt(value);
- } catch (NumberFormatException e) {
- handleError(e, -1 /* lineNumber */);
+ if (value != null) {
+ try {
+ mApiLevelRequirement = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ handleError(e, -1 /* lineNumber */);
+ }
}
} else if (NODE_INSTRUMENTATION.equals(localName)) {
processInstrumentationNode(attributes);
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
index 1810ad2..589e70b 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
@@ -109,17 +109,22 @@
mErrorListener.errorFound();
}
+ String message = exception.getMessage();
+ if (message == null) {
+ message = "Unknown error " + exception.getClass().getCanonicalName();
+ }
+
if (mFile != null) {
if (lineNumber != -1) {
BaseProjectHelper.addMarker(mFile,
AndroidConstants.MARKER_XML,
- exception.getMessage(),
+ message,
lineNumber,
IMarker.SEVERITY_ERROR);
} else {
BaseProjectHelper.addMarker(mFile,
AndroidConstants.MARKER_XML,
- exception.getMessage(),
+ message,
IMarker.SEVERITY_ERROR);
}
}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF
index 09b8085..2488fd1 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: Dalvik Debug Monitor Service
Bundle-SymbolicName: com.android.ide.eclipse.ddms;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.9.1.qualifier
Bundle-Activator: com.android.ide.eclipse.ddms.DdmsPlugin
Bundle-Vendor: The Android Open Source Project
Bundle-Localization: plugin
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
index c7f5ba8..22cda71 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: Android Plugin Tests
Bundle-SymbolicName: com.android.ide.eclipse.tests
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.9.1.qualifier
Bundle-Activator: com.android.ide.eclipse.tests.AndroidTestPlugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
diff --git a/tools/eclipse/sites/external/site.xml b/tools/eclipse/sites/external/site.xml
index 9fca8d2..404abe5 100644
--- a/tools/eclipse/sites/external/site.xml
+++ b/tools/eclipse/sites/external/site.xml
@@ -3,10 +3,10 @@
<description url="https://dl-ssl.google.com/android/eclipse/">
Update Site for Android Development Toolkit
</description>
- <feature url="features/com.android.ide.eclipse.adt_0.9.0.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.0.qualifier">
+ <feature url="features/com.android.ide.eclipse.adt_0.9.1.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.1.qualifier">
<category name="developer"/>
</feature>
- <feature url="features/com.android.ide.eclipse.ddms_0.9.0.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.0.qualifier">
+ <feature url="features/com.android.ide.eclipse.ddms_0.9.1.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.1.qualifier">
<category name="developer"/>
</feature>
<category-def name="developer" label="Developer Tools">
diff --git a/tools/eclipse/sites/internal/site.xml b/tools/eclipse/sites/internal/site.xml
index 9f2642f..b53af92 100644
--- a/tools/eclipse/sites/internal/site.xml
+++ b/tools/eclipse/sites/internal/site.xml
@@ -3,13 +3,13 @@
<description url="https://android.corp.google.com/adt/">
Update Site for Android Development Toolkit
</description>
- <feature url="features/com.android.ide.eclipse.adt_0.9.0.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.0.qualifier">
+ <feature url="features/com.android.ide.eclipse.adt_0.9.1.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.1.qualifier">
<category name="developer"/>
</feature>
- <feature url="features/com.android.ide.eclipse.ddms_0.9.0.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.0.qualifier">
+ <feature url="features/com.android.ide.eclipse.ddms_0.9.1.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.1.qualifier">
<category name="developer"/>
</feature>
- <feature url="features/com.android.ide.eclipse.tests_0.9.0.qualifier.jar" id="com.android.ide.eclipse.tests" version="0.9.0.qualifier">
+ <feature url="features/com.android.ide.eclipse.tests_0.9.1.qualifier.jar" id="com.android.ide.eclipse.tests" version="0.9.1.qualifier">
<category name="test"/>
</feature>
<category-def name="developer" label="Application Developer Tools">
diff --git a/tools/jarutils/.gitignore b/tools/jarutils/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/jarutils/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/layoutlib_utils/.gitignore b/tools/layoutlib_utils/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/layoutlib_utils/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java b/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
index 8a8a677..77a6401 100755
--- a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
+++ b/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
@@ -96,6 +96,7 @@
parser.parse(new File(filename), new DefaultHandler() {
boolean inWord;
int freq;
+ StringBuilder wordBuilder = new StringBuilder(48);
@Override
public void startElement(String uri, String localName,
@@ -103,6 +104,7 @@
if (qName.equals("w")) {
inWord = true;
freq = Integer.parseInt(attributes.getValue(0));
+ wordBuilder.setLength(0);
}
}
@@ -110,18 +112,19 @@
public void characters(char[] data, int offset, int length) {
// Ignore other whitespace
if (!inWord) return;
-
- // Ignore one letter words
- if (length < 2) return;
- mWordCount++;
- String word = new String(data, offset, length);
- addWordTop(word, freq);
+ wordBuilder.append(data, offset, length);
}
@Override
public void endElement(String uri, String localName,
String qName) {
- if (qName.equals("w")) inWord = false;
+ if (qName.equals("w")) {
+ if (wordBuilder.length() > 1) {
+ addWordTop(wordBuilder.toString(), freq);
+ mWordCount++;
+ }
+ inWord = false;
+ }
}
});
} catch (Exception ioe) {
@@ -145,7 +148,6 @@
private void addWordTop(String word, int occur) {
if (occur > 255) occur = 255;
-
char firstChar = word.charAt(0);
int index = indexOf(roots, firstChar);
if (index == -1) {
diff --git a/tools/mkstubs/.classpath b/tools/mkstubs/.classpath
index a6b4c47..49a6d6c 100644
--- a/tools/mkstubs/.classpath
+++ b/tools/mkstubs/.classpath
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="src" path="tests"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
- <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
- <classpathentry combineaccessrules="false" kind="src" path="/asm3"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="tests"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+ <classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-3.1.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/mkstubs/.gitignore b/tools/mkstubs/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/mkstubs/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/mkstubs/.project b/tools/mkstubs/.project
index bef013e..12944f4 100644
--- a/tools/mkstubs/.project
+++ b/tools/mkstubs/.project
@@ -1,18 +1,17 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>MkStubs</name>
- <comment></comment>
- <projects>
- <project>asm3</project>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>MkStubs</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/tools/sdkmanager/.gitignore b/tools/sdkmanager/.gitignore
new file mode 100644
index 0000000..48f206a
--- /dev/null
+++ b/tools/sdkmanager/.gitignore
@@ -0,0 +1,4 @@
+app/bin
+libs/sdklib/bin
+libs/sdkuilib/bin
+
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
index fc9a2be..35d9bb1 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -454,16 +454,18 @@
// display some extra values.
Map<String, String> properties = info.getProperties();
- String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME);
- if (skin != null) {
- mSdkLog.printf(" Skin: %s\n", skin);
- }
- String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE);
- if (sdcard == null) {
- sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH);
- }
- if (sdcard != null) {
- mSdkLog.printf(" Sdcard: %s\n", sdcard);
+ if (properties != null) {
+ String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME);
+ if (skin != null) {
+ mSdkLog.printf(" Skin: %s\n", skin);
+ }
+ String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE);
+ if (sdcard == null) {
+ sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH);
+ }
+ if (sdcard != null) {
+ mSdkLog.printf(" Sdcard: %s\n", sdcard);
+ }
}
}
@@ -508,7 +510,7 @@
}
try {
- boolean removePrevious = false;
+ boolean removePrevious = mSdkCommandLine.getFlagForce();
AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
String avdName = mSdkCommandLine.getParamName();
@@ -522,8 +524,7 @@
AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/);
if (info != null) {
- if (mSdkCommandLine.getFlagForce()) {
- removePrevious = true;
+ if (removePrevious) {
mSdkLog.warning(
"Android Virtual Device '%s' already exists and will be replaced.",
avdName);
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
index 1936f8a..23b2f26 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
@@ -185,7 +185,7 @@
* @param targetHash the target hash
* @param target The target. Can be null, if the target was not resolved.
* @param properties The property map. Can be null.
- * @param error The error describing why this AVD is invalid. Cannot be null.
+ * @param status The {@link AvdStatus} of this AVD. Cannot be null.
*/
public AvdInfo(String name, String path, String targetHash, IAndroidTarget target,
Map<String, String> properties, AvdStatus status) {
@@ -193,7 +193,7 @@
mPath = path;
mTargetHash = targetHash;
mTarget = target;
- mProperties = Collections.unmodifiableMap(properties);
+ mProperties = properties == null ? null : Collections.unmodifiableMap(properties);
mStatus = status;
}
@@ -214,7 +214,7 @@
return mTargetHash;
}
- /** Returns the target of the AVD, or <code>null</code> if it has not been resolved */
+ /** Returns the target of the AVD, or <code>null</code> if it has not been resolved. */
public IAndroidTarget getTarget() {
return mTarget;
}
@@ -257,7 +257,7 @@
}
/**
- * Returns a map of properties for the AVD.
+ * Returns an unmodifiable map of properties for the AVD. This can be null.
*/
public Map<String, String> getProperties() {
return mProperties;
@@ -1173,7 +1173,9 @@
// create a new map
Map<String, String> properties = new HashMap<String, String>();
- properties.putAll(oldProperties);
+ if (oldProperties != null) {
+ properties.putAll(oldProperties);
+ }
AvdStatus status;
diff --git a/tools/sdkstats/.gitignore b/tools/sdkstats/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/sdkstats/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java b/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
index 0b3d41b..688474e 100644
--- a/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
+++ b/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
@@ -110,8 +110,10 @@
*
* @param app name to report in the ping
* @param version to report in the ping
+ * @param display an optional {@link Display} object to use, or null, if a new one should be
+ * created.
*/
- public static void ping(final String app, final String version) {
+ public static void ping(final String app, final String version, final Display display) {
// Validate the application and version input.
final String normalVersion = normalizeVersion(app, version);
@@ -123,7 +125,7 @@
prefs.setValue(PING_ID, new Random().nextLong());
// Also give them a chance to opt out.
- prefs.setValue(PING_OPT_IN, getUserPermission());
+ prefs.setValue(PING_OPT_IN, getUserPermission(display));
try {
prefs.save();
}
@@ -273,77 +275,90 @@
* Prompt the user for whether they want to opt out of reporting.
* @return whether the user allows reporting (they do not opt out).
*/
- private static boolean getUserPermission() {
- // Use dialog trim for the shell, but without a close button.
- final Display display = new Display();
- final Shell shell = new Shell(display, SWT.TITLE | SWT.BORDER);
- shell.setText(WINDOW_TITLE_TEXT);
- shell.setLayout(new GridLayout(1, false)); // 1 column
-
- // Take the default font and scale it up for the title.
- final Label title = new Label(shell, SWT.CENTER | SWT.WRAP);
- final FontData[] fontdata = title.getFont().getFontData();
- for (int i = 0; i < fontdata.length; i++) {
- fontdata[i].setHeight(fontdata[i].getHeight() * 4 / 3);
- }
- title.setFont(new Font(display, fontdata));
- title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- title.setText(HEADER_TEXT);
-
- final Label notice = new Label(shell, SWT.WRAP);
- notice.setFont(title.getFont());
- notice.setForeground(new Color(display, 255, 0, 0));
- notice.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- notice.setText(NOTICE_TEXT);
-
- final Link text = new Link(shell, SWT.WRAP);
- text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- text.setText(BODY_TEXT);
- text.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent event) {
- openUrl(event.text);
- }
- });
-
- final Button checkbox = new Button(shell, SWT.CHECK);
- checkbox.setSelection(true); // Opt-in by default.
- checkbox.setText(CHECKBOX_TEXT);
-
- final Link footer = new Link(shell, SWT.WRAP);
- footer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- footer.setText(FOOTER_TEXT);
-
+ private static boolean getUserPermission(Display display) {
// Whether the user gave permission (size-1 array for writing to).
// Initialize to false, set when the user clicks the button.
final boolean[] permission = new boolean[] { false };
- final Button button = new Button(shell, SWT.PUSH);
- button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
- button.setText(BUTTON_TEXT);
- button.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent event) {
- permission[0] = checkbox.getSelection();
- shell.close();
+ boolean dispose = false;
+ if (display == null) {
+ display = new Display();
+ dispose = true;
+ }
+
+ final Display currentDisplay = display;
+ final boolean disposeDisplay = dispose;
+
+ display.syncExec(new Runnable() {
+ public void run() {
+ final Shell shell = new Shell(currentDisplay, SWT.TITLE | SWT.BORDER);
+ shell.setText(WINDOW_TITLE_TEXT);
+ shell.setLayout(new GridLayout(1, false)); // 1 column
+
+ // Take the default font and scale it up for the title.
+ final Label title = new Label(shell, SWT.CENTER | SWT.WRAP);
+ final FontData[] fontdata = title.getFont().getFontData();
+ for (int i = 0; i < fontdata.length; i++) {
+ fontdata[i].setHeight(fontdata[i].getHeight() * 4 / 3);
+ }
+ title.setFont(new Font(currentDisplay, fontdata));
+ title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ title.setText(HEADER_TEXT);
+
+ final Label notice = new Label(shell, SWT.WRAP);
+ notice.setFont(title.getFont());
+ notice.setForeground(new Color(currentDisplay, 255, 0, 0));
+ notice.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ notice.setText(NOTICE_TEXT);
+
+ final Link text = new Link(shell, SWT.WRAP);
+ text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ text.setText(BODY_TEXT);
+ text.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ openUrl(event.text);
+ }
+ });
+
+ final Button checkbox = new Button(shell, SWT.CHECK);
+ checkbox.setSelection(true); // Opt-in by default.
+ checkbox.setText(CHECKBOX_TEXT);
+
+ final Link footer = new Link(shell, SWT.WRAP);
+ footer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ footer.setText(FOOTER_TEXT);
+
+ final Button button = new Button(shell, SWT.PUSH);
+ button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+ button.setText(BUTTON_TEXT);
+ button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ permission[0] = checkbox.getSelection();
+ shell.close();
+ }
+ });
+
+ // Size the window to a fixed width, as high as necessary,
+ // centered.
+ final Point size = shell.computeSize(450, SWT.DEFAULT, true);
+ final Rectangle screen = currentDisplay.getClientArea();
+ shell.setBounds(screen.x + screen.width / 2 - size.x / 2, screen.y + screen.height
+ / 2 - size.y / 2, size.x, size.y);
+
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!currentDisplay.readAndDispatch())
+ currentDisplay.sleep();
+ }
+
+ if (disposeDisplay) {
+ currentDisplay.dispose();
+ }
}
});
- // Size the window to a fixed width, as high as necessary, centered.
- final Point size = shell.computeSize(450, SWT.DEFAULT, true);
- final Rectangle screen = display.getClientArea();
- shell.setBounds(
- screen.x + screen.width / 2 - size.x / 2,
- screen.y + screen.height / 2 - size.y / 2,
- size.x, size.y);
-
- shell.open();
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
-
- display.dispose(); // Otherwise ddms' own Display can't be created
return permission[0];
}
diff --git a/tools/traceview/.gitignore b/tools/traceview/.gitignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/tools/traceview/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/tools/traceview/src/com/android/traceview/MainWindow.java b/tools/traceview/src/com/android/traceview/MainWindow.java
index b0c24e9..5800f81 100644
--- a/tools/traceview/src/com/android/traceview/MainWindow.java
+++ b/tools/traceview/src/com/android/traceview/MainWindow.java
@@ -133,7 +133,7 @@
boolean regression = false;
// ping the usage server
- SdkStatsService.ping(PING_NAME, PING_VERSION);
+ SdkStatsService.ping(PING_NAME, PING_VERSION, null);
// Process command line arguments
int argc = 0;
diff --git a/tools/yuv420sp2rgb/Android.mk b/tools/yuv420sp2rgb/Android.mk
new file mode 100644
index 0000000..b7e7802
--- /dev/null
+++ b/tools/yuv420sp2rgb/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2005 Google Inc. All Rights Reserved.
+#
+# Android.mk for yuv420sp2rgb
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(TARGET_ARCH),arm)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := yuv420sp2rgb.c cmdline.c debug.c
+
+LOCAL_MODULE := yuv420sp2rgb
+
+include $(BUILD_HOST_EXECUTABLE)
+endif
diff --git a/tools/yuv420sp2rgb/cmdline.c b/tools/yuv420sp2rgb/cmdline.c
new file mode 100644
index 0000000..eb870b5
--- /dev/null
+++ b/tools/yuv420sp2rgb/cmdline.c
@@ -0,0 +1,147 @@
+#include <debug.h>
+#include <cmdline.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <ctype.h>
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+static struct option long_options[] = {
+ {"output", required_argument, 0, 'o'},
+ {"height", required_argument, 0, 'h'},
+ {"width", required_argument, 0, 'w'},
+ {"gray", no_argument, 0, 'g'},
+ {"type", required_argument, 0, 't'},
+ {"rotate", required_argument, 0, 'r'},
+ {"verbose", no_argument, 0, 'V'},
+ {"help", no_argument, 0, 1},
+ {0, 0, 0, 0},
+};
+
+/* This array must parallel long_options[] */
+static const char *descriptions[] = {
+ "output file",
+ "image height in pixels",
+ "image width in pixels",
+ "process the luma plane only",
+ "encode as one of { 'ppm', 'rgb', or 'argb' }",
+ "rotate (90, -90, 180 degrees)",
+ "print verbose output",
+ "print this help screen",
+};
+
+void print_help(const char *name) {
+ fprintf(stdout,
+ "Converts yuv 4:2:0 to rgb24 and generates a PPM file.\n"
+ "invokation:\n"
+ "\t%s infile --height <height> --width <width> --output <outfile> -t <ppm|grb|argb> [ --gray ] [ --rotate <degrees> ] [ --verbose ]\n"
+ "\t%s infile --help\n",
+ name, name);
+ fprintf(stdout, "options:\n");
+ struct option *opt = long_options;
+ const char **desc = descriptions;
+ while (opt->name) {
+ fprintf(stdout, "\t-%c/--%s%s: %s\n",
+ isprint(opt->val) ? opt->val : ' ',
+ opt->name,
+ (opt->has_arg ? " (argument)" : ""),
+ *desc);
+ opt++;
+ desc++;
+ }
+}
+
+int get_options(int argc, char **argv,
+ char **outfile,
+ int *height,
+ int *width,
+ int *gray,
+ char **type,
+ int *rotate,
+ int *verbose) {
+ int c;
+
+ ASSERT(outfile); *outfile = NULL;
+ ASSERT(height); *height = -1;
+ ASSERT(width); *width = -1;
+ ASSERT(gray); *gray = 0;
+ ASSERT(rotate); *rotate = 0;
+ ASSERT(verbose); *verbose = 0;
+ ASSERT(type); *type = NULL;
+
+ while (1) {
+ /* getopt_long stores the option index here. */
+ int option_index = 0;
+
+ c = getopt_long (argc, argv,
+ "Vgo:h:w:r:t:",
+ long_options,
+ &option_index);
+ /* Detect the end of the options. */
+ if (c == -1) break;
+
+ if (isgraph(c)) {
+ INFO ("option -%c with value `%s'\n", c, (optarg ?: "(null)"));
+ }
+
+#define SET_STRING_OPTION(name) do { \
+ ASSERT(optarg); \
+ (*name) = strdup(optarg); \
+} while(0)
+
+#define SET_INT_OPTION(val) do { \
+ ASSERT(optarg); \
+ if (strlen(optarg) >= 2 && optarg[0] == '0' && optarg[1] == 'x') { \
+ FAILIF(1 != sscanf(optarg+2, "%x", val), \
+ "Expecting a hexadecimal argument!\n"); \
+ } else { \
+ FAILIF(1 != sscanf(optarg, "%d", val), \
+ "Expecting a decimal argument!\n"); \
+ } \
+} while(0)
+
+ switch (c) {
+ case 0:
+ /* If this option set a flag, do nothing else now. */
+ if (long_options[option_index].flag != 0)
+ break;
+ INFO ("option %s", long_options[option_index].name);
+ if (optarg)
+ INFO (" with arg %s", optarg);
+ INFO ("\n");
+ break;
+ case 1: print_help(argv[0]); exit(1); break;
+ case 'o':
+ SET_STRING_OPTION(outfile);
+ break;
+ case 't':
+ SET_STRING_OPTION(type);
+ break;
+ case 'h':
+ SET_INT_OPTION(height);
+ break;
+ case 'w':
+ SET_INT_OPTION(width);
+ break;
+ case 'r':
+ SET_INT_OPTION(rotate);
+ break;
+ case 'g': *gray = 1; break;
+ case 'V': *verbose = 1; break;
+ case '?':
+ /* getopt_long already printed an error message. */
+ break;
+
+#undef SET_STRING_OPTION
+#undef SET_INT_OPTION
+
+ default:
+ FAILIF(1, "Unknown option");
+ }
+ }
+
+ return optind;
+}
diff --git a/tools/yuv420sp2rgb/cmdline.h b/tools/yuv420sp2rgb/cmdline.h
new file mode 100644
index 0000000..49760ad
--- /dev/null
+++ b/tools/yuv420sp2rgb/cmdline.h
@@ -0,0 +1,15 @@
+#ifndef CMDLINE_H
+#define CMDLINE_H
+
+void print_help(const char *executable_name);
+
+extern int get_options(int argc, char **argv,
+ char **outfile,
+ int *height,
+ int *width,
+ int *gray,
+ char **type,
+ int *rotate,
+ int *verbose);
+
+#endif/*CMDLINE_H*/
diff --git a/tools/yuv420sp2rgb/debug.c b/tools/yuv420sp2rgb/debug.c
new file mode 100644
index 0000000..263e09f
--- /dev/null
+++ b/tools/yuv420sp2rgb/debug.c
@@ -0,0 +1,38 @@
+#include <debug.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define NUM_COLS (32)
+
+int dump_hex_buffer(FILE *s, void *b, size_t len, size_t elsize) {
+ int num_nonprintable = 0;
+ int i, last;
+ char *pchr = (char *)b;
+ fputc('\n', s);
+ fprintf(s, "%p: ", b);
+ for (i = last = 0; i < len; i++) {
+ if (!elsize) {
+ if (i && !(i % 4)) fprintf(s, " ");
+ if (i && !(i % 8)) fprintf(s, " ");
+ } else {
+ if (i && !(i % elsize)) fprintf(s, " ");
+ }
+
+ if (i && !(i % NUM_COLS)) {
+ while (last < i) {
+ if (isprint(pchr[last]))
+ fputc(pchr[last], s);
+ else {
+ fputc('.', s);
+ num_nonprintable++;
+ }
+ last++;
+ }
+ fprintf(s, " (%d)\n%p: ", i, b);
+ }
+ fprintf(s, "%02x", (unsigned char)pchr[i]);
+ }
+ if (i && (i % NUM_COLS)) fputs("\n", s);
+ return num_nonprintable;
+}
+
diff --git a/tools/yuv420sp2rgb/debug.h b/tools/yuv420sp2rgb/debug.h
new file mode 100644
index 0000000..9bbf47f
--- /dev/null
+++ b/tools/yuv420sp2rgb/debug.h
@@ -0,0 +1,90 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define unlikely(expr) __builtin_expect (expr, 0)
+#define likely(expr) __builtin_expect (expr, 1)
+
+#ifdef DEBUG
+
+ #define FAILIF(cond, msg...) do { \
+ if (unlikely(cond)) { \
+ fprintf(stderr, "%s(%d): ", __FILE__, __LINE__); \
+ fprintf(stderr, ##msg); \
+ exit(1); \
+ } \
+} while(0)
+
+/* Debug enabled */
+ #define ASSERT(x) do { \
+ if (unlikely(!(x))) { \
+ fprintf(stderr, \
+ "ASSERTION FAILURE %s:%d: [%s]\n", \
+ __FILE__, __LINE__, #x); \
+ exit(1); \
+ } \
+} while(0)
+
+#else
+
+ #define FAILIF(cond, msg...) do { \
+ if (unlikely(cond)) { \
+ fprintf(stderr, ##msg); \
+ exit(1); \
+ } \
+} while(0)
+
+/* No debug */
+ #define ASSERT(x) do { } while(0)
+
+#endif/* DEBUG */
+
+#define FAILIF_LIBELF(cond, function) \
+ FAILIF(cond, "%s(): %s\n", #function, elf_errmsg(elf_errno()));
+
+static inline void *MALLOC(unsigned int size) {
+ void *m = malloc(size);
+ FAILIF(NULL == m, "malloc(%d) failed!\n", size);
+ return m;
+}
+
+static inline void *CALLOC(unsigned int num_entries, unsigned int entry_size) {
+ void *m = calloc(num_entries, entry_size);
+ FAILIF(NULL == m, "calloc(%d, %d) failed!\n", num_entries, entry_size);
+ return m;
+}
+
+static inline void *REALLOC(void *ptr, unsigned int size) {
+ void *m = realloc(ptr, size);
+ FAILIF(NULL == m, "realloc(%p, %d) failed!\n", ptr, size);
+ return m;
+}
+
+static inline void FREE(void *ptr) {
+ free(ptr);
+}
+
+static inline void FREEIF(void *ptr) {
+ if (ptr) FREE(ptr);
+}
+
+#define PRINT(x...) do { \
+ extern int quiet_flag; \
+ if(likely(!quiet_flag)) \
+ fprintf(stdout, ##x); \
+} while(0)
+
+#define ERROR PRINT
+
+#define INFO(x...) do { \
+ extern int verbose_flag; \
+ if(unlikely(verbose_flag)) \
+ fprintf(stdout, ##x); \
+} while(0)
+
+/* Prints a hex and ASCII dump of the selected buffer to the selected stream. */
+int dump_hex_buffer(FILE *s, void *b, size_t l, size_t elsize);
+
+#endif/*DEBUG_H*/
diff --git a/tools/yuv420sp2rgb/yuv420sp2rgb.c b/tools/yuv420sp2rgb/yuv420sp2rgb.c
new file mode 100644
index 0000000..6fe82e5
--- /dev/null
+++ b/tools/yuv420sp2rgb/yuv420sp2rgb.c
@@ -0,0 +1,339 @@
+#include <stdio.h>
+#include <debug.h>
+#include <cmdline.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifndef max
+#define max(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
+#define min(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
+#endif
+
+#define CONVERT_TYPE_PPM 0
+#define CONVERT_TYPE_RGB 1
+#define CONVERT_TYPE_ARGB 2
+
+/*
+ YUV 4:2:0 image with a plane of 8 bit Y samples followed by an interleaved
+ U/V plane containing 8 bit 2x2 subsampled chroma samples.
+ except the interleave order of U and V is reversed.
+
+ H V
+ Y Sample Period 1 1
+ U (Cb) Sample Period 2 2
+ V (Cr) Sample Period 2 2
+ */
+
+typedef struct rgb_context {
+ unsigned char *buffer;
+ int width;
+ int height;
+ int rotate;
+ int i;
+ int j;
+ int size; /* for debugging */
+} rgb_context;
+
+typedef void (*rgb_cb)(
+ unsigned char r,
+ unsigned char g,
+ unsigned char b,
+ rgb_context *ctx);
+
+const int bytes_per_pixel = 2;
+
+static void color_convert_common(
+ unsigned char *pY, unsigned char *pUV,
+ int width, int height,
+ unsigned char *buffer,
+ int size, /* buffer size in bytes */
+ int gray,
+ int rotate,
+ rgb_cb cb)
+{
+ int i, j;
+ int nR, nG, nB;
+ int nY, nU, nV;
+ rgb_context ctx;
+
+ ctx.buffer = buffer;
+ ctx.size = size; /* debug */
+ ctx.width = width;
+ ctx.height = height;
+ ctx.rotate = rotate;
+
+ if (gray) {
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ nB = *(pY + i * width + j);
+ ctx.i = i;
+ ctx.j = j;
+ cb(nB, nB, nB, &ctx);
+ }
+ }
+ } else {
+ // YUV 4:2:0
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ nY = *(pY + i * width + j);
+ nV = *(pUV + (i/2) * width + bytes_per_pixel * (j/2));
+ nU = *(pUV + (i/2) * width + bytes_per_pixel * (j/2) + 1);
+
+ // Yuv Convert
+ nY -= 16;
+ nU -= 128;
+ nV -= 128;
+
+ if (nY < 0)
+ nY = 0;
+
+ // nR = (int)(1.164 * nY + 2.018 * nU);
+ // nG = (int)(1.164 * nY - 0.813 * nV - 0.391 * nU);
+ // nB = (int)(1.164 * nY + 1.596 * nV);
+
+ nB = (int)(1192 * nY + 2066 * nU);
+ nG = (int)(1192 * nY - 833 * nV - 400 * nU);
+ nR = (int)(1192 * nY + 1634 * nV);
+
+ nR = min(262143, max(0, nR));
+ nG = min(262143, max(0, nG));
+ nB = min(262143, max(0, nB));
+
+ nR >>= 10; nR &= 0xff;
+ nG >>= 10; nG &= 0xff;
+ nB >>= 10; nB &= 0xff;
+
+ ctx.i = i;
+ ctx.j = j;
+ cb(nR, nG, nB, &ctx);
+ }
+ }
+ }
+}
+
+static void rgb16_cb(
+ unsigned char r,
+ unsigned char g,
+ unsigned char b,
+ rgb_context *ctx)
+{
+ unsigned short *rgb16 = (unsigned short *)ctx->buffer;
+ *(rgb16 + ctx->i * ctx->width + ctx->j) = b | (g << 5) | (r << 11);
+}
+
+static void common_rgb_cb(
+ unsigned char r,
+ unsigned char g,
+ unsigned char b,
+ rgb_context *ctx,
+ int alpha)
+{
+ unsigned char *out = ctx->buffer;
+ int offset = 0;
+ int bpp;
+ int i = 0;
+ switch(ctx->rotate) {
+ case 0: /* no rotation */
+ offset = ctx->i * ctx->width + ctx->j;
+ break;
+ case 1: /* 90 degrees */
+ offset = ctx->height * (ctx->j + 1) - ctx->i;
+ break;
+ case 2: /* 180 degrees */
+ offset = (ctx->height - 1 - ctx->i) * ctx->width + ctx->j;
+ break;
+ case 3: /* 270 degrees */
+ offset = (ctx->width - 1 - ctx->j) * ctx->height + ctx->i;
+ break;
+ default:
+ FAILIF(1, "Unexpected roation value %d!\n", ctx->rotate);
+ }
+
+ bpp = 3 + !!alpha;
+ offset *= bpp;
+ FAILIF(offset < 0, "point (%d, %d) generates a negative offset.\n", ctx->i, ctx->j);
+ FAILIF(offset + bpp > ctx->size, "point (%d, %d) at offset %d exceeds the size %d of the buffer.\n",
+ ctx->i, ctx->j,
+ offset,
+ ctx->size);
+
+ out += offset;
+
+ if (alpha) out[i++] = 0xff;
+ out[i++] = r;
+ out[i++] = g;
+ out[i] = b;
+}
+
+static void rgb24_cb(
+ unsigned char r,
+ unsigned char g,
+ unsigned char b,
+ rgb_context *ctx)
+{
+ return common_rgb_cb(r,g,b,ctx,0);
+}
+
+static void argb_cb(
+ unsigned char r,
+ unsigned char g,
+ unsigned char b,
+ rgb_context *ctx)
+{
+ return common_rgb_cb(r,g,b,ctx,1);
+}
+
+static void convert(const char *infile,
+ const char *outfile,
+ int height,
+ int width,
+ int gray,
+ int type,
+ int rotate)
+{
+ void *in, *out;
+ int ifd, ofd, rc;
+ int psz = getpagesize();
+ static char header[1024];
+ int header_size;
+ size_t outsize;
+
+ int bpp = 3;
+ switch (type) {
+ case CONVERT_TYPE_PPM:
+ PRINT("encoding PPM\n");
+ if (rotate & 1)
+ header_size = snprintf(header, sizeof(header), "P6\n%d %d\n255\n", height, width);
+ else
+ header_size = snprintf(header, sizeof(header), "P6\n%d %d\n255\n", width, height);
+ break;
+ case CONVERT_TYPE_RGB:
+ PRINT("encoding raw RGB24\n");
+ header_size = 0;
+ break;
+ case CONVERT_TYPE_ARGB:
+ PRINT("encoding raw ARGB\n");
+ header_size = 0;
+ bpp = 4;
+ break;
+ }
+
+ outsize = header_size + width * height * bpp;
+ outsize = (outsize + psz - 1) & ~(psz - 1);
+
+ INFO("Opening input file %s\n", infile);
+ ifd = open(infile, O_RDONLY);
+ FAILIF(ifd < 0, "open(%s) failed: %s (%d)\n",
+ infile, strerror(errno), errno);
+
+ INFO("Opening output file %s\n", outfile);
+ ofd = open(outfile, O_RDWR | O_CREAT, 0664);
+ FAILIF(ofd < 0, "open(%s) failed: %s (%d)\n",
+ outfile, strerror(errno), errno);
+
+ INFO("Memory-mapping input file %s\n", infile);
+ in = mmap(0, width * height * 3 / 2, PROT_READ, MAP_PRIVATE, ifd, 0);
+ FAILIF(in == MAP_FAILED, "could not mmap input file: %s (%d)\n",
+ strerror(errno), errno);
+
+ INFO("Truncating output file %s to %d bytes\n", outfile, outsize);
+ FAILIF(ftruncate(ofd, outsize) < 0,
+ "Could not truncate output file to required size: %s (%d)\n",
+ strerror(errno), errno);
+
+ INFO("Memory mapping output file %s\n", outfile);
+ out = mmap(0, outsize, PROT_WRITE, MAP_SHARED, ofd, 0);
+ FAILIF(out == MAP_FAILED, "could not mmap output file: %s (%d)\n",
+ strerror(errno), errno);
+
+ INFO("PPM header (%d) bytes:\n%s\n", header_size, header);
+ FAILIF(write(ofd, header, header_size) != header_size,
+ "Error wrinting PPM header: %s (%d)\n",
+ strerror(errno), errno);
+
+ INFO("Converting %dx%d YUV 4:2:0 to RGB24...\n", width, height);
+ color_convert_common(in, in + width * height,
+ width, height,
+ out + header_size, outsize - header_size,
+ gray, rotate,
+ type == CONVERT_TYPE_ARGB ? argb_cb : rgb24_cb);
+}
+
+int verbose_flag;
+int quiet_flag;
+
+int main(int argc, char **argv) {
+
+ char *infile, *outfile, *type;
+ int height, width, gray, rotate;
+ int cmdline_error = 0;
+
+ /* Parse command-line arguments. */
+
+ int first = get_options(argc, argv,
+ &outfile,
+ &height,
+ &width,
+ &gray,
+ &type,
+ &rotate,
+ &verbose_flag);
+
+ if (first == argc) {
+ ERROR("You must specify an input file!\n");
+ cmdline_error++;
+ }
+ if (!outfile) {
+ ERROR("You must specify an output file!\n");
+ cmdline_error++;
+ }
+ if (height < 0 || width < 0) {
+ ERROR("You must specify both image height and width!\n");
+ cmdline_error++;
+ }
+
+ FAILIF(rotate % 90, "Rotation angle must be a multiple of 90 degrees!\n");
+
+ rotate /= 90;
+ rotate %= 4;
+ if (rotate < 0) rotate += 4;
+
+ if (cmdline_error) {
+ print_help(argv[0]);
+ exit(1);
+ }
+
+ infile = argv[first];
+
+ INFO("input file: [%s]\n", infile);
+ INFO("output file: [%s]\n", outfile);
+ INFO("height: %d\n", height);
+ INFO("width: %d\n", width);
+ INFO("gray only: %d\n", gray);
+ INFO("encode as: %s\n", type);
+ INFO("rotation: %d\n", rotate);
+
+ /* Convert the image */
+
+ int conv_type;
+ if (!type || !strcmp(type, "ppm"))
+ conv_type = CONVERT_TYPE_PPM;
+ else if (!strcmp(type, "rgb"))
+ conv_type = CONVERT_TYPE_RGB;
+ else if (!strcmp(type, "argb"))
+ conv_type = CONVERT_TYPE_ARGB;
+ else FAILIF(1, "Unknown encoding type %s.\n", type);
+
+ convert(infile, outfile,
+ height, width, gray,
+ conv_type,
+ rotate);
+
+ free(outfile);
+ return 0;
+}