diff options
Diffstat (limited to 'core/java')
23 files changed, 379 insertions, 96 deletions
| diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 2fc476e..1e15d14 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -191,16 +191,11 @@ public final class ActivityThread {                  usePreloaded = false;                  DisplayMetrics newMetrics = new DisplayMetrics();                  newMetrics.setTo(metrics); -                float invertedScale = 1.0f / applicationScale; -                newMetrics.density *= invertedScale; -                newMetrics.xdpi *= invertedScale; -                newMetrics.ydpi *= invertedScale; -                newMetrics.widthPixels *= invertedScale; -                newMetrics.heightPixels *= invertedScale; +                float newDensity = metrics.density / applicationScale; +                newMetrics.updateDensity(newDensity);                  metrics = newMetrics;              } -            //Log.i(TAG, "Resource:" + appDir + ", density " + newMetrics.density + ", orig density:" + -            //      metrics.density); +            //Log.i(TAG, "Resource:" + appDir + ", display metrics=" + metrics);              r = new Resources(assets, metrics, getConfiguration(), usePreloaded);              //Log.i(TAG, "Created app resources " + r + ": " + r.getConfiguration());              // XXX need to remove entries when weak references go away @@ -3502,8 +3497,10 @@ public final class ActivityThread {                      Resources r = v.get();                      if (r != null) {                          // keep the original density based on application cale. -                        appDm.density = r.getDisplayMetrics().density; +                        appDm.updateDensity(r.getDisplayMetrics().density);                          r.updateConfiguration(config, appDm); +                        // reset +                        appDm.setTo(dm);                          //Log.i(TAG, "Updated app resources " + v.getKey()                          //        + " " + r + ": " + r.getConfiguration());                      } else { 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 @@ 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/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 0aa5975..a174843 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -325,6 +325,14 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS          // show the dialog. this will call onStart().          if (!isShowing()) { +            // First make sure the keyboard is showing (if needed), so that we get the right height +            // for the dropdown to respect the IME. +            if (getContext().getResources().getConfiguration().hardKeyboardHidden == +                Configuration.HARDKEYBOARDHIDDEN_YES) { +                InputMethodManager inputManager = (InputMethodManager) +                getContext().getSystemService(Context.INPUT_METHOD_SERVICE); +                        inputManager.showSoftInputUnchecked(0, null); +            }              show();          } @@ -528,13 +536,16 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS          mSearchAutoComplete.setDropDownAnimationStyle(0); // no animation          mSearchAutoComplete.setThreshold(mSearchable.getSuggestThreshold()); -        // TODO: Use different dropdown background resource for in-app search.          if (mGlobalSearchMode) {              mSearchAutoComplete.setDropDownAlwaysVisible(true);  // fill space until results come in              mSearchAutoComplete.setDropDownDismissedOnCompletion(false); +            mSearchAutoComplete.setDropDownBackgroundResource( +                    com.android.internal.R.drawable.search_dropdown_background);          } else {              mSearchAutoComplete.setDropDownAlwaysVisible(false);              mSearchAutoComplete.setDropDownDismissedOnCompletion(true); +            mSearchAutoComplete.setDropDownBackgroundResource( +                    com.android.internal.R.drawable.search_dropdown_background_apps);          }          // attach the suggestions adapter, if suggestions are available diff --git a/core/java/android/content/ComponentName.java b/core/java/android/content/ComponentName.java index 32c6864..0455202 100644 --- a/core/java/android/content/ComponentName.java +++ b/core/java/android/content/ComponentName.java @@ -18,6 +18,7 @@ package android.content;  import android.os.Parcel;  import android.os.Parcelable; +import java.lang.Comparable;  /**   * Identifier for a specific application component @@ -29,7 +30,7 @@ import android.os.Parcelable;   * name inside of that package.   *    */ -public final class ComponentName implements Parcelable { +public final class ComponentName implements Parcelable, Comparable<ComponentName> {      private final String mPackage;      private final String mClass; @@ -196,6 +197,15 @@ public final class ComponentName implements Parcelable {      public int hashCode() {          return mPackage.hashCode() + mClass.hashCode();      } + +    public int compareTo(ComponentName that) { +        int v; +        v = this.mPackage.compareTo(that.mPackage); +        if (v != 0) { +            return v; +        } +        return this.mClass.compareTo(that.mClass); +    }      public int describeContents() {          return 0; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 3ebf816..81f72ac 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1940,7 +1940,7 @@ public class Intent implements Parcelable {      /**       * If set, this marks a point in the task's activity stack that should       * be cleared when the task is reset.  That is, the next time the task -     * is broad to the foreground with +     * is brought to the foreground with       * {@link #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED} (typically as a result of       * the user re-launching it from home), this activity and all on top of       * it will be finished so that the user does not return to them, but diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index fa9ec6e..88ac04c 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -126,6 +126,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {      public static final int FLAG_TARGETS_SDK = 1<<8;      /** +     * Value for {@link #flags}: this is set of the application has set +     * its android:targetSdkVersion to something >= the current SDK version. +     */ +    public static final int FLAG_TEST_ONLY = 1<<9; + +    /**       * Flags associated with the application.  Any combination of       * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},       * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and diff --git a/core/java/android/content/pm/IPackageInstallObserver.aidl b/core/java/android/content/pm/IPackageInstallObserver.aidl index e83bbc6..6133365 100644 --- a/core/java/android/content/pm/IPackageInstallObserver.aidl +++ b/core/java/android/content/pm/IPackageInstallObserver.aidl @@ -19,7 +19,7 @@ package android.content.pm;  /**   * API for installation callbacks from the Package Manager. - * + * @hide   */  oneway interface IPackageInstallObserver {      void packageInstalled(in String packageName, int returnCode); diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index d3f6f3c..c199619 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 d21252b..3a192f7 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -172,6 +172,14 @@ public abstract class PackageManager {      public static final int GET_SUPPORTS_DENSITIES    = 0x00008000;      /** +     * Resolution and querying flag: if set, only filters that support the +     * {@link android.content.Intent#CATEGORY_DEFAULT} will be considered for +     * matching.  This is a synonym for including the CATEGORY_DEFAULT in your +     * supplied Intent. +     */ +    public static final int MATCH_DEFAULT_ONLY   = 0x00010000; + +    /**       * Permission check result: this is returned by {@link #checkPermission}       * if the permission has been granted to the given package.       */ @@ -219,14 +227,6 @@ public abstract class PackageManager {       */      public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; -    /** -     * Resolution and querying flag: if set, only filters that support the -     * {@link android.content.Intent#CATEGORY_DEFAULT} will be considered for -     * matching.  This is a synonym for including the CATEGORY_DEFAULT in your -     * supplied Intent. -     */ -    public static final int MATCH_DEFAULT_ONLY   = 0x00010000; -      public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0;      public static final int COMPONENT_ENABLED_STATE_ENABLED = 1;      public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; @@ -235,14 +235,24 @@ public abstract class PackageManager {       * Flag parameter for {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} to       * indicate that this package should be installed as forward locked, i.e. only the app itself       * should have access to it's code and non-resource assets. +     * @hide       */ -    public static final int FORWARD_LOCK_PACKAGE = 0x00000001; +    public static final int INSTALL_FORWARD_LOCK = 0x00000001;      /**       * Flag parameter for {@link #installPackage} to indicate that you want to replace an already -     * installed package, if one exists +     * installed package, if one exists. +     * @hide       */ -    public static final int REPLACE_EXISTING_PACKAGE = 0x00000002; +    public static final int INSTALL_REPLACE_EXISTING = 0x00000002; + +    /** +     * Flag parameter for {@link #installPackage} to indicate that you want to  +     * allow test packages (those that have set android:testOnly in their +     * manifest) to be installed. +     * @hide +     */ +    public static final int INSTALL_ALLOW_TEST = 0x00000004;      /**       * Flag parameter for @@ -255,6 +265,7 @@ public abstract class PackageManager {      /**       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} on success. +     * @hide       */      public static final int INSTALL_SUCCEEDED = 1; @@ -262,6 +273,7 @@ public abstract class PackageManager {       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package is       * already installed. +     * @hide       */      public static final int INSTALL_FAILED_ALREADY_EXISTS = -1; @@ -269,6 +281,7 @@ public abstract class PackageManager {       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package archive       * file is invalid. +     * @hide       */      public static final int INSTALL_FAILED_INVALID_APK = -2; @@ -276,13 +289,15 @@ public abstract class PackageManager {       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the URI passed in       * is invalid. +     * @hide       */      public static final int INSTALL_FAILED_INVALID_URI = -3;      /**       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package manager -     * service found that the device didn't have enough storage space to install the app +     * service found that the device didn't have enough storage space to install the app. +     * @hide       */      public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4; @@ -290,6 +305,7 @@ public abstract class PackageManager {       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if a       * package is already installed with the same name. +     * @hide       */      public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5; @@ -297,6 +313,7 @@ public abstract class PackageManager {       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * the requested shared user does not exist. +     * @hide       */      public static final int INSTALL_FAILED_NO_SHARED_USER = -6; @@ -305,6 +322,7 @@ public abstract class PackageManager {       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * a previously installed package of the same name has a different signature       * than the new package (and the old package's data was not removed). +     * @hide       */      public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7; @@ -313,6 +331,7 @@ public abstract class PackageManager {       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * the new package is requested a shared user which is already installed on the       * device and does not have matching signature. +     * @hide       */      public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8; @@ -320,6 +339,7 @@ public abstract class PackageManager {       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * the new package uses a shared library that is not available. +     * @hide       */      public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9; @@ -327,6 +347,7 @@ public abstract class PackageManager {       * Installation return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * the new package uses a shared library that is not available. +     * @hide       */      public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10; @@ -335,6 +356,7 @@ public abstract class PackageManager {       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * the new package failed while optimizing and validating its dex files,       * either because there was not enough storage or the validation failed. +     * @hide       */      public static final int INSTALL_FAILED_DEXOPT = -11; @@ -343,6 +365,7 @@ public abstract class PackageManager {       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * the new package failed because the current SDK version is older than       * that required by the package. +     * @hide       */      public static final int INSTALL_FAILED_OLDER_SDK = -12; @@ -351,6 +374,7 @@ public abstract class PackageManager {       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * the new package failed because it contains a content provider with the       * same authority as a provider already installed in the system. +     * @hide       */      public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13; @@ -359,14 +383,26 @@ public abstract class PackageManager {       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if       * the new package failed because the current SDK version is newer than       * that required by the package. +     * @hide       */      public static final int INSTALL_FAILED_NEWER_SDK = -14;      /** +     * Installation return code: this is passed to the {@link IPackageInstallObserver} by +     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if +     * the new package failed because it has specified that it is a test-only +     * package and the caller has not supplied the {@link #INSTALL_ALLOW_TEST} +     * flag. +     * @hide +     */ +    public static final int INSTALL_FAILED_TEST_ONLY = -15; + +    /**       * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser was given a path that is not a file, or does not end with the expected       * '.apk' extension. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_NOT_APK = -100; @@ -374,6 +410,7 @@ public abstract class PackageManager {       * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser was unable to retrieve the AndroidManifest.xml file. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101; @@ -381,6 +418,7 @@ public abstract class PackageManager {       * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser encountered an unexpected exception. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102; @@ -388,6 +426,7 @@ public abstract class PackageManager {       * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser did not find any certificates in the .apk. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103; @@ -395,6 +434,7 @@ public abstract class PackageManager {       * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser found inconsistent certificates on the files in the .apk. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104; @@ -403,6 +443,7 @@ public abstract class PackageManager {       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser encountered a CertificateEncodingException in one of the       * files in the .apk. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105; @@ -410,6 +451,7 @@ public abstract class PackageManager {       * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser encountered a bad or missing package name in the manifest. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106; @@ -417,6 +459,7 @@ public abstract class PackageManager {       * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser encountered a bad shared user id name in the manifest. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107; @@ -424,6 +467,7 @@ public abstract class PackageManager {       * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser encountered some structural problem in the manifest. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108; @@ -432,6 +476,7 @@ public abstract class PackageManager {       * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}       * if the parser did not find any actionable tags (instrumentation or application)       * in the manifest. +     * @hide       */      public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109; @@ -1338,6 +1383,8 @@ public abstract class PackageManager {      }      /** +     * @hide +     *        * 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 @@ -1349,13 +1396,14 @@ public abstract class PackageManager {       * @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} -     * -     * @see #installPackage(android.net.Uri) +     * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK}, +     * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}. +     * @param installerPackageName Optional package name of the application that is performing the +     * installation. This identifies which market the package came from.       */      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 +1422,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 @@ -1479,17 +1538,6 @@ public abstract class PackageManager {              IPackageStatsObserver observer);      /** -     * Install a package. -     * -     * @param packageURI The location of the package file to install -     * -     * @see #installPackage(android.net.Uri, IPackageInstallObserver, int) -     */ -    public void installPackage(Uri packageURI) { -        installPackage(packageURI, null, 0); -    } - -    /**       * Add a new package to the list of preferred packages.  This new package       * will be added to the front of the list (removed from its current location       * if already listed), meaning it will now be preferred over all other diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 12df5bd..a1c0f48 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1187,6 +1187,12 @@ public class PackageParser {              ai.flags |= ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;          } +        if (sa.getBoolean( +                com.android.internal.R.styleable.AndroidManifestApplication_testOnly, +                true)) { +            ai.flags |= ApplicationInfo.FLAG_TEST_ONLY; +        } +          String str;          str = sa.getNonResourceString(                  com.android.internal.R.styleable.AndroidManifestApplication_permission); diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java index 6a560ce..fea63be 100755 --- a/core/java/android/inputmethodservice/Keyboard.java +++ b/core/java/android/inputmethodservice/Keyboard.java @@ -27,8 +27,7 @@ import android.text.TextUtils;  import android.util.Log;  import android.util.TypedValue;  import android.util.Xml; -import android.view.Display; -import android.view.WindowManager; +import android.util.DisplayMetrics;  import java.io.IOException;  import java.util.ArrayList; @@ -510,10 +509,11 @@ public class Keyboard {       * @param modeId keyboard mode identifier       */      public Keyboard(Context context, int xmlLayoutResId, int modeId) { -        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); -        final Display display = wm.getDefaultDisplay(); -        mDisplayWidth = display.getWidth(); -        mDisplayHeight = display.getHeight(); +        DisplayMetrics dm = context.getResources().getDisplayMetrics(); +        mDisplayWidth = dm.widthPixels; +        mDisplayHeight = dm.heightPixels; +        //Log.v(TAG, "keyboard's display metrics:" + dm); +          mDefaultHorizontalGap = 0;          mDefaultWidth = mDisplayWidth / 10;          mDefaultVerticalGap = 0; diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index 095f4f4..e4dd020 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -99,4 +99,24 @@ public class DisplayMetrics {          xdpi = DEVICE_DENSITY;          ydpi = DEVICE_DENSITY;      } + +    /** +     * Set the display metrics' density and update parameters depend on it. +     * @hide +     */ +    public void updateDensity(float newDensity) { +        float ratio = newDensity / density; +        density = newDensity; +        scaledDensity = density; +        widthPixels *= ratio; +        heightPixels *= ratio; +        xdpi *= ratio; +        ydpi *= ratio; +    } + +    public String toString() { +        return "DisplayMetrics{density=" + density + ", width=" + widthPixels + +            ", height=" + heightPixels + ", scaledDensity=" + scaledDensity + +            ", xdpi=" + xdpi + ", ydpi=" + ydpi + "}"; +    }  } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 61dca4c..40b03c8 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -256,6 +256,23 @@ public class SurfaceView extends View {      }      @Override +    public boolean dispatchTouchEvent(MotionEvent event) { +        // SurfaceView uses pre-scaled size unless fixed size is requested. This hook +        // scales the event back to the pre-scaled coordinates for such surface. +        if (mRequestedWidth < 0 && mAppScale != 1.0f) { +            MotionEvent scaledBack = MotionEvent.obtain(event); +            scaledBack.scale(mAppScale); +            try { +                return super.dispatchTouchEvent(scaledBack); +            } finally { +                scaledBack.recycle(); +            } +        } else { +            return super.dispatchTouchEvent(event); +        } +    } + +    @Override      protected void dispatchDraw(Canvas canvas) {          // if SKIP_DRAW is cleared, draw() has already punched a hole          if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { @@ -277,7 +294,13 @@ public class SurfaceView extends View {          if (myWidth <= 0) myWidth = getWidth();          int myHeight = mRequestedHeight;          if (myHeight <= 0) myHeight = getHeight(); -         + +        // Use original size for surface unless fixed size is requested. +        if (mRequestedWidth <= 0) { +            myWidth *= mAppScale; +            myHeight *= mAppScale; +        } +          getLocationInWindow(mLocation);          final boolean creating = mWindow == null;          final boolean formatChanged = mFormat != mRequestedFormat; @@ -333,7 +356,7 @@ public class SurfaceView extends View {                  mSurfaceLock.lock();                  mDrawingStopped = !visible;                  final int relayoutResult = mSession.relayout( -                    mWindow, mLayout, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale), +                    mWindow, mLayout, mWidth, mHeight,                          visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,                          mVisibleInsets, mSurface); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index d042f28..335b43c 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -850,6 +850,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback {      public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000;      /** +     * View flag indicating whether this view was invalidated (fully or partially.) +     * +     * @hide +     */ +    static final int DIRTY = 0x20000000; + +    /** +     * View flag indicating whether this view was invalidated by an opaque +     * invalidate request. +     * +     * @hide +     */ +    static final int DIRTY_OPAQUE = 0x40000000; + +    /** +     * Mask for {@link #DIRTY} and {@link #DIRTY_OPAQUE}. +     * +     * @hide +     */ +    static final int DIRTY_MASK = 0x60000000; + +    /**       * Use with {@link #focusSearch}. Move focus to the previous selectable       * item.       */ @@ -4522,6 +4544,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback {      }      /** +     * Indicates whether this View is opaque. An opaque View guarantees that it will +     * draw all the pixels overlapping its bounds using a fully opaque color. +     * +     * Subclasses of View should override this method whenever possible to indicate +     * whether an instance is opaque. Opaque Views are treated in a special way by +     * the View hierarchy, possibly allowing it to perform optimizations during +     * invalidate/draw passes. +     *  +     * @return True if this View is guaranteed to be fully opaque, false otherwise. +     * +     * @hide Pending API council approval +     */ +    @ViewDebug.ExportedProperty +    public boolean isOpaque() { +        return mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE; +    } + +    /**       * @return A handler associated with the thread running the View. This       * handler can be used to pump events in the UI events queue.       */ @@ -5687,7 +5727,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {              final int restoreCount = canvas.save();              canvas.translate(-mScrollX, -mScrollY); -            mPrivateFlags |= DRAWN; +            mPrivateFlags = (mPrivateFlags & ~DIRTY_MASK) | DRAWN;               // Fast path for layouts with no backgrounds              if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { @@ -5875,7 +5915,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback {              ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);          } -        mPrivateFlags |= DRAWN;                     +        final boolean dirtyOpaque = (mPrivateFlags & DIRTY_MASK) == DIRTY_OPAQUE; +        mPrivateFlags = (mPrivateFlags & ~DIRTY_MASK) | DRAWN;          /*           * Draw traversal performs several drawing steps which must be executed @@ -5892,22 +5933,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback {          // Step 1, draw the background, if needed          int saveCount; -        final Drawable background = mBGDrawable; -        if (background != null) { -            final int scrollX = mScrollX; -            final int scrollY = mScrollY; +        if (!dirtyOpaque) { +            final Drawable background = mBGDrawable; +            if (background != null) { +                final int scrollX = mScrollX; +                final int scrollY = mScrollY; -            if (mBackgroundSizeChanged) { -                background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop); -                mBackgroundSizeChanged = false; -            } +                if (mBackgroundSizeChanged) { +                    background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop); +                    mBackgroundSizeChanged = false; +                } -            if ((scrollX | scrollY) == 0) { -                background.draw(canvas); -            } else { -                canvas.translate(scrollX, scrollY); -                background.draw(canvas); -                canvas.translate(-scrollX, -scrollY); +                if ((scrollX | scrollY) == 0) { +                    background.draw(canvas); +                } else { +                    canvas.translate(scrollX, scrollY); +                    background.draw(canvas); +                    canvas.translate(-scrollX, -scrollY); +                }              }          } @@ -5917,7 +5960,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {          boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;          if (!verticalEdges && !horizontalEdges) {              // Step 3, draw the content -            onDraw(canvas); +            if (!dirtyOpaque) onDraw(canvas);              // Step 4, draw the children              dispatchDraw(canvas); @@ -6020,7 +6063,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {          }          // Step 3, draw the content -        onDraw(canvas); +        if (!dirtyOpaque) onDraw(canvas);          // Step 4, draw the children          dispatchDraw(canvas); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index e686d1c..31159d7 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1796,7 +1796,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager              boolean preventRequestLayout) {          child.mParent = null;          addViewInner(child, index, params, preventRequestLayout); -        child.mPrivateFlags |= DRAWN; +        child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK) | DRAWN;          return true;      } @@ -2210,7 +2210,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager          addInArray(child, index);          child.mParent = this; -        child.mPrivateFlags |= DRAWN; +        child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK) | DRAWN;          if (child.hasFocus()) {              requestChildFocus(child, child.findFocus()); @@ -2320,15 +2320,33 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager              // ourselves and the parent to make sure the invalidate request goes              // through              final boolean drawAnimation = (child.mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION; -     + +            // Check whether the child that requests the invalidate is fully opaque +            final boolean isOpaque = child.isOpaque(); +            // Mark the child as dirty, using the appropriate flag +            // Make sure we do not set both flags at the same time +            final int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY; +              do { +                View view = null; +                if (parent instanceof View) { +                    view = (View) parent; +                } +                  if (drawAnimation) { -                    if (parent instanceof View) { -                        ((View) parent).mPrivateFlags |= DRAW_ANIMATION; +                    if (view != null) { +                        view.mPrivateFlags |= DRAW_ANIMATION;                      } else if (parent instanceof ViewRoot) {                          ((ViewRoot) parent).mIsAnimating = true;                      }                  } + +                // If the parent is dirty opaque or not dirty, mark it dirty with the opaque +                // flag coming from the child that initiated the invalidate +                if (view != null && (view.mPrivateFlags & DIRTY_MASK) != DIRTY) { +                    view.mPrivateFlags = (view.mPrivateFlags & ~DIRTY_MASK) | opaqueFlag; +                } +                  parent = parent.invalidateChildInParent(location, dirty);              } while (parent != null);          } diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 0b03626..8494d5e 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -539,6 +539,7 @@ public final class ViewRoot extends Handler implements ViewParent,              }              dirty = mTempRect;          } +        // TODO: When doing a union with mDirty != empty, we must cancel all the DIRTY_OPAQUE flags          mDirty.union(dirty);          if (!mWillDrawSoon) {              scheduleTraversals(); @@ -959,11 +960,10 @@ public final class ViewRoot extends Handler implements ViewParent,                          mTmpLocation[1] + host.mBottom - host.mTop);                  host.gatherTransparentRegion(mTransparentRegion); +                if (mAppScale != 1.0f) { +                    mTransparentRegion.scale(mAppScale); +                } -                // TODO: scale the region, like: -                // Region uses native methods. We probabl should have ScalableRegion class. - -                // Region does not have equals method ?                  if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {                      mPreviousTransparentRegion.set(mTransparentRegion);                      // reconfigure window manager @@ -1878,9 +1878,6 @@ public final class ViewRoot extends Handler implements ViewParent,          } else {              didFinish = false;          } -        if (event != null) { -            event.scale(mAppScaleInverted); -        }          if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event); diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java index 5f8acc8..17d3f94 100644 --- a/core/java/android/webkit/CallbackProxy.java +++ b/core/java/android/webkit/CallbackProxy.java @@ -98,6 +98,7 @@ class CallbackProxy extends Handler {      private static final int SCALE_CHANGED        = 123;      private static final int RECEIVED_CERTIFICATE = 124;      private static final int SWITCH_OUT_HISTORY   = 125; +    private static final int JS_TIMEOUT           = 126;      // Message triggered by the client to resume execution      private static final int NOTIFY               = 200; @@ -530,6 +531,18 @@ class CallbackProxy extends Handler {                  }                  break; +            case JS_TIMEOUT: +                if(mWebChromeClient != null) { +                    final JsResult res = (JsResult) msg.obj; +                    if(mWebChromeClient.onJsTimeout()) { +                        res.confirm(); +                    } else { +                        res.cancel(); +                    } +                    res.setReady(); +                } +                break; +              case RECEIVED_CERTIFICATE:                  mWebView.setCertificate((SslCertificate) msg.obj);                  break; @@ -1022,4 +1035,26 @@ class CallbackProxy extends Handler {          }          return result.getResult();      } + +    /** +     * @hide pending API council approval +     */ +    public boolean onJsTimeout() { +        //always interrupt timedout JS by default +        if (mWebChromeClient == null) { +            return true; +        } +        JsResult result = new JsResult(this, true); +        Message timeout = obtainMessage(JS_TIMEOUT, result); +        synchronized (this) { +            sendMessage(timeout); +            try { +                wait(); +            } catch (InterruptedException e) { +                Log.e(LOGTAG, "Caught exception while waiting for jsUnload"); +                Log.e(LOGTAG, Log.getStackTraceString(e)); +            } +        } +        return result.getResult(); +    }  } diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java index c0c6775..e8c2279 100644 --- a/core/java/android/webkit/CookieManager.java +++ b/core/java/android/webkit/CookieManager.java @@ -647,8 +647,6 @@ public final class CookieManager {                      // another file in the local web server directory. Still                      // "localhost" is the best pseudo domain name.                      ret[0] = "localhost"; -                } else if (!ret[0].equals("localhost")) { -                    return null;                  }              } else if (index == ret[0].lastIndexOf(PERIOD)) {                  // cookie host must have at least two periods diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java index f940006..9d9763c 100644 --- a/core/java/android/webkit/WebChromeClient.java +++ b/core/java/android/webkit/WebChromeClient.java @@ -157,4 +157,19 @@ public class WebChromeClient {              JsResult result) {          return false;      } + +    /** +     * Tell the client that a JavaScript execution timeout has occured. And the +     * client may decide whether or not to interrupt the execution. If the +     * client returns true, the JavaScript will be interrupted. If the client +     * returns false, the execution will continue. Note that in the case of +     * continuing execution, the timeout counter will be reset, and the callback +     * will continue to occur if the script does not finish at the next check +     * point. +     * @return boolean Whether the JavaScript execution should be interrupted. +     * @hide pending API Council approval +     */ +    public boolean onJsTimeout() { +        return true; +    }  } diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 58d8ae7..e9df453 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -263,6 +263,16 @@ final class WebViewCore {          return mCallbackProxy.onJsBeforeUnload(url, message);      } +    /** +     * +     * Callback to notify that a JavaScript execution timeout has occured. +     * @return True if the JavaScript execution should be interrupted. False +     *         will continue the execution. +     */ +    protected boolean jsInterrupt() { +        return mCallbackProxy.onJsTimeout(); +    } +      //-------------------------------------------------------------------------      // JNI methods      //------------------------------------------------------------------------- diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 767c7e7..4f503b4 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. @@ -2299,6 +2301,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te              }              if (more) { +                invalidate();                  mLastFlingY = y;                  post(this);              } else { @@ -2322,16 +2325,23 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te      }      private void clearScrollingCache() { -        if (mCachingStarted) { -            setChildrenDrawnWithCacheEnabled(false); -            if ((mPersistentDrawingCache & PERSISTENT_SCROLLING_CACHE) == 0) { -                setChildrenDrawingCacheEnabled(false); -            } -            if (!isAlwaysDrawnWithCacheEnabled()) { -                invalidate(); -            } -            mCachingStarted = false; +        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);      }      /** @@ -2788,7 +2798,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te          int screenHeight = getResources().getDisplayMetrics().heightPixels;          final int[] xy = new int[2];          getLocationOnScreen(xy); -        // TODO: The 20 below should come from the theme and be expressed in dip +        // TODO: The 20 below should come from the theme          // TODO: And the gravity should be defined in the theme as well          final int bottomGap = screenHeight - xy[1] - getHeight() + (int) (mDensityScale * 20);          if (!mPopup.isShowing()) { diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 66c162e..5472d68 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -20,6 +20,7 @@ import android.content.Context;  import android.content.res.TypedArray;  import android.graphics.Canvas;  import android.graphics.Rect; +import android.graphics.PixelFormat;  import android.graphics.drawable.Drawable;  import android.graphics.drawable.ColorDrawable;  import android.os.Parcel; @@ -113,7 +114,11 @@ public class ListView extends AbsListView {      Drawable mDivider;      int mDividerHeight; + +    private boolean mIsCacheColorOpaque; +    private boolean mDividerIsOpaque;      private boolean mClipDivider; +      private boolean mHeaderDividersEnabled;      private boolean mFooterDividersEnabled; @@ -2776,6 +2781,20 @@ public class ListView extends AbsListView {          return mItemsCanFocus;      } +    /** +     * @hide Pending API council approval. +     */ +    @Override +    public boolean isOpaque() { +        return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque) || super.isOpaque(); +    } + +    @Override +    public void setCacheColorHint(int color) { +        mIsCacheColorOpaque = (color >>> 24) == 0xFF; +        super.setCacheColorHint(color); +    } +      @Override      protected void dispatchDraw(Canvas canvas) {          // Draw the dividers @@ -2897,6 +2916,7 @@ public class ListView extends AbsListView {              mClipDivider = false;          }          mDivider = divider; +        mDividerIsOpaque = divider == null || divider.getOpacity() == PixelFormat.OPAQUE;          requestLayoutIfNecessary();      } 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 @@ 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]; | 
