Merge change 1057 into donut
* changes:
* Add regoin scaling for transparent support
diff --git a/api/current.xml b/api/current.xml
index 14faadc..71b5bc2 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -33542,7 +33542,7 @@
</method>
<method name="installPackage"
return="void"
- abstract="true"
+ abstract="false"
native="false"
synchronized="false"
static="false"
@@ -53318,6 +53318,32 @@
<parameter name="path" type="java.lang.String">
</parameter>
</method>
+<method name="createFromFile"
+ return="android.graphics.Typeface"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="path" type="java.io.File">
+</parameter>
+</method>
+<method name="createFromFile"
+ return="android.graphics.Typeface"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="path" type="java.lang.String">
+</parameter>
+</method>
<method name="defaultFromStyle"
return="android.graphics.Typeface"
abstract="false"
@@ -112313,6 +112339,8 @@
</parameter>
<parameter name="flags" type="int">
</parameter>
+<parameter name="installerPackageName" type="java.lang.String">
+</parameter>
</method>
<method name="isSafeMode"
return="boolean"
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 04e69e3..ac62757 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -579,6 +579,7 @@
private void runInstall() {
int installFlags = 0;
+ String installerPackageName = null;
String opt;
while ((opt=nextOption()) != null) {
@@ -586,6 +587,13 @@
installFlags |= PackageManager.FORWARD_LOCK_PACKAGE;
} else if (opt.equals("-r")) {
installFlags |= PackageManager.REPLACE_EXISTING_PACKAGE;
+ } else if (opt.equals("-i")) {
+ installerPackageName = nextOptionData();
+ if (installerPackageName == null) {
+ System.err.println("Error: no value specified for -i");
+ showUsage();
+ return;
+ }
} else {
System.err.println("Error: Unknown option: " + opt);
showUsage();
@@ -603,7 +611,8 @@
PackageInstallObserver obs = new PackageInstallObserver();
try {
- mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags);
+ mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags,
+ installerPackageName);
synchronized (obs) {
while (!obs.finished) {
@@ -812,7 +821,7 @@
System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]");
System.err.println(" pm path PACKAGE");
- System.err.println(" pm install [-l] [-r] PATH");
+ System.err.println(" pm install [-l] [-r] [-i INSTALLER_PACKAGE_NAME] PATH");
System.err.println(" pm uninstall [-k] PACKAGE");
System.err.println(" pm enable PACKAGE_OR_COMPONENT");
System.err.println(" pm disable PACKAGE_OR_COMPONENT");
@@ -840,6 +849,7 @@
System.err.println("The install command installs a package to the system. Use");
System.err.println("the -l option to install the package with FORWARD_LOCK. Use");
System.err.println("the -r option to reinstall an exisiting app, keeping its data.");
+ System.err.println("the -i option to specify the installer package name.");
System.err.println("");
System.err.println("The uninstall command removes a package from the system. Use");
System.err.println("the -k option to keep the data and cache directories around");
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5cb9fe2..1e15d14 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3498,7 +3498,6 @@
if (r != null) {
// keep the original density based on application cale.
appDm.updateDensity(r.getDisplayMetrics().density);
- Log.i("oshima", "Updated app display metrics " + appDm);
r.updateConfiguration(config, appDm);
// reset
appDm.setTo(dm);
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index a1f5a58..bb17dc3 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -2310,15 +2310,26 @@
}
@Override
- public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags) {
+ public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
+ String installerPackageName) {
try {
- mPM.installPackage(packageURI, observer, flags);
+ mPM.installPackage(packageURI, observer, flags, installerPackageName);
} catch (RemoteException e) {
// Should never happen!
}
}
@Override
+ public String getInstallerPackageName(String packageName) {
+ try {
+ return mPM.getInstallerPackageName(packageName);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ return null;
+ }
+
+ @Override
public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
try {
mPM.deletePackage(packageName, observer, flags);
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index d3f6f3c5..c199619 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -139,8 +139,11 @@
* @param observer a callback to use to notify when the package installation in finished.
* @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
* {@link #REPLACE_EXISITING_PACKAGE}
+ * @param installerPackageName Optional package name of the application that is performing the
+ * installation. This identifies which market the package came from.
*/
- void installPackage(in Uri packageURI, IPackageInstallObserver observer, int flags);
+ void installPackage(in Uri packageURI, IPackageInstallObserver observer, int flags,
+ in String installerPackageName);
/**
* Delete a package.
@@ -151,6 +154,8 @@
*/
void deletePackage(in String packageName, IPackageDeleteObserver observer, int flags);
+ String getInstallerPackageName(in String packageName);
+
void addPackageToPreferred(String packageName);
void removePackageFromPreferred(String packageName);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e2f0ce4..3695516 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1354,8 +1354,35 @@
*
* @see #installPackage(android.net.Uri)
*/
+ public void installPackage(
+ Uri packageURI, IPackageInstallObserver observer, int flags) {
+ installPackage(packageURI, observer, flags, null);
+ }
+
+ /**
+ * Install a package. Since this may take a little while, the result will
+ * be posted back to the given observer. An installation will fail if the calling context
+ * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
+ * package named in the package file's manifest is already installed, or if there's no space
+ * available on the device.
+ *
+ * @param packageURI The location of the package file to install. This can be a 'file:' or a
+ * 'content:' URI.
+ * @param observer An observer callback to get notified when the package installation is
+ * complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be
+ * called when that happens. observer may be null to indicate that no callback is desired.
+ * @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
+ * {@link #REPLACE_EXISTING_PACKAGE}
+ * @param installerPackageName Optional package name of the application that is performing the
+ * installation. This identifies which market the package came from.
+ *
+ * @see #installPackage(android.net.Uri)
+ *
+ * @hide
+ */
public abstract void installPackage(
- Uri packageURI, IPackageInstallObserver observer, int flags);
+ Uri packageURI, IPackageInstallObserver observer, int flags,
+ String installerPackageName);
/**
* Attempts to delete a package. Since this may take a little while, the result will
@@ -1374,6 +1401,17 @@
*/
public abstract void deletePackage(
String packageName, IPackageDeleteObserver observer, int flags);
+
+ /**
+ * Retrieve the package name of the application that installed a package. This identifies
+ * which market the package came from.
+ *
+ * @param packageName The name of the package to query
+ *
+ * @hide
+ */
+ public abstract String getInstallerPackageName(String packageName);
+
/**
* Attempts to clear the user data directory of an application.
* Since this may take a little while, the result will
@@ -1483,7 +1521,7 @@
*
* @param packageURI The location of the package file to install
*
- * @see #installPackage(android.net.Uri, IPackageInstallObserver, int)
+ * @see #installPackage(android.net.Uri, IPackageInstallObserver, int, String)
*/
public void installPackage(Uri packageURI) {
installPackage(packageURI, null, 0);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 410adb0..335b43c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4556,6 +4556,7 @@
*
* @hide Pending API council approval
*/
+ @ViewDebug.ExportedProperty
public boolean isOpaque() {
return mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE;
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index ffb6785..4f503b4 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -433,7 +433,9 @@
private InputConnection mDefInputConnection;
private InputConnectionWrapper mPublicInputConnection;
-
+
+ private Runnable mClearScrollingCache;
+
/**
* Interface definition for a callback to be invoked when the list or grid
* has been scrolled.
@@ -1947,7 +1949,7 @@
if (y != mLastY) {
deltaY -= mMotionCorrection;
int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;
- trackMotionScroll(deltaY, incrementalDeltaY, true);
+ trackMotionScroll(deltaY, incrementalDeltaY);
// Check to see if we have bumped into the scroll limit
View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
@@ -2286,7 +2288,7 @@
delta = Math.max(-(getHeight() - mPaddingBottom - mPaddingTop - 1), delta);
}
- trackMotionScroll(delta, delta, false);
+ trackMotionScroll(delta, delta);
// Check to see if we have bumped into the scroll limit
View motionView = getChildAt(mMotionPosition - mFirstPosition);
@@ -2323,16 +2325,23 @@
}
private void clearScrollingCache() {
- if (mCachingStarted) {
- mCachingStarted = false;
- setChildrenDrawnWithCacheEnabled(false);
- if ((mPersistentDrawingCache & PERSISTENT_SCROLLING_CACHE) == 0) {
- setChildrenDrawingCacheEnabled(false);
- }
- if (!isAlwaysDrawnWithCacheEnabled()) {
- invalidate();
- }
+ if (mClearScrollingCache == null) {
+ mClearScrollingCache = new Runnable() {
+ public void run() {
+ if (mCachingStarted) {
+ mCachingStarted = false;
+ setChildrenDrawnWithCacheEnabled(false);
+ if ((mPersistentDrawingCache & PERSISTENT_SCROLLING_CACHE) == 0) {
+ setChildrenDrawingCacheEnabled(false);
+ }
+ if (!isAlwaysDrawnWithCacheEnabled()) {
+ invalidate();
+ }
+ }
+ }
+ };
}
+ post(mClearScrollingCache);
}
/**
@@ -2341,9 +2350,8 @@
* @param deltaY Amount to offset mMotionView. This is the accumulated delta since the motion
* began. Positive numbers mean the user's finger is moving down the screen.
* @param incrementalDeltaY Change in deltaY from the previous event.
- * @param invalidate True to make this method call invalidate(), false otherwise.
*/
- void trackMotionScroll(int deltaY, int incrementalDeltaY, boolean invalidate) {
+ void trackMotionScroll(int deltaY, int incrementalDeltaY) {
final int childCount = getChildCount();
if (childCount == 0) {
return;
@@ -2377,7 +2385,7 @@
if (spaceAbove >= absIncrementalDeltaY && spaceBelow >= absIncrementalDeltaY) {
hideSelector();
offsetChildrenTopAndBottom(incrementalDeltaY);
- if (invalidate) invalidate();
+ invalidate();
mMotionViewNewTop = mMotionViewOriginalTop + deltaY;
} else {
final int firstPosition = mFirstPosition;
@@ -2455,7 +2463,7 @@
mFirstPosition += count;
}
- if (invalidate) invalidate();
+ invalidate();
fillGap(down);
mBlockLayoutRequests = false;
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index c4f0abd..edbb3db 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -823,7 +823,7 @@
@ViewDebug.IntToString(from = RIGHT_OF, to = "rightOf")
}, mapping = {
@ViewDebug.IntToString(from = TRUE, to = "true"),
- @ViewDebug.IntToString(from = 0, to = "NO_ID")
+ @ViewDebug.IntToString(from = 0, to = "FALSE/NO_ID")
})
private int[] mRules = new int[VERB_COUNT];
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index e951431..21dde63 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -133,6 +133,14 @@
return SkTypeface::CreateFromStream(new AssetStream(asset, true));
}
+static SkTypeface* Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) {
+ NPE_CHECK_RETURN_ZERO(env, jpath);
+
+ AutoJavaStringToUTF8 str(env, jpath);
+
+ return SkTypeface::CreateFromFile(str.c_str());
+}
+
///////////////////////////////////////////////////////////////////////////////
static JNINativeMethod gTypefaceMethods[] = {
@@ -140,9 +148,10 @@
{ "nativeCreateFromTypeface", "(II)I", (void*)Typeface_createFromTypeface },
{ "nativeUnref", "(I)V", (void*)Typeface_unref },
{ "nativeGetStyle", "(I)I", (void*)Typeface_getStyle },
- { "nativeCreateFromAsset",
- "(Landroid/content/res/AssetManager;Ljava/lang/String;)I",
- (void*)Typeface_createFromAsset }
+ { "nativeCreateFromAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;)I",
+ (void*)Typeface_createFromAsset },
+ { "nativeCreateFromFile", "(Ljava/lang/String;)I",
+ (void*)Typeface_createFromFile }
};
int register_android_graphics_Typeface(JNIEnv* env);
@@ -153,4 +162,3 @@
gTypefaceMethods,
SK_ARRAY_COUNT(gTypefaceMethods));
}
-
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index b8d6586..42ada54 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -335,7 +335,7 @@
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for start()");
}
-
+
lpTrack->start();
}
@@ -433,6 +433,45 @@
// ----------------------------------------------------------------------------
+jint writeToTrack(AudioTrack* pTrack, jint audioFormat, jbyte* data,
+ jint offsetInBytes, jint sizeInBytes) {
+ // give the data to the native AudioTrack object (the data starts at the offset)
+ ssize_t written = 0;
+ // regular write() or copy the data to the AudioTrack's shared memory?
+ if (pTrack->sharedBuffer() == 0) {
+ written = pTrack->write(data + offsetInBytes, sizeInBytes);
+ } else {
+ if (audioFormat == javaAudioTrackFields.PCM16) {
+ // writing to shared memory, check for capacity
+ if ((size_t)sizeInBytes > pTrack->sharedBuffer()->size()) {
+ sizeInBytes = pTrack->sharedBuffer()->size();
+ }
+ memcpy(pTrack->sharedBuffer()->pointer(), data + offsetInBytes, sizeInBytes);
+ written = sizeInBytes;
+ } else if (audioFormat == javaAudioTrackFields.PCM8) {
+ // data contains 8bit data we need to expand to 16bit before copying
+ // to the shared memory
+ // writing to shared memory, check for capacity,
+ // note that input data will occupy 2X the input space due to 8 to 16bit conversion
+ if (((size_t)sizeInBytes)*2 > pTrack->sharedBuffer()->size()) {
+ sizeInBytes = pTrack->sharedBuffer()->size() / 2;
+ }
+ int count = sizeInBytes;
+ int16_t *dst = (int16_t *)pTrack->sharedBuffer()->pointer();
+ const int8_t *src = (const int8_t *)(data + offsetInBytes);
+ while(count--) {
+ *dst++ = (int16_t)(*src++^0x80) << 8;
+ }
+ // even though we wrote 2*sizeInBytes, we only report sizeInBytes as written to hide
+ // the 8bit mixer restriction from the user of this function
+ written = sizeInBytes;
+ }
+ }
+ return written;
+
+}
+
+// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz,
jbyteArray javaAudioData,
jint offsetInBytes, jint sizeInBytes,
@@ -461,35 +500,13 @@
return 0;
}
- // give the data to the native AudioTrack object (the data starts at the offset)
- ssize_t written = 0;
- // regular write() or copy the data to the AudioTrack's shared memory?
- if (lpTrack->sharedBuffer() == 0) {
- written = lpTrack->write(cAudioData + offsetInBytes, sizeInBytes);
- } else {
- if (javaAudioFormat == javaAudioTrackFields.PCM16) {
- memcpy(lpTrack->sharedBuffer()->pointer(), cAudioData + offsetInBytes, sizeInBytes);
- written = sizeInBytes;
- } else if (javaAudioFormat == javaAudioTrackFields.PCM8) {
- // cAudioData contains 8bit data we need to expand to 16bit before copying
- // to the shared memory
- int count = sizeInBytes;
- int16_t *dst = (int16_t *)lpTrack->sharedBuffer()->pointer();
- const int8_t *src = (const int8_t *)(cAudioData + offsetInBytes);
- while(count--) {
- *dst++ = (int16_t)(*src++^0x80) << 8;
- }
- // even though we wrote 2*sizeInBytes, we only report sizeInBytes as written to hide
- // the 8bit mixer restriction from the user of this function
- written = sizeInBytes;
- }
- }
+ jint written = writeToTrack(lpTrack, javaAudioFormat, cAudioData, offsetInBytes, sizeInBytes);
env->ReleasePrimitiveArrayCritical(javaAudioData, cAudioData, 0);
//LOGV("write wrote %d (tried %d) bytes in the native AudioTrack with offset %d",
// (int)written, (int)(sizeInBytes), (int)offsetInBytes);
- return (int)written;
+ return written;
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index c69c92c..e40e84a 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -18,6 +18,8 @@
import android.content.res.AssetManager;
+import java.io.File;
+
/**
* The Typeface class specifies the typeface and intrinsic style of a font.
* This is used in the paint, along with optionally Paint settings like
@@ -118,7 +120,27 @@
public static Typeface createFromAsset(AssetManager mgr, String path) {
return new Typeface(nativeCreateFromAsset(mgr, path));
}
-
+
+ /**
+ * Create a new typeface from the specified font file.
+ *
+ * @param path The path to the font data.
+ * @return The new typeface.
+ */
+ public static Typeface createFromFile(File path) {
+ return new Typeface(nativeCreateFromFile(path.getAbsolutePath()));
+ }
+
+ /**
+ * Create a new typeface from the specified font file.
+ *
+ * @param path The full path to the font data.
+ * @return The new typeface.
+ */
+ public static Typeface createFromFile(String path) {
+ return new Typeface(nativeCreateFromFile(path));
+ }
+
// don't allow clients to call this directly
private Typeface(int ni) {
native_instance = ni;
@@ -140,14 +162,14 @@
}
protected void finalize() throws Throwable {
+ super.finalize();
nativeUnref(native_instance);
}
private static native int nativeCreate(String familyName, int style);
- private static native int nativeCreateFromTypeface(int native_instance,
- int style);
+ private static native int nativeCreateFromTypeface(int native_instance, int style);
private static native void nativeUnref(int native_instance);
private static native int nativeGetStyle(int native_instance);
- private static native int nativeCreateFromAsset(AssetManager mgr,
- String path);
+ private static native int nativeCreateFromAsset(AssetManager mgr, String path);
+ private static native int nativeCreateFromFile(String path);
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 29f2a00..f8b88d0 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -181,7 +181,8 @@
@Override
public int getOpacity() {
- return mDrawableContainerState.getOpacity();
+ return mCurrDrawable == null || !mCurrDrawable.isVisible() ? PixelFormat.TRANSPARENT :
+ mDrawableContainerState.getOpacity();
}
public boolean selectDrawable(int idx)
@@ -336,13 +337,11 @@
return pos;
}
- public final int getChildCount()
- {
+ public final int getChildCount() {
return mNumChildren;
}
- public final Drawable[] getChildren()
- {
+ public final Drawable[] getChildren() {
return mDrawables;
}
@@ -350,13 +349,11 @@
* all frames in the set (false), or to use the padding value of the frame
* being shown (true). Default value is false.
*/
- public final void setVariablePadding(boolean variable)
- {
+ public final void setVariablePadding(boolean variable) {
mVariablePadding = variable;
}
- public final Rect getConstantPadding()
- {
+ public final Rect getConstantPadding() {
if (mVariablePadding) {
return null;
}
@@ -364,11 +361,12 @@
return mConstantPadding;
}
- Rect r = new Rect(0, 0, 0, 0);
- Rect t = new Rect();
+ final Rect r = new Rect(0, 0, 0, 0);
+ final Rect t = new Rect();
final int N = getChildCount();
- for (int i=0; i<N; i++) {
- if (mDrawables[i].getPadding(t)) {
+ final Drawable[] drawables = mDrawables;
+ for (int i = 0; i < N; i++) {
+ if (drawables[i].getPadding(t)) {
if (t.left > r.left) r.left = t.left;
if (t.top > r.top) r.top = t.top;
if (t.right > r.right) r.right = t.right;
@@ -378,18 +376,15 @@
return (mConstantPadding=r);
}
- public final void setConstantSize(boolean constant)
- {
+ public final void setConstantSize(boolean constant) {
mConstantSize = constant;
}
- public final boolean isConstantSize()
- {
+ public final boolean isConstantSize() {
return mConstantSize;
}
- public final int getConstantWidth()
- {
+ public final int getConstantWidth() {
if (!mComputedConstantSize) {
computeConstantSize();
}
@@ -397,8 +392,7 @@
return mConstantWidth;
}
- public final int getConstantHeight()
- {
+ public final int getConstantHeight() {
if (!mComputedConstantSize) {
computeConstantSize();
}
@@ -406,8 +400,7 @@
return mConstantHeight;
}
- public final int getConstantMinimumWidth()
- {
+ public final int getConstantMinimumWidth() {
if (!mComputedConstantSize) {
computeConstantSize();
}
@@ -415,8 +408,7 @@
return mConstantMinimumWidth;
}
- public final int getConstantMinimumHeight()
- {
+ public final int getConstantMinimumHeight() {
if (!mComputedConstantSize) {
computeConstantSize();
}
@@ -424,15 +416,15 @@
return mConstantMinimumHeight;
}
- private void computeConstantSize()
- {
+ private void computeConstantSize() {
mComputedConstantSize = true;
final int N = getChildCount();
+ final Drawable[] drawables = mDrawables;
mConstantWidth = mConstantHeight = 0;
mConstantMinimumWidth = mConstantMinimumHeight = 0;
- for (int i=0; i<N; i++) {
- Drawable dr = mDrawables[i];
+ for (int i = 0; i < N; i++) {
+ Drawable dr = drawables[i];
int s = dr.getIntrinsicWidth();
if (s > mConstantWidth) mConstantWidth = s;
s = dr.getIntrinsicHeight();
@@ -444,23 +436,22 @@
}
}
- public final int getOpacity()
- {
+ public final int getOpacity() {
if (mHaveOpacity) {
return mOpacity;
}
final int N = getChildCount();
- int op = N > 0
- ? mDrawables[0].getOpacity() : PixelFormat.TRANSPARENT;
- for (int i=1; i<N; i++) {
- op = Drawable.resolveOpacity(op, mDrawables[i].getOpacity());
+ final Drawable[] drawables = mDrawables;
+ int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
+ for (int i = 1; i < N; i++) {
+ op = Drawable.resolveOpacity(op, drawables[i].getOpacity());
}
mOpacity = op;
mHaveOpacity = true;
return op;
}
-
+
public final boolean isStateful() {
if (mHaveStateful) {
return mStateful;
@@ -480,8 +471,7 @@
return stateful;
}
- public void growArray(int oldSize, int newSize)
- {
+ public void growArray(int oldSize, int newSize) {
Drawable[] newDrawables = new Drawable[newSize];
System.arraycopy(mDrawables, 0, newDrawables, 0, oldSize);
mDrawables = newDrawables;
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index aef8985..872838c 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1257,7 +1257,7 @@
}
/**
- * Installs a network location provider.
+ * Installs a location provider.
*
* @param name of the location provider
* @param provider Binder interface for the location provider
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
index 80303f4..b40cdca 100644
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ b/location/java/com/android/internal/location/LocationProviderProxy.java
@@ -21,6 +21,7 @@
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -31,7 +32,7 @@
*
* {@hide}
*/
-public class LocationProviderProxy {
+public class LocationProviderProxy implements IBinder.DeathRecipient {
private static final String TAG = "LocationProviderProxy";
@@ -39,16 +40,27 @@
private final ILocationProvider mProvider;
private boolean mLocationTracking = false;
private long mMinTime = 0;
+ private boolean mDead;
public LocationProviderProxy(String name, ILocationProvider provider) {
mName = name;
mProvider = provider;
+ try {
+ provider.asBinder().linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ Log.e(TAG, "linkToDeath failed", e);
+ mDead = true;
+ }
}
public String getName() {
return mName;
}
+ public boolean isDead() {
+ return mDead;
+ }
+
public boolean requiresNetwork() {
try {
return mProvider.requiresNetwork();
@@ -231,4 +243,9 @@
Log.e(TAG, "removeListener failed", e);
}
}
+
+ public void binderDied() {
+ Log.w(TAG, "Location Provider " + mName + " died");
+ mDead = true;
+ }
}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 14c834b..05888e0 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -215,8 +215,7 @@
public int hashCode() {
return mKey.hashCode();
}
-
-
+
@Override
public String toString() {
if (mListener != null) {
@@ -611,6 +610,17 @@
}
synchronized (mLock) {
+ // check to see if we are reinstalling a dead provider
+ LocationProviderProxy oldProvider = mProvidersByName.get(name);
+ if (oldProvider != null) {
+ if (oldProvider.isDead()) {
+ Log.d(TAG, "replacing dead provider");
+ removeProvider(oldProvider);
+ } else {
+ throw new IllegalArgumentException("Provider \"" + name + "\" already exists");
+ }
+ }
+
LocationProviderProxy proxy = new LocationProviderProxy(name, provider);
addProvider(proxy);
updateProvidersLocked();
@@ -1616,6 +1626,7 @@
mCollector.updateLocation(location);
} catch (RemoteException e) {
Log.w(TAG, "mCollector.updateLocation failed");
+ mCollector = null;
}
}
@@ -1750,6 +1761,7 @@
variant, appName, addrs);
} catch (RemoteException e) {
Log.e(TAG, "getFromLocation failed", e);
+ mGeocodeProvider = null;
}
}
return null;
@@ -1768,6 +1780,7 @@
maxResults, language, country, variant, appName, addrs);
} catch (RemoteException e) {
Log.e(TAG, "getFromLocationName failed", e);
+ mGeocodeProvider = null;
}
}
return null;
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 237b70d..b17a941 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -3231,20 +3231,27 @@
private final String mRootDir;
private final boolean mIsRom;
}
-
+
/* Called when a downloaded package installation has been confirmed by the user */
public void installPackage(
final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
+ installPackage(packageURI, observer, flags, null);
+ }
+
+ /* Called when a downloaded package installation has been confirmed by the user */
+ public void installPackage(
+ final Uri packageURI, final IPackageInstallObserver observer, final int flags,
+ final String installerPackageName) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INSTALL_PACKAGES, null);
-
+
// Queue up an async operation since the package installation may take a little while.
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
PackageInstalledInfo res;
synchronized (mInstallLock) {
- res = installPackageLI(packageURI, flags, true);
+ res = installPackageLI(packageURI, flags, true, installerPackageName);
}
if (observer != null) {
try {
@@ -3292,7 +3299,7 @@
File tmpPackageFile,
String destFilePath, File destPackageFile, File destResourceFile,
PackageParser.Package pkg, boolean forwardLocked, boolean newInstall,
- PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res) {
// Remember this for later, in case we need to rollback this install
boolean dataDirExists = (new File(mAppDataDir, pkgName)).exists();
res.name = pkgName;
@@ -3328,7 +3335,8 @@
destResourceFile, pkg,
newPackage,
true,
- forwardLocked,
+ forwardLocked,
+ installerPackageName,
res);
// delete the partially installed application. the data directory will have to be
// restored if it was already existing
@@ -3349,7 +3357,8 @@
File tmpPackageFile,
String destFilePath, File destPackageFile, File destResourceFile,
PackageParser.Package pkg, boolean forwardLocked, boolean newInstall,
- PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res) {
+
PackageParser.Package oldPackage;
// First find the old package info and check signatures
synchronized(mPackages) {
@@ -3364,11 +3373,11 @@
replaceSystemPackageLI(oldPackage,
tmpPackageFile, destFilePath,
destPackageFile, destResourceFile, pkg, forwardLocked,
- newInstall, res);
+ newInstall, installerPackageName, res);
} else {
replaceNonSystemPackageLI(oldPackage, tmpPackageFile, destFilePath,
destPackageFile, destResourceFile, pkg, forwardLocked,
- newInstall, res);
+ newInstall, installerPackageName, res);
}
}
@@ -3376,11 +3385,17 @@
File tmpPackageFile,
String destFilePath, File destPackageFile, File destResourceFile,
PackageParser.Package pkg, boolean forwardLocked, boolean newInstall,
- PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res) {
PackageParser.Package newPackage = null;
String pkgName = deletedPackage.packageName;
boolean deletedPkg = true;
boolean updatedSettings = false;
+
+ String oldInstallerPackageName = null;
+ synchronized (mPackages) {
+ oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName);
+ }
+
int parseFlags = PackageManager.REPLACE_EXISTING_PACKAGE;
// First delete the existing package while retaining the data directory
if (!deletePackageLI(pkgName, false, PackageManager.DONT_DELETE_DATA,
@@ -3409,6 +3424,7 @@
newPackage,
true,
forwardLocked,
+ installerPackageName,
res);
updatedSettings = true;
}
@@ -3453,7 +3469,7 @@
Uri.fromFile(new File(deletedPackage.mPath)),
isForwardLocked(deletedPackage)
? PackageManager.FORWARD_LOCK_PACKAGE
- : 0, false);
+ : 0, false, oldInstallerPackageName);
}
}
}
@@ -3462,7 +3478,7 @@
File tmpPackageFile,
String destFilePath, File destPackageFile, File destResourceFile,
PackageParser.Package pkg, boolean forwardLocked, boolean newInstall,
- PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res) {
PackageParser.Package newPackage = null;
boolean updatedSettings = false;
int parseFlags = PackageManager.REPLACE_EXISTING_PACKAGE |
@@ -3512,7 +3528,8 @@
destResourceFile, pkg,
newPackage,
true,
- forwardLocked,
+ forwardLocked,
+ installerPackageName,
res);
updatedSettings = true;
}
@@ -3539,6 +3556,8 @@
synchronized(mPackages) {
if(updatedSettings) {
mSettings.enableSystemPackageLP(packageName);
+ mSettings.setInstallerPackageName(packageName,
+ oldPkgSetting.installerPackageName);
}
mSettings.writeLP();
}
@@ -3552,7 +3571,7 @@
PackageParser.Package newPackage,
boolean replacingExistingPackage,
boolean forwardLocked,
- PackageInstalledInfo res) {
+ String installerPackageName, PackageInstalledInfo res) {
synchronized (mPackages) {
//write settings. the installStatus will be incomplete at this stage.
//note that the new package setting would have already been
@@ -3599,6 +3618,7 @@
res.uid = newPackage.applicationInfo.uid;
res.pkg = newPackage;
mSettings.setInstallStatus(pkgName, PKG_INSTALL_COMPLETE);
+ mSettings.setInstallerPackageName(pkgName, installerPackageName);
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
//to update install status
mSettings.writeLP();
@@ -3606,7 +3626,7 @@
}
private PackageInstalledInfo installPackageLI(Uri pPackageURI,
- int pFlags, boolean newInstall) {
+ int pFlags, boolean newInstall, String installerPackageName) {
File tmpPackageFile = null;
String pkgName = null;
boolean forwardLocked = false;
@@ -3719,13 +3739,13 @@
replacePackageLI(pkgName,
tmpPackageFile,
destFilePath, destPackageFile, destResourceFile,
- pkg, forwardLocked, newInstall,
+ pkg, forwardLocked, newInstall, installerPackageName,
res);
} else {
installNewPackageLI(pkgName,
tmpPackageFile,
destFilePath, destPackageFile, destResourceFile,
- pkg, forwardLocked, newInstall,
+ pkg, forwardLocked, newInstall, installerPackageName,
res);
}
} finally {
@@ -4543,6 +4563,16 @@
}
}
+ public String getInstallerPackageName(String packageName) {
+ synchronized (mPackages) {
+ PackageSetting pkg = mSettings.mPackages.get(packageName);
+ if (pkg == null) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ return pkg.installerPackageName;
+ }
+ }
+
public int getApplicationEnabledSetting(String appPackageName) {
synchronized (mPackages) {
PackageSetting pkg = mSettings.mPackages.get(appPackageName);
@@ -5192,6 +5222,9 @@
HashSet<String> enabledComponents = new HashSet<String>(0);
int enabled = COMPONENT_ENABLED_STATE_DEFAULT;
int installStatus = PKG_INSTALL_COMPLETE;
+
+ /* package name of the app that installed this package */
+ String installerPackageName;
PackageSettingBase(String name, File codePath, File resourcePath,
int pVersionCode, int pkgFlags) {
@@ -5204,6 +5237,14 @@
this.versionCode = pVersionCode;
}
+ public void setInstallerPackageName(String packageName) {
+ installerPackageName = packageName;
+ }
+
+ String getInstallerPackageName() {
+ return installerPackageName;
+ }
+
public void setInstallStatus(int newStatus) {
installStatus = newStatus;
}
@@ -5434,6 +5475,19 @@
}
}
+ void setInstallerPackageName(String pkgName,
+ String installerPkgName) {
+ PackageSetting p = mPackages.get(pkgName);
+ if(p != null) {
+ p.setInstallerPackageName(installerPkgName);
+ }
+ }
+
+ String getInstallerPackageName(String pkgName) {
+ PackageSetting p = mPackages.get(pkgName);
+ return (p == null) ? null : p.getInstallerPackageName();
+ }
+
int getInstallStatus(String pkgName) {
PackageSetting p = mPackages.get(pkgName);
if(p != null) {
@@ -5909,6 +5963,9 @@
if(pkg.installStatus == PKG_INSTALL_INCOMPLETE) {
serializer.attribute(null, "installStatus", "false");
}
+ if (pkg.installerPackageName != null) {
+ serializer.attribute(null, "installer", pkg.installerPackageName);
+ }
pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
if ((pkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
serializer.startTag(null, "perms");
@@ -5943,6 +6000,7 @@
}
serializer.endTag(null, "enabled-components");
}
+
serializer.endTag(null, "package");
}
@@ -6264,6 +6322,7 @@
String codePathStr = null;
String resourcePathStr = null;
String systemStr = null;
+ String installerPackageName = null;
int pkgFlags = 0;
String timeStampStr;
long timeStamp = 0;
@@ -6284,6 +6343,7 @@
}
}
systemStr = parser.getAttributeValue(null, "system");
+ installerPackageName = parser.getAttributeValue(null, "installer");
if (systemStr != null) {
if ("true".equals(systemStr)) {
pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
@@ -6357,6 +6417,7 @@
+ parser.getPositionDescription());
}
if (packageSetting != null) {
+ packageSetting.installerPackageName = installerPackageName;
final String enabledStr = parser.getAttributeValue(null, "enabled");
if (enabledStr != null) {
if (enabledStr.equalsIgnoreCase("true")) {
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index ea190e2..4769057 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -286,7 +286,15 @@
@Override
public void installPackage(Uri packageURI, IPackageInstallObserver observer,
- int flags) {
+ int flags, String installerPackageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @hide - to match hiding in superclass
+ */
+ @Override
+ public String getInstallerPackageName(String packageName) {
throw new UnsupportedOperationException();
}