Merge change 25291 into eclair
* changes:
Try to fix sdk build again.
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index 8f7e8ca..4f9531e 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -20,14 +20,15 @@
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.ContentResolver.OpenResourceIdResult;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.DrawableContainer;
import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.os.Bundle;
@@ -38,14 +39,15 @@
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Filter;
import android.widget.ImageView;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView;
-import android.widget.Filter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
import java.util.WeakHashMap;
/**
@@ -580,14 +582,26 @@
// Not cached, try using it as a plain resource ID in the provider's context.
int resourceId = Integer.parseInt(drawableId);
drawable = mProviderContext.getResources().getDrawable(resourceId);
- if (DBG) Log.d(LOG_TAG, "Found icon by resource ID: " + drawableId);
} catch (NumberFormatException nfe) {
- // The id was not an integer resource id.
- // Let the ContentResolver handle content, android.resource and file URIs.
+ // The id was not an integer resource id, use it as a URI
try {
Uri uri = Uri.parse(drawableId);
- InputStream stream = mProviderContext.getContentResolver().openInputStream(uri);
- if (stream != null) {
+ String scheme = uri.getScheme();
+ if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
+ // Load drawables through Resources, to get the source density information
+ OpenResourceIdResult r =
+ mProviderContext.getContentResolver().getResourceId(uri);
+ try {
+ drawable = r.r.getDrawable(r.id);
+ } catch (Resources.NotFoundException ex) {
+ throw new FileNotFoundException("Resource does not exist: " + uri);
+ }
+ } else {
+ // Let the ContentResolver handle content and file URIs.
+ InputStream stream = mProviderContext.getContentResolver().openInputStream(uri);
+ if (stream == null) {
+ throw new FileNotFoundException("Failed to open " + uri);
+ }
try {
drawable = Drawable.createFromStream(stream, null);
} finally {
@@ -598,22 +612,25 @@
}
}
}
- if (DBG) Log.d(LOG_TAG, "Opened icon input stream: " + drawableId);
} catch (FileNotFoundException fnfe) {
- if (DBG) Log.d(LOG_TAG, "Icon stream not found: " + drawableId);
+ Log.w(LOG_TAG, "Icon not found: " + drawableId + ", " + fnfe.getMessage());
// drawable = null;
}
-
- // If we got a drawable for this resource id, then stick it in the
- // map so we don't do this lookup again.
- if (drawable != null) {
- mOutsideDrawablesCache.put(drawableId, drawable.getConstantState());
- }
} catch (Resources.NotFoundException nfe) {
- if (DBG) Log.d(LOG_TAG, "Icon resource not found: " + drawableId);
+ Log.w(LOG_TAG, "Icon resource not found: " + drawableId);
// drawable = null;
}
+ if (drawable == null) {
+ if (DBG) Log.d(LOG_TAG, "Didn't find icon: " + drawableId);
+ } else {
+ if (DBG) {
+ Log.d(LOG_TAG, "Found icon: " + drawableId);
+ }
+ // Cache it so we don't do this lookup again
+ mOutsideDrawablesCache.put(drawableId, drawable.getConstantState());
+ }
+
return drawable;
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 88a4d02f..307899a 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -527,12 +527,22 @@
}
}
- class OpenResourceIdResult {
- Resources r;
- int id;
+ /**
+ * A resource identified by the {@link Resources} that contains it, and a resource id.
+ *
+ * @hide
+ */
+ public class OpenResourceIdResult {
+ public Resources r;
+ public int id;
}
-
- OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException {
+
+ /**
+ * Resolves an android.resource URI to a {@link Resources} and a resource id.
+ *
+ * @hide
+ */
+ public OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException {
String authority = uri.getAuthority();
Resources r;
if (TextUtils.isEmpty(authority)) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 081f67a..4ca17ac 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4791,8 +4791,11 @@
mMaxZoomScale = restoreState.mMaxScale;
}
setNewZoomScale(mLastScale, false);
- setContentScrollTo(restoreState.mScrollX,
- restoreState.mScrollY);
+ if (getVisibleTitleHeight() == 0
+ || restoreState.mScrollY != 0) {
+ setContentScrollTo(restoreState.mScrollX,
+ restoreState.mScrollY);
+ }
if (useWideViewport
&& settings.getLoadWithOverviewMode()) {
if (restoreState.mViewScale == 0
diff --git a/include/media/stagefright/SoftwareRenderer.h b/include/media/stagefright/SoftwareRenderer.h
index b61858c..1545493 100644
--- a/include/media/stagefright/SoftwareRenderer.h
+++ b/include/media/stagefright/SoftwareRenderer.h
@@ -45,6 +45,7 @@
void renderCbYCrY(const void *data, size_t size);
void renderYUV420Planar(const void *data, size_t size);
+ void renderQCOMYUV420SemiPlanar(const void *data, size_t size);
OMX_COLOR_FORMATTYPE mColorFormat;
sp<ISurface> mISurface;
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1dd644b..d6463a1 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -345,6 +345,9 @@
/**
* Adjusts the volume of a particular stream by one step in a direction.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
*
* @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
* {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC} or
@@ -370,6 +373,9 @@
* active, it will have the highest priority regardless of if the in-call
* screen is showing. Another example, if music is playing in the background
* and a call is not active, the music stream will be adjusted.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
*
* @param direction The direction to adjust the volume. One of
* {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
@@ -391,6 +397,9 @@
/**
* Adjusts the volume of the most relevant stream, or the given fallback
* stream.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
*
* @param direction The direction to adjust the volume. One of
* {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
@@ -541,6 +550,9 @@
* <p>
* For a better user experience, applications MUST unmute a muted stream
* in onPause() and mute is again in onResume() if appropriate.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
*
* @param streamType The stream to be muted/unmuted.
* @param state The required mute state: true for mute ON, false for mute OFF
@@ -608,6 +620,9 @@
/**
* Sets the setting for when the vibrate type should vibrate.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
*
* @param vibrateType The type of vibrate. One of
* {@link #VIBRATE_TYPE_NOTIFICATION} or
@@ -630,6 +645,9 @@
/**
* Sets the speakerphone on or off.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
*
* @param on set <var>true</var> to turn on speakerphone;
* <var>false</var> to turn it off
@@ -660,6 +678,9 @@
/**
* Request use of Bluetooth SCO headset for communications.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
*
* @param on set <var>true</var> to use bluetooth SCO for communications;
* <var>false</var> to not use bluetooth SCO for communications
@@ -739,6 +760,9 @@
/**
* Sets the microphone mute on or off.
+ * <p>
+ * This method should only be used by applications that replace the platform-wide
+ * management of audio settings or the main telephony application.
*
* @param on set <var>true</var> to mute the microphone;
* <var>false</var> to turn mute off
@@ -758,6 +782,13 @@
/**
* Sets the audio mode.
+ * <p>
+ * The audio mode encompasses audio routing AND the behavior of
+ * the telephony layer. Therefore this method should only be used by applications that
+ * replace the platform-wide management of audio settings or the main telephony application.
+ * In particular, the {@link #MODE_IN_CALL} mode should only be used by the telephony
+ * application when it places a phone call, as it will cause signals from the radio layer
+ * to feed the platform mixer.
*
* @param mode the requested audio mode (NORMAL, RINGTONE, or IN_CALL).
* Informs the HAL about the current audio state so that
diff --git a/media/libstagefright/omx/SoftwareRenderer.cpp b/media/libstagefright/omx/SoftwareRenderer.cpp
index a1c478f..4ed6869 100644
--- a/media/libstagefright/omx/SoftwareRenderer.cpp
+++ b/media/libstagefright/omx/SoftwareRenderer.cpp
@@ -65,6 +65,8 @@
void SoftwareRenderer::render(
const void *data, size_t size, void *platformPrivate) {
+ static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00;
+
switch (mColorFormat) {
case OMX_COLOR_FormatYUV420Planar:
return renderYUV420Planar(data, size);
@@ -72,6 +74,9 @@
case OMX_COLOR_FormatCbYCrY:
return renderCbYCrY(data, size);
+ case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
+ return renderQCOMYUV420SemiPlanar(data, size);
+
default:
{
LOGW("Cannot render color format %ld", mColorFormat);
@@ -242,6 +247,76 @@
mIndex = 1 - mIndex;
}
+void SoftwareRenderer::renderQCOMYUV420SemiPlanar(
+ const void *data, size_t size) {
+ if (size != (mDecodedHeight * mDecodedWidth * 3) / 2) {
+ LOGE("size is %d, expected %d",
+ size, (mDecodedHeight * mDecodedWidth * 3) / 2);
+ }
+ CHECK(size >= (mDecodedWidth * mDecodedHeight * 3) / 2);
+
+ uint8_t *kAdjustedClip = initClip();
+
+ size_t offset = mIndex * mFrameSize;
+
+ void *dst = (uint8_t *)mMemoryHeap->getBase() + offset;
+
+ uint32_t *dst_ptr = (uint32_t *)dst;
+
+ const uint8_t *src_y = (const uint8_t *)data;
+
+ const uint8_t *src_u =
+ (const uint8_t *)src_y + mDecodedWidth * mDecodedHeight;
+
+ for (size_t y = 0; y < mDecodedHeight; ++y) {
+ for (size_t x = 0; x < mDecodedWidth; x += 2) {
+ signed y1 = (signed)src_y[x] - 16;
+ signed y2 = (signed)src_y[x + 1] - 16;
+
+ signed u = (signed)src_u[x & ~1] - 128;
+ signed v = (signed)src_u[(x & ~1) + 1] - 128;
+
+ signed u_b = u * 517;
+ signed u_g = -u * 100;
+ signed v_g = -v * 208;
+ signed v_r = v * 409;
+
+ signed tmp1 = y1 * 298;
+ signed b1 = (tmp1 + u_b) / 256;
+ signed g1 = (tmp1 + v_g + u_g) / 256;
+ signed r1 = (tmp1 + v_r) / 256;
+
+ signed tmp2 = y2 * 298;
+ signed b2 = (tmp2 + u_b) / 256;
+ signed g2 = (tmp2 + v_g + u_g) / 256;
+ signed r2 = (tmp2 + v_r) / 256;
+
+ uint32_t rgb1 =
+ ((kAdjustedClip[b1] >> 3) << 11)
+ | ((kAdjustedClip[g1] >> 2) << 5)
+ | (kAdjustedClip[r1] >> 3);
+
+ uint32_t rgb2 =
+ ((kAdjustedClip[b2] >> 3) << 11)
+ | ((kAdjustedClip[g2] >> 2) << 5)
+ | (kAdjustedClip[r2] >> 3);
+
+ dst_ptr[x / 2] = (rgb2 << 16) | rgb1;
+ }
+
+ src_y += mDecodedWidth;
+
+ if (y & 1) {
+ src_u += mDecodedWidth;
+ }
+
+ dst_ptr += mDecodedWidth / 2;
+ }
+
+ mISurface->postBuffer(offset);
+ mIndex = 1 - mIndex;
+}
+
uint8_t *SoftwareRenderer::initClip() {
static const signed kClipMin = -278;
static const signed kClipMax = 535;
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 82cf1bc..45e0ceb 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -3611,9 +3611,18 @@
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
- PackageInstalledInfo res;
- synchronized (mInstallLock) {
- res = installPackageLI(packageURI, flags, true, installerPackageName);
+ // Result object to be returned
+ PackageInstalledInfo res = new PackageInstalledInfo();
+ res.returnCode = PackageManager.INSTALL_SUCCEEDED;
+ res.uid = -1;
+ res.pkg = null;
+ res.removedInfo = new PackageRemovedInfo();
+ // Make a temporary copy of file from given packageURI
+ File tmpPackageFile = copyTempInstallFile(packageURI, res);
+ if (tmpPackageFile != null) {
+ synchronized (mInstallLock) {
+ installPackageLI(packageURI, flags, true, installerPackageName, tmpPackageFile, res);
+ }
}
if (observer != null) {
try {
@@ -3828,11 +3837,30 @@
// Since we failed to install the new package we need to restore the old
// package that we deleted.
if(deletedPkg) {
+ File restoreFile = new File(deletedPackage.mPath);
+ if (restoreFile == null) {
+ Log.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName);
+ return;
+ }
+ File restoreTmpFile = createTempPackageFile();
+ if (restoreTmpFile == null) {
+ Log.e(TAG, "Failed creating temp file when restoring pkg : " + pkgName);
+ return;
+ }
+ if (!FileUtils.copyFile(restoreFile, restoreTmpFile)) {
+ Log.e(TAG, "Failed copying temp file when restoring pkg : " + pkgName);
+ return;
+ }
+ PackageInstalledInfo restoreRes = new PackageInstalledInfo();
+ restoreRes.removedInfo = new PackageRemovedInfo();
installPackageLI(
- Uri.fromFile(new File(deletedPackage.mPath)),
+ Uri.fromFile(restoreFile),
isForwardLocked(deletedPackage)
? PackageManager.INSTALL_FORWARD_LOCK
- : 0, false, oldInstallerPackageName);
+ : 0, false, oldInstallerPackageName, restoreTmpFile, restoreRes);
+ if (restoreRes.returnCode != PackageManager.INSTALL_SUCCEEDED) {
+ Log.e(TAG, "Failed restoring pkg : " + pkgName + " after failed upgrade");
+ }
}
}
}
@@ -3995,50 +4023,36 @@
return new File(mAppInstallDir, publicZipFileName);
}
- private PackageInstalledInfo installPackageLI(Uri pPackageURI,
- int pFlags, boolean newInstall, String installerPackageName) {
- File tmpPackageFile = null;
- String pkgName = null;
- boolean forwardLocked = false;
- boolean replacingExistingPackage = false;
- // Result object to be returned
- PackageInstalledInfo res = new PackageInstalledInfo();
- res.returnCode = PackageManager.INSTALL_SUCCEEDED;
- res.uid = -1;
- res.pkg = null;
- res.removedInfo = new PackageRemovedInfo();
+ private File copyTempInstallFile(Uri pPackageURI,
+ PackageInstalledInfo res) {
+ File tmpPackageFile = createTempPackageFile();
+ int retCode = PackageManager.INSTALL_SUCCEEDED;
+ if (tmpPackageFile == null) {
+ res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ return null;
+ }
- main_flow: try {
- tmpPackageFile = createTempPackageFile();
- if (tmpPackageFile == null) {
- res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- break main_flow;
+ if (pPackageURI.getScheme().equals("file")) {
+ final File srcPackageFile = new File(pPackageURI.getPath());
+ // We copy the source package file to a temp file and then rename it to the
+ // destination file in order to eliminate a window where the package directory
+ // scanner notices the new package file but it's not completely copied yet.
+ if (!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
+ Log.e(TAG, "Couldn't copy package file to temp file.");
+ retCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}
- tmpPackageFile.deleteOnExit(); // paranoia
- if (pPackageURI.getScheme().equals("file")) {
- final File srcPackageFile = new File(pPackageURI.getPath());
- // We copy the source package file to a temp file and then rename it to the
- // destination file in order to eliminate a window where the package directory
- // scanner notices the new package file but it's not completely copied yet.
- if (!FileUtils.copyFile(srcPackageFile, tmpPackageFile)) {
- Log.e(TAG, "Couldn't copy package file to temp file.");
- res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- break main_flow;
- }
- } else if (pPackageURI.getScheme().equals("content")) {
- ParcelFileDescriptor fd;
- try {
- fd = mContext.getContentResolver().openFileDescriptor(pPackageURI, "r");
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Couldn't open file descriptor from download service.");
- res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- break main_flow;
- }
- if (fd == null) {
- Log.e(TAG, "Couldn't open file descriptor from download service (null).");
- res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- break main_flow;
- }
+ } else if (pPackageURI.getScheme().equals("content")) {
+ ParcelFileDescriptor fd = null;
+ try {
+ fd = mContext.getContentResolver().openFileDescriptor(pPackageURI, "r");
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Couldn't open file descriptor from download service. Failed with exception " + e);
+ retCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ }
+ if (fd == null) {
+ Log.e(TAG, "Couldn't open file descriptor from download service (null).");
+ retCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ } else {
if (Config.LOGV) {
Log.v(TAG, "Opened file descriptor from download service.");
}
@@ -4049,14 +4063,34 @@
// scanner notices the new package file but it's not completely copied yet.
if (!FileUtils.copyToFile(dlStream, tmpPackageFile)) {
Log.e(TAG, "Couldn't copy package stream to temp file.");
- res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- break main_flow;
+ retCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}
- } else {
- Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
- res.returnCode = PackageManager.INSTALL_FAILED_INVALID_URI;
- break main_flow;
}
+ } else {
+ Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
+ retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
+ }
+
+ res.returnCode = retCode;
+ if (retCode != PackageManager.INSTALL_SUCCEEDED) {
+ if (tmpPackageFile != null && tmpPackageFile.exists()) {
+ tmpPackageFile.delete();
+ }
+ return null;
+ }
+ return tmpPackageFile;
+ }
+
+ private void installPackageLI(Uri pPackageURI,
+ int pFlags, boolean newInstall, String installerPackageName,
+ File tmpPackageFile, PackageInstalledInfo res) {
+ String pkgName = null;
+ boolean forwardLocked = false;
+ boolean replacingExistingPackage = false;
+ // Result object to be returned
+ res.returnCode = PackageManager.INSTALL_SUCCEEDED;
+
+ main_flow: try {
pkgName = PackageParser.parsePackageName(
tmpPackageFile.getAbsolutePath(), 0);
if (pkgName == null) {
@@ -4128,7 +4162,6 @@
tmpPackageFile.delete();
}
}
- return res;
}
private int setPermissionsLI(String pkgName,