diff options
18 files changed, 355 insertions, 119 deletions
diff --git a/api/current.xml b/api/current.xml index 14faadc7bdf7..71b5bc2eea2c 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 04e69e3022d3..ac6275737ea6 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 @@ public final class Pm { private void runInstall() { int installFlags = 0; + String installerPackageName = null; String opt; while ((opt=nextOption()) != null) { @@ -586,6 +587,13 @@ public final class Pm { 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 @@ public final class Pm { 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 @@ public final class Pm { 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 @@ public final class Pm { 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 5cb9fe23e2b7..1e15d14271d3 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3498,7 +3498,6 @@ public final class ActivityThread { 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 a1f5a58313a0..bb17dc35b4e0 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -2310,15 +2310,26 @@ class ApplicationContext extends Context { } @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 d3f6f3c564c8..c199619c57a9 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -139,8 +139,11 @@ interface IPackageManager { * @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 @@ interface IPackageManager { */ 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 e2f0ce4f4713..3695516aa4f1 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1354,8 +1354,35 @@ public abstract class PackageManager { * * @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 class PackageManager { */ 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 @@ public abstract class PackageManager { * * @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 410adb097845..335b43c7c6e4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4556,6 +4556,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback { * * @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 ffb6785dca27..4f503b488460 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -433,7 +433,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (spaceAbove >= absIncrementalDeltaY && spaceBelow >= absIncrementalDeltaY) { hideSelector(); offsetChildrenTopAndBottom(incrementalDeltaY); - if (invalidate) invalidate(); + invalidate(); mMotionViewNewTop = mMotionViewOriginalTop + deltaY; } else { final int firstPosition = mFirstPosition; @@ -2455,7 +2463,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 c4f0abdd85a6..edbb3db255ab 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -823,7 +823,7 @@ public class RelativeLayout extends ViewGroup { @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 e9514317b8f3..21dde6395286 100644 --- a/core/jni/android/graphics/Typeface.cpp +++ b/core/jni/android/graphics/Typeface.cpp @@ -133,6 +133,14 @@ static SkTypeface* Typeface_createFromAsset(JNIEnv* env, jobject, 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 @@ static JNINativeMethod gTypefaceMethods[] = { { "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 @@ int register_android_graphics_Typeface(JNIEnv* env) gTypefaceMethods, SK_ARRAY_COUNT(gTypefaceMethods)); } - diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index b8d6586d4db2..42ada5450744 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -335,7 +335,7 @@ android_media_AudioTrack_start(JNIEnv *env, jobject thiz) jniThrowException(env, "java/lang/IllegalStateException", "Unable to retrieve AudioTrack pointer for start()"); } - + lpTrack->start(); } @@ -433,6 +433,45 @@ static void android_media_AudioTrack_native_release(JNIEnv *env, jobject thiz) // ---------------------------------------------------------------------------- +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 @@ static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz, 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 c69c92cd76d7..e40e84af1096 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -18,6 +18,8 @@ package android.graphics; 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 class Typeface { 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 @@ public class Typeface { } 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 29f2a0018f17..f8b88d00a8f1 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -181,7 +181,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { @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 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { 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 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { * 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 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { 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 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { 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 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { return mConstantWidth; } - public final int getConstantHeight() - { + public final int getConstantHeight() { if (!mComputedConstantSize) { computeConstantSize(); } @@ -406,8 +400,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { return mConstantHeight; } - public final int getConstantMinimumWidth() - { + public final int getConstantMinimumWidth() { if (!mComputedConstantSize) { computeConstantSize(); } @@ -415,8 +408,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { return mConstantMinimumWidth; } - public final int getConstantMinimumHeight() - { + public final int getConstantMinimumHeight() { if (!mComputedConstantSize) { computeConstantSize(); } @@ -424,15 +416,15 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { 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 class DrawableContainer extends Drawable implements Drawable.Callback { } } - 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 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { 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 aef89850169b..872838c732bd 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -1257,7 +1257,7 @@ public class LocationManager { } /** - * 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 80303f46833a..b40cdcaf212f 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.ILocationProvider; 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 @@ import java.util.List; * * {@hide} */ -public class LocationProviderProxy { +public class LocationProviderProxy implements IBinder.DeathRecipient { private static final String TAG = "LocationProviderProxy"; @@ -39,16 +40,27 @@ public class LocationProviderProxy { 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 @@ public class LocationProviderProxy { 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 14c834b722da..05888e03d4ea 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -215,8 +215,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run public int hashCode() { return mKey.hashCode(); } - - + @Override public String toString() { if (mListener != null) { @@ -611,6 +610,17 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } 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 @@ public class LocationManagerService extends ILocationManager.Stub implements Run mCollector.updateLocation(location); } catch (RemoteException e) { Log.w(TAG, "mCollector.updateLocation failed"); + mCollector = null; } } @@ -1750,6 +1761,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run variant, appName, addrs); } catch (RemoteException e) { Log.e(TAG, "getFromLocation failed", e); + mGeocodeProvider = null; } } return null; @@ -1768,6 +1780,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run 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 237b70d3f448..b17a9411f07b 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -3231,20 +3231,27 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { newPackage, true, forwardLocked, + installerPackageName, res); updatedSettings = true; } @@ -3453,7 +3469,7 @@ class PackageManagerService extends IPackageManager.Stub { Uri.fromFile(new File(deletedPackage.mPath)), isForwardLocked(deletedPackage) ? PackageManager.FORWARD_LOCK_PACKAGE - : 0, false); + : 0, false, oldInstallerPackageName); } } } @@ -3462,7 +3478,7 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { destResourceFile, pkg, newPackage, true, - forwardLocked, + forwardLocked, + installerPackageName, res); updatedSettings = true; } @@ -3539,6 +3556,8 @@ class PackageManagerService extends IPackageManager.Stub { synchronized(mPackages) { if(updatedSettings) { mSettings.enableSystemPackageLP(packageName); + mSettings.setInstallerPackageName(packageName, + oldPkgSetting.installerPackageName); } mSettings.writeLP(); } @@ -3552,7 +3571,7 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { } 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { } } + 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { } } + 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 @@ class PackageManagerService extends IPackageManager.Stub { 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 @@ class PackageManagerService extends IPackageManager.Stub { } serializer.endTag(null, "enabled-components"); } + serializer.endTag(null, "package"); } @@ -6264,6 +6322,7 @@ class PackageManagerService extends IPackageManager.Stub { String codePathStr = null; String resourcePathStr = null; String systemStr = null; + String installerPackageName = null; int pkgFlags = 0; String timeStampStr; long timeStamp = 0; @@ -6284,6 +6343,7 @@ class PackageManagerService extends IPackageManager.Stub { } } 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 @@ class PackageManagerService extends IPackageManager.Stub { + 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 ea190e237144..4769057d89be 100644 --- a/test-runner/android/test/mock/MockPackageManager.java +++ b/test-runner/android/test/mock/MockPackageManager.java @@ -286,7 +286,15 @@ public class MockPackageManager extends PackageManager { @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(); } |