Merge change 9330 into donut
* changes:
Fix #2025900. If a https request is canceled while openConnection is called and a ssl error happened, the http thread can be blocked for up to 10 min. Added code to detect this case and unlock the thread.
diff --git a/cmds/keystore/netkeystore.c b/cmds/keystore/netkeystore.c
index eac455e..637e0d8 100644
--- a/cmds/keystore/netkeystore.c
+++ b/cmds/keystore/netkeystore.c
@@ -37,6 +37,7 @@
#include "netkeystore.h"
#include "keymgmt.h"
+#define DBG 1
#define CMD_PUT_WITH_FILE "putfile"
typedef void CMD_FUNC(LPC_MARSHAL *cmd, LPC_MARSHAL *reply);
@@ -397,12 +398,12 @@
// read the command, execute and send the result back.
if(read_marshal(s, &cmd)) goto err;
- LOGI("new connection\n");
+ if (DBG) LOGD("new connection\n");
execute(&cmd, &reply);
write_marshal(s, &reply);
err:
memset(&reply, 0, sizeof(LPC_MARSHAL));
- LOGI("closing connection\n");
+ if (DBG) LOGD("closing connection\n");
close(s);
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 6a9bcfb..b8f0a7e 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -463,6 +463,7 @@
if (matrix == null && !mMatrix.isIdentity() ||
matrix != null && !mMatrix.equals(matrix)) {
mMatrix.set(matrix);
+ configureBounds();
invalidate();
}
}
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
new file mode 100644
index 0000000..9af0918
--- /dev/null
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -0,0 +1,79 @@
+page.title=Android API Levels
+@jd:body
+
+
+<p>The Android <em>API Level</em> is an integer that indicates a set of APIs available in an Android SDK
+and on a version of the Android platform. Each version of the Android platform supports a specific set
+of APIs, which are always backward-compatible. For example, Android 1.5 supports all APIs available in
+Android 1.0, but the reverse is not true. If an application uses APIs
+available in Android 1.5 that are not available in 1.0, then the application should never be installed
+on an Android 1.0 device, because it will fail due to missing APIs. The API Level ensures this does not happen
+by comparing the minimum API Level required by the applicaiton to the API Level available on the device.</p>
+
+<p>When a new version of Android adds APIs, a new API Level is added to the platform. The new APIs
+are available only to applications that declare a minimum API Level that is equal-to or greater-than
+the API Level in which the APIs were introduced. The API Level required by an application is declared with the
+<code><uses-sdk></code> element inside the Android manifest, like this:</p>
+
+<pre><uses-sdk android:minSdkVersion="3" /></pre>
+
+<p>The value for <code>minSdkVersion</code> is the minimum API Level required by the application.
+If this is not declared, then it is assumed that the application is compatible with all versions and defaults to
+API Level 1. In which case, if the application actually uses APIs introduced with an API Level greater than 1, then
+the application will fail in unpredictable ways when installed on a device that only supports API Level 1
+(such as an Android 1.0 device).
+See the <code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><uses-sdk></a></code>
+documentation for more about declaring the API Level in your manifest.</p>
+
+<p>For example, the {@link android.appwidget} package was introduced with API Level 3. If your application
+has set <code>minSdkVersion</code> to 1 or 2, then your application cannot use this package,
+even if the device running your application uses a version of Android that supports it.
+In order to use the {@link android.appwidget} package, your application must set <code>minSdkVersion</code>
+to 3 or higher. When the <code>minSdkVersion</code> is set to 3, the application will no longer be able to install
+on a device running a platform version with an API Level less than 3.</p>
+
+<p>Despite the name of the manifest attribute (<code>minSdkVersion</code>), the API Level is not directly
+associated with a specific SDK. For example, the SDK for Android 1.0 uses
+API Level 1 and the SDK for Android 1.1 uses API Level 2. So it may seem that the API Level increases consistently.
+However, it's possible that a subsequent platform
+releases will not introduce new APIs, and thus, the API Level will remain the same. In addition, there are often
+multiple SDK releases for a single platform version (there were three SDK releases for Android 1.5), and
+there's no guarantee that the API Level will remain the same between these. It's possible (but unlikely) that
+a second or third SDK for a given version of the platform will provide new APIs and add a new API Level.
+When you install a new SDK, be sure to read the SDK Contents on the install page, which specifies the API
+Level for each platform available in the SDK. Also see the comparison of
+<a href="#VersionsVsApiLevels">Platform Versions vs. API Levels</a>, below.</p>
+
+<p class="note"><strong>Note:</strong> During "preview" SDK releases, there may not yet be an official platform version
+or API Level number specified. In these cases, a string value equal to the
+current codename will be a valid value for <code>minSdkVersion</code>, instead of an integer. This codename value
+will only be valid while using the preview SDK. When the final SDK is released, you must update your manifest to use
+the official API Level integer.</p>
+
+<h2 id="VersionsVsApiLevels">Platform Versions vs. API Levels</h2>
+
+<p>The following table specifies the <em>maximum</em> API Level supported by each version of the Android platform.</p>
+
+<table>
+ <tr><th>Platform Version</th><th>API Level</th></tr>
+ <tr><td>Android 1.0</td><td>1</td></tr>
+ <tr><td>Android 1.1</td><td>2</td></tr>
+ <tr><td>Android 1.5</td><td>3</td></tr>
+ <tr><td>Android Donut</td><td>Donut</td></tr>
+</table>
+
+
+<h2 id="ViewingTheApiReference">Viewing the API Reference Based on API Level</h2>
+
+<p>The Android API reference includes information that specififies the minimum API Level required for each
+package, class, and member. You can see this information on the right side of each header or label.</p>
+
+<p>By default, the reference documentation shows all APIs available with the latest SDK release.
+This means that the reference assumes you're using the latest API Level and will show you everything available
+with it. If you're developing applications for a version of Android that does not support the latest API Level,
+then you can filter the reference to reveal only the packages, classes, and members available for that API Level.
+When viewing the reference, use the "Filter by API Level" selection box (below the search bar) to pick the API Level
+you'd like to view.</p>
+
+
+
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
index b1b78ea..989432a 100644
--- a/keystore/java/android/security/CertTool.java
+++ b/keystore/java/android/security/CertTool.java
@@ -209,6 +209,10 @@
}
freeX509Certificate(handle);
}
- if (intent != null) context.startActivity(intent);
+ if (intent != null) {
+ context.startActivity(intent);
+ } else {
+ Log.w("CertTool", "incorrect data for addCertificate()");
+ }
}
}
diff --git a/keystore/java/android/security/ServiceCommand.java b/keystore/java/android/security/ServiceCommand.java
index 6178d59..dddf654 100644
--- a/keystore/java/android/security/ServiceCommand.java
+++ b/keystore/java/android/security/ServiceCommand.java
@@ -49,6 +49,8 @@
public static final int BUFFER_LENGTH = 4096;
+ private static final boolean DBG = true;
+
private String mServiceName;
private String mTag;
private InputStream mIn;
@@ -59,7 +61,7 @@
if (mSocket != null) {
return true;
}
- Log.i(mTag, "connecting...");
+ if (DBG) Log.d(mTag, "connecting...");
try {
mSocket = new LocalSocket();
@@ -78,7 +80,7 @@
}
private void disconnect() {
- Log.i(mTag,"disconnecting...");
+ if (DBG) Log.d(mTag,"disconnecting...");
try {
if (mSocket != null) mSocket.close();
} catch (IOException ex) { }
@@ -105,7 +107,7 @@
}
off += count;
} catch (IOException ex) {
- Log.e(mTag,"read exception");
+ Log.e(mTag,"read exception", ex);
break;
}
}
@@ -156,7 +158,7 @@
mOut.write(buf, 0, 8);
mOut.write(data, 0, len);
} catch (IOException ex) {
- Log.e(mTag,"write error");
+ Log.e(mTag,"write error", ex);
disconnect();
return false;
}
diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java
index 4fb0ead..d75d81d 100644
--- a/media/java/android/media/JetPlayer.java
+++ b/media/java/android/media/JetPlayer.java
@@ -183,6 +183,7 @@
*/
public void release() {
native_release();
+ singletonRef = null;
}
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 1fdecdd..00a121b 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -93,7 +93,7 @@
void SoundPool::addToRestartList(SoundChannel* channel)
{
- Mutex::Autolock lock(&mLock);
+ Mutex::Autolock lock(&mRestartLock);
mRestart.push_back(channel);
mCondition.signal();
}
@@ -106,9 +106,9 @@
int SoundPool::run()
{
- mLock.lock();
+ mRestartLock.lock();
while (!mQuit) {
- mCondition.wait(mLock);
+ mCondition.wait(mRestartLock);
LOGV("awake");
if (mQuit) break;
@@ -125,19 +125,19 @@
mRestart.clear();
mCondition.signal();
- mLock.unlock();
+ mRestartLock.unlock();
LOGV("goodbye");
return 0;
}
void SoundPool::quit()
{
- mLock.lock();
+ mRestartLock.lock();
mQuit = true;
mCondition.signal();
- mCondition.wait(mLock);
+ mCondition.wait(mRestartLock);
LOGV("return from quit");
- mLock.unlock();
+ mRestartLock.unlock();
}
bool SoundPool::startThreads()
@@ -484,11 +484,8 @@
// if not idle, this voice is being stolen
if (mState != IDLE) {
LOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID);
- stop_l();
mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate);
-#ifdef USE_SHARED_MEM_BUFFER
- mSoundPool->done(this);
-#endif
+ stop();
return;
}
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index 7802781..ab86e90 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -204,6 +204,7 @@
jobject mSoundPoolRef;
Mutex mLock;
+ Mutex mRestartLock;
Condition mCondition;
SoundPoolThread* mDecodeThread;
SoundChannel* mChannelPool;
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
index b107c7d..f410c7b 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
@@ -147,8 +147,7 @@
synchronized boolean onConnect(String username, String password) {
try {
- mState = VpnState.CONNECTING;
- broadcastConnectivity(VpnState.CONNECTING);
+ setState(VpnState.CONNECTING);
stopPreviouslyRunDaemons();
String serverIp = getIp(getProfile().getServerName());
@@ -166,8 +165,7 @@
synchronized void onDisconnect() {
try {
Log.i(TAG, "disconnecting VPN...");
- mState = VpnState.DISCONNECTING;
- broadcastConnectivity(VpnState.DISCONNECTING);
+ setState(VpnState.DISCONNECTING);
mNotification.showDisconnect();
mDaemonHelper.stopAll();
@@ -235,14 +233,13 @@
saveOriginalDns();
saveAndSetDomainSuffices();
- mState = VpnState.CONNECTED;
mStartTime = System.currentTimeMillis();
// set DNS after saving the states in case the process gets killed
// before states are saved
saveSelf();
setVpnDns();
- broadcastConnectivity(VpnState.CONNECTED);
+ setState(VpnState.CONNECTED);
enterConnectivityLoop();
}
@@ -261,10 +258,10 @@
restoreOriginalDns();
restoreOriginalDomainSuffices();
- mState = VpnState.IDLE;
- broadcastConnectivity(VpnState.IDLE);
+ setState(VpnState.IDLE);
// stop the service itself
+ SystemProperties.set(VPN_STATUS, VPN_IS_DOWN);
mContext.removeStates();
mContext.stopSelf();
}
@@ -316,6 +313,11 @@
SystemProperties.set(DNS_DOMAIN_SUFFICES, mOriginalDomainSuffices);
}
+ private void setState(VpnState newState) {
+ mState = newState;
+ broadcastConnectivity(newState);
+ }
+
private void broadcastConnectivity(VpnState s) {
VpnManager m = new VpnManager(mContext);
Throwable err = mError;
@@ -326,6 +328,9 @@
} else if (err instanceof VpnConnectingError) {
m.broadcastConnectivity(mProfile.getName(), s,
((VpnConnectingError) err).getErrorCode());
+ } else if (VPN_IS_UP.equals(SystemProperties.get(VPN_STATUS))) {
+ m.broadcastConnectivity(mProfile.getName(), s,
+ VpnManager.VPN_ERROR_CONNECTION_LOST);
} else {
m.broadcastConnectivity(mProfile.getName(), s,
VpnManager.VPN_ERROR_CONNECTION_FAILED);
@@ -373,7 +378,7 @@
// returns false if vpn connectivity is broken
private boolean checkConnectivity() {
if (mDaemonHelper.anyDaemonStopped() || isLocalIpChanged()) {
- onDisconnect();
+ onError(new IOException("Connectivity lost"));
return false;
} else {
return true;
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index e448e5a..f71bbea 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -54,6 +54,8 @@
public static final int VPN_ERROR_CHALLENGE = 4;
/** Error code to indicate an error of remote server hanging up. */
public static final int VPN_ERROR_REMOTE_HUNG_UP = 5;
+ /** Error code to indicate an error of losing connectivity. */
+ public static final int VPN_ERROR_CONNECTION_LOST = 6;
private static final int VPN_ERROR_NO_ERROR = 0;
public static final String PROFILES_PATH = "/data/misc/vpn/profiles";