Merge "Fixed a typo in a method name of MediaPlayerPerformance.java class" into gingerbread
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index b7a750b..00063af 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -403,7 +403,7 @@
      *
      * <p class="caution">Note that the system calls this on your
      * service's main thread.  A service's main thread is the same
-     * thread where UI operations place for Activities running in the
+     * thread where UI operations take place for Activities running in the
      * same process.  You should always avoid stalling the main
      * thread's event loop.  When doing long-running operations,
      * network calls, or heavy disk I/O, you should kick off a new
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 73c4011..0b35d8b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -587,7 +587,7 @@
      * location from the apk location at the given file path.
      * @param packageFilePath file location of the apk
      * @param flags Special parse flags
-     * @return PackageLite object with package information.
+     * @return PackageLite object with package information or null on failure.
      */
     public static PackageLite parsePackageLite(String packageFilePath, int flags) {
         XmlResourceParser parser = null;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7bb89f5..ea26207 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3373,6 +3373,14 @@
         public static final String THROTTLE_MAX_NTP_CACHE_AGE_SEC =
                 "throttle_max_ntp_cache_age_sec";
 
+        /**
+         * The maximum size, in bytes, of a download that the download manager will transfer over
+         * a non-wifi connection.
+         * @hide
+         */
+        public static final String DOWNLOAD_MAX_BYTES_OVER_MOBILE =
+                "download_manager_max_bytes_over_mobile";
+
 
         /**
          * @hide
diff --git a/docs/html/guide/publishing/licensing.jd b/docs/html/guide/publishing/licensing.jd
index e3b9135..07af68d 100644
--- a/docs/html/guide/publishing/licensing.jd
+++ b/docs/html/guide/publishing/licensing.jd
@@ -154,7 +154,7 @@
 <p>When the application receives a signed response, it uses the embedded public
 key to verify the data. The use of public key cryptography in the licensing
 service makes it possible for the application to detect responses that have been
-tampered with or are spoofed.</p>
+tampered with or that are spoofed.</p>
 
 <h4>Use of licensing in your application</h4>
 
@@ -184,7 +184,7 @@
 and helps ensure a more secure, robust implementation for your application. The
 LVL provides internal classes that handle most of the standard operations of a
 license query, such as contacting Android Market to initiate a license request
-and decrypting and validating the responses. It also exposes key interfaces that
+and verifying and validating the responses. It also exposes key interfaces that
 let you easily plug in your custom code for defining licensing policy and
 managing access as needed by your application. The key LVL interfaces are: </p>
 
@@ -211,7 +211,7 @@
 <li><a href="#ServerManagedPolicy">ServerManagedPolicy</a> is a flexible Policy
 that uses settings provided by the licensing server to manage response caching
 and access to the application while the device is offline (such as when the
-user is on on an airplane). For most applications, the use of
+user is on an airplane). For most applications, the use of
 ServerManagedPolicy is highly recommended. </li>
 <li><a href="#StrictPolicy">StrictPolicy</a> is a restrictive Policy that
 does not cache any response data and allows the application access <em>only</em>
@@ -233,10 +233,10 @@
 <h4>Requirements and limitations</h4>
 
 <p>Android Market Licensing is designed to let you apply license controls to
-applications that you publish through Android Market and that users download
-from Market. The service is not designed to let you control access to
-applications that are not published through Android Market or that are run
-on devices that do not offer the Android Market client. </p>
+applications that you publish through Android Market. The service is not
+designed to let you control access to applications that are not published
+through Android Market or that are run on devices that do not offer the Android
+Market client. </p>
 
 <p>Here are some points to keep in mind as you implement licensing in your
 application: </p>
@@ -267,14 +267,15 @@
 
 <p>Android Market Licensing is a flexible, secure mechanism for controlling
 access to your applications. It effectively replaces the copy-protection
-mechanism and gives you wider distribution potential for your applications. </p>
+mechanism offered on Android Market and gives you wider distribution
+potential for your applications. </p>
 
 <ul>
-<li>A limitation of copy protection is that applications using it can be
-installed only on compatible devices that provide a secure internal storage
-environment. For example, a copy-protected application cannot be downloaded
-from Market to a device that provides root access, and the application
-cannot be installed to a device's SD card. </li>
+<li>A limitation of the legacy copy-protection mechanism on Android Market is
+that applications using it can be installed only on compatible devices that
+provide a secure internal storage environment. For example, a copy-protected
+application cannot be downloaded from Market to a device that provides root
+access, and the application cannot be installed to a device's SD card. </li>
 <li>With Android Market licensing, you can move to a license-based model in
 which access is not bound to the characteristics of the host device, but to your
 publisher account on Android Market and the licensing policy that you define.
@@ -338,7 +339,7 @@
 <ul>
 <li>Set up multiple "test accounts", identified by email address. The licensing
 server allows users signed into test accounts on a device or emulator to send
-license checks and receive static test reponses.</li>
+license checks and receive static test responses.</li>
 <li>Obtain the account's public key for licensing. When you are implementing
 licensing in an application, you must copy the public key string into the
 application.</li>
@@ -402,7 +403,7 @@
 <p>If you haven't done so, you need to download the Android SDK before you can
 develop Android applications. The SDK provides the tools that you need to build
 and debug Android applications, including applications that use Android Market
-licensing. For complete information, including installation intructions, see
+licensing. For complete information, including installation instructions, see
 the <a href="{@docRoot}sdk/index.html">Android SDK</a>. </p>
 
 <p>If you have already installed the SDK, make sure to update the
@@ -472,7 +473,7 @@
 
 <ul>
 <li>An Android Market background service that implements the
-<code>ILicensingService</code> remote interface, so that your application can
+ILicensingService remote interface, so that your application can
 send license checks over the network to the licensing server. </li>
 <li>A set of underlying account services that let you add an a Google account on
 the AVD and sign in using your publisher account or test account credentials.
@@ -492,7 +493,7 @@
 <img src="{@docRoot}images/licensing_gapis_8.png" style="text-align:left;margin-bottom:0;" />
 <div style="margin:0 2em;padding:0"><strong>Figure 3.</strong> Google APIs
 Add-On, API 8 (release 2) or higher lets you debug and test your licensing
-implemention in an emulator.</div>
+implementation in an emulator.</div>
 </div>
 
 <p>To set up an emulator for adding licensing to an application, follow
@@ -581,9 +582,9 @@
 <p>When the download is complete, the Android SDK and AVD Manager installs both
 the LVL library project and the example application into these directories: </p>
 
-<p style="margin-left:2em"><code>&lt;<em>sdk</em>&gt;/marketlicensing/library/</code>
+<p style="margin-left:2em"><code>&lt;<em>sdk</em>&gt;/market_licensing/library/</code>
 &nbsp;&nbsp;(the LVL library project)<br />
-<code>&lt;<em>sdk</em>&gt;/marketlicensing/sample/</code>&nbsp;&nbsp;(the example
+<code>&lt;<em>sdk</em>&gt;/market_licensing/sample/</code>&nbsp;&nbsp;(the example
 application)</p>
 
 <p>If you aren't familiar with how to download components into your SDK, see the
@@ -601,20 +602,21 @@
 maintain it more easily over time. Note that the LVL is not designed to be
 compiled separately and added to an application as a static .jar file. </p>
 
-<h4>Moving the library sources out  location</h4>
+<h4>Moving the library sources to a new location</h4>
 
 <p>Because you will be customizing the LVL sources to some extent, you should
 make sure to <em>move or copy</em> the library sources (the entire
-directory at <code>&lt;<em>sdk</em>&gt;/marketlicensing/library/</code>)
-to a working directory outside of the SDK. You can then add the sources
-in the working location to your source-code management system, rather
-than those in the SDK.</p>
+directory at <code>&lt;<em>sdk</em>&gt;/market_licensing/library/</code>)
+to a working directory outside of the SDK. You should then use the relocated
+sources as your working set. If you are using a source-code management
+system, add and track the sources that are in the working location rather
+than those in default location in the SDK. </p>
 
 <p>Moving the library sources is important is because, when you later update the
 Market licensing package, the SDK installs the new files to the same location as
 the older files. Moving your working library files to a safe location ensures
-that they won't be inadvertently overwritten when you download a new version of
-the LVL.</p>
+that your work won't be inadvertently overwritten should you download a new
+version of the LVL.</p>
 
 <h4>Creating the LVL as a library project</h4>
 
@@ -639,11 +641,11 @@
 <em>library project</em>. A library project is a type of development project
 that holds shared Android source code and resources. Other Android application
 projects can reference the library project and, at build time, include its
-compiled sources in their <code>.apk</code> files. In the context of licensing, this means
-that you can do most of your licensing development once, in a library project,
-then include the library sources in your various application projects. In this
-way, you can easily maintain a uniform implementation of licensing across all of
-your projects and maintain it centrally. </p>
+compiled sources in their <code>.apk</code> files. In the context of licensing,
+this means that you can do most of your licensing development once, in a library
+project, then include the library sources in your various application projects.
+In this way, you can easily maintain a uniform implementation of licensing
+across all of your projects and maintain it centrally. </p>
 
 <p>The LVL is provided as a configured library project &mdash; once you have
 downloaded it, you can start using it right away. </p>
@@ -675,9 +677,8 @@
 
 <p>As an alternative to adding the LVL as a library project, you can copy the
 library sources directly into your application. To do so, copy (or import) the
-directory
-<code>&lt;<em>sdk</em>&gt;/extras/marketlicensing/library/src/com</code> into
-your application's <code>src/</code> directory.</p>
+LVL's <code>library/src/com</code> directory into your application's
+<code>src/</code> directory.</p>
 
 <p>If you add the LVL sources directly to your application, you can skip the
 next section and start working with the library, as described in <a
@@ -688,10 +689,10 @@
 application</h3>
 
 <p>If you want to use the LVL sources as a library project, you need to add a
-reference to the LVL library project in your project properties. This tells
+reference to the LVL library project in your application project properties. This tells
 build tools to include the LVL library project sources in your application at
-compile time. The process for adding a reference to a library project varies,
-based on your development environment, as described below.</p>
+compile time. The process for adding a reference to a library project depends
+on your development environment, as described below.</p>
 
 <p> If you are developing in Eclipse with ADT, you should already have added the
 library project to your workspace, as described in the previous section. If you
@@ -793,10 +794,10 @@
 </pre>
 
 <p class="note"><strong>Note:</strong> Currently, you cannot declare the
-<code>CHECK_LICENSE</code> permission in the LVL's manifest, because the SDK
-Tools will not merge it into the manifests of dependent applications. Instead,
-you must declare the permission in the manifest of each dependent application.
-</p>
+<code>CHECK_LICENSE</code> permission in the LVL library project's manifest,
+because the SDK Tools will not merge it into the manifests of dependent
+applications. Instead, you must declare the permission in each dependent
+application's manifest. </p>
 
 
 <h3 id="impl-Policy">Implementing a Policy</h3>
@@ -856,7 +857,7 @@
 example, your implementation of <code>allowAccess()</code> could take into
 account additional criteria, such as usage or other data retrieved from a
 backend server. In all cases, an implementation of <code>allowAccess()</code>
-should only return <code>true</code> if there user is licensed to use the
+should only return <code>true</code> if the user is licensed to use the
 application, as determined by the licensing server, or if there is a transient
 network or system problem that prevents the license check from completing. In
 such cases, your implementation can maintain a count of retry responses and
@@ -866,7 +867,8 @@
 
 <p>To simplify the process of adding licensing to your application and to
 provide an illustration of how a Policy should be designed, the LVL includes
-two full Policy implementations that you can use without modification:</p>
+two full Policy implementations that you can use without modification or
+adapt to your needs:</p>
 
 <ul>
 <li><a href="#ServerManagedPolicy">ServerManagedPolicy</a>, a flexible Policy
@@ -886,7 +888,7 @@
 
 <p>In your licensing implementation, you can use one of the complete policies
 provided in the LVL (ServerManagedPolicy or StrictPolicy) or you can create a
-custom Policy. For any type of custom policy, there are several important design
+custom policy. For any type of custom policy, there are several important design
 points to understand and account for in your implementation.</p>
 
 <p>The licensing server applies general request limits to guard against overuse
@@ -896,7 +898,7 @@
 license response will be available to the user until the limit is reset, which
 can affect the user for an indefinite period.</p>
 
-<p>If you are designing a custom Policy, we recommend that the Policy:
+<p>If you are designing a custom policy, we recommend that the Policy:
 <ol>
 <!-- <li>Limits the number of points at which your app calls for a license check
 to the minimum. </li> -->
@@ -904,12 +906,12 @@
 in local persistent storage.</li>
 <li>Returns the cached response for all license checks, for as long as the
 cached response is valid, rather than making a request to the licensing server.
-Setting the response validity accrording to the server-provided <code>VT</code>
+Setting the response validity according to the server-provided <code>VT</code>
 extra is highly recommended. See <a href="#extras">Server Response Extras</a>
 for more information.</li>
-<li>Uses an exponential backoff period if retrying any requests the result in
-errors. However, because the Android Market client automatically retries failed
-requests, the Policy does not need to do so, in most cases.</li>
+<li>Uses an exponential backoff period, if retrying any requests the result in
+errors. Note that the Android Market client automatically retries failed
+requests, so in most cases there is no need for your Policy to retry them.</li>
 <li>Provides for a "grace period" that allows the user to access your
 application for a limited time or number of uses, while a license check is being
 retried. The grace period benefits the user by allowing access until the next
@@ -942,7 +944,7 @@
 
 <p style="margin-top:.5em;">See <a href="#extras">Server Response Extras</a> for
 a list of settings and <code>ServerManagedPolicy.java</code> for information
-about how a Policy can usethe extras.</p>
+about how a Policy can use the extras.</p>
 
 </div>
 </div>
@@ -965,8 +967,8 @@
 server-provided settings as the basis for managing licensing across an
 application's refund period and through varying network and error conditions.
 When an application contacts the Android Market server for a license check, the
-server appends several settings as key-value pairs in the license response
-extras field. For example, the server provides recommended values for the
+server appends several settings as key-value pairs in the extras field of certain
+license response types. For example, the server provides recommended values for the
 application's license validity period, retry grace period, and maximum allowable
 retry count, among others. ServerManagedPolicy extracts the values from the
 license response in its <code>processServerResponse()</code> method and checks
@@ -1019,8 +1021,7 @@
 means that they won't be able to access the application when there is no network
 (cell or wi-fi) connection available. Another side-effect is that your
 application will send more license check requests to the server, since using a
-cached response is not possible. Depending on network conditions, this might
-prove challenging for users also.</p>
+cached response is not possible.</p>
 
 <p>Overall, this policy represents a tradeoff of some degree of user convenience
 for absolute security and control over access. Consider the tradeoff carefully
@@ -1058,7 +1059,7 @@
 
 <p>Because the Policy will use stored license response data to determine whether
 to allow or disallow access to the application, it <em>must</em> ensure that any
-stored data is secure and can not be reused or manipulated by a root user on a
+stored data is secure and cannot be reused or manipulated by a root user on a
 device. Specifically, the Policy must always obfuscate the data before storing
 it, using a key that is unique for the application and device. Obfuscating using
 a key that is both application-specific and device-specific is critical, because
@@ -1066,20 +1067,18 @@
 devices.</p>
 
 <p>The LVL assists the application with storing its license response data in a
-secure, persistent manner. First, it provides an <code>Obfuscator</code>
+secure, persistent manner. First, it provides an Obfuscator
 interface that lets your application supply the obfuscation algorithm of its
 choice for stored data. Building on that, the LVL provides the helper class
-<code>PreferenceObfuscator</code>, which handles most of the work of calling the
+PreferenceObfuscator, which handles most of the work of calling the
 application's Obfuscator class and reading and writing the obfuscated data in a
 SharedPreferences instance. </p>
 
 <p>The LVL provides a full Obfuscator implementation called
-<code>AESObfuscator</code> that uses AES encryption to obfuscate data. You can
-use <code>AESObfuscator</code> in your application without modification or you
+AESObfuscator that uses AES encryption to obfuscate data. You can
+use AESObfuscator in your application without modification or you
 can adapt it to your needs. For more information, see the next section.</p>
 
-<p>Alternatively, you can write a custom Obfuscator based on your own code
-or use an obfuscator program such as ProGuard for additional security.</p>
 
 <h4 id="AESObfuscator">AESObfuscator</h4>
 
@@ -1118,14 +1117,16 @@
 <code>android.Settings.Secure.ANDROID_ID</code>, which is unique to each device.
 </p>
 
-<p>Note that, depending on the APIs you use to derive device-specific
-information, your application might need to request additional permissions in
-order to secure device-specific information. For example, if you query the
-TelephonyManager to obtain the device IMEI or related data, your application
-will also need to request the <code>android.permission.READ_PHONE_STATE</code>
-permission in its manifest. Before requesting permissions in this way, consider
-how doing so might affect your application or its filtering of your application
-on Android Market (since some permissions can cause the SDK build tools to add
+<p>Note that, depending on the APIs you use, your application might need to
+request additional permissions in order to acquire device-specific information.
+For example, to query the {@link android.telephony.TelephonyManager} to obtain
+the device IMEI or related data, the application will also need to request the
+<code>android.permission.READ_PHONE_STATE</code> permission in its manifest.</p>
+
+<p>Before requesting new permissions for the <em>sole purpose</em> of acquiring
+device-specific information for use in your Obfuscator, consider
+how doing so might affect your application or its filtering on Android Market
+(since some permissions can cause the SDK build tools to add
 the associated <code>&lt;uses-feature&gt;</code>).</p>
 
 <p>Finally, construct an instance of AESObfuscator, passing the salt,
@@ -1441,7 +1442,7 @@
 </ul>
 
 <p>If you are using ServerManagedPolicy, you won't need to access the class
-directly, so you can instantiate it directly in the LicenseChecker constructor,
+directly, so you can instantiate it in the LicenseChecker constructor,
 as shown in the example below. Note that you need to pass a reference to a new
 Obfuscator instance when you construct ServerManagedPolicy.</p>
 
@@ -1510,7 +1511,7 @@
 <h4 id="account-key">Embed your public key for licensing</h4>
 
 <p>For each publisher account, the Android Market service automatically
-generates a  2048-bit RSA public/private key pair that is used exlusively for
+generates a  2048-bit RSA public/private key pair that is used exclusively for
 licensing. The key pair is uniquely associated with the publisher account and is
 shared across all applications that are published through the account. Although
 associated with a publisher account, the key pair is <em>not</em> the same as
@@ -1562,14 +1563,14 @@
 application's ILicensingService and removes any local references to the service
 and handler.</p>
 
-<p>Failing to add the call the LicenseChecker's <code>onDestroy()</code> method
+<p>Failing to call the LicenseChecker's <code>onDestroy()</code> method
 can lead to problems over the lifecycle of your application. For example, if the
 user changes screen orientation while a license check is active, the application
 {@link android.content.Context} is destroyed. If your application does not
 properly close the LicenseChecker's IPC connection, your application will crash
 when the response is received. Similarly, if the user exits your application
 while a license check is in progress,  your application will crash when the
-response is received, unless your application has properly called the
+response is received, unless it has properly called the
 LicenseChecker's <code>onDestroy()</code> method to disconnect from the service.
 </p>
 
@@ -1608,7 +1609,7 @@
 required</strong> &mdash; the LicenseChecker class automatically uses a default
 implementation called NullDeviceLimiter. As the name suggests, NullDeviceLimiter
 is a "no-op" class whose <code>allowDeviceAccess()</code> method simply returns
-a LICENSED response for all users and devices. </p>
+a <code>LICENSED</code> response for all users and devices. </p>
 
 <div style="border-left:4px solid #FFCF00;margin:1em;padding: 0 0 0 .5em">
 <p><strong>Caution:</strong> Per-device licensing is <em>not recommended for
@@ -1634,15 +1635,15 @@
 
 <ul>
 <li>A "Test response" configuration in your publisher account that lets you
-control the licensing response returned, when the server processes a license
-check for an uploaded application from the publisher account or a test
-account.</li>
-<li>An optional set of test accounts that will receive the configured test
-response when checking the license of an application that you have uploaded
+set the static licensing response returned, when the server processes a
+license check for an application uploaded to the publisher account, from a user
+signed in to the publisher account or a test account.</li>
+<li>An optional set of test accounts that will receive the static test
+response when they check the license of an application that you have uploaded
 (regardless whether the application is published or not).</li>
 <li>A runtime environment for the application that includes the Android Market
 application or Google APIs Add-On, on which the user is signed in to the
-publisher account or one of the test accounts.
+publisher account or one of the test accounts.</li>
 </ul>
 
 <p>Setting up the test environment properly involves:</p>
@@ -1659,11 +1660,12 @@
 <h3 id="test-response">Setting test responses for license checks</h3>
 
 <p>Android Market provides a configuration setting in your publisher account
-that lets you override the normal processing of a license check for an
-application you have uploaded and return a specified response code. The setting
-is for testing only and applies <em>only</em> to license checks for applications
-that you have uploaded. For other users (users not signed in to test accounts),
-the server always processes license checks according to normal rules.  </p>
+that lets you override the normal processing of a license check and return a
+specified static response code. The setting is for testing only and applies
+<em>only</em> to license checks for applications that you have uploaded, made by
+any user signed in to an emulator or device using the credentials of the
+publisher account or a registered test account. For other users, the server
+always processes license checks according to normal rules.  </p>
 
 <p>To set a test response for your account, sign in to your publisher account
 and click "Edit Profile". In the Edit Profile page, locate the Test Response
@@ -1672,9 +1674,9 @@
 test in your application.</p>
 
 <p>In general, you should make sure to test your application's licensing
-implementation with every response code available in the Test Response" menu.
+implementation with every response code available in the Test Response menu.
 For a description of the codes, see <a href="#server-response-codes">Server
-Response Codes</a>, below.</p>
+Response Codes</a> in the Appendix of this document.</p>
 
 <div style="margin-bottom:2em;" id="licensing_test_response">
 
@@ -1688,10 +1690,11 @@
 that is, it applies not to a single application, but to <em>all</em>
 applications associated with the publisher account. If you are testing multiple
 applications at once, changing the test response will affect all of those
-applications on their next license check.</p>
+applications on their next license check (if the user is signed into
+the emulator or device using the publisher account or a test account).</p>
 
-<p>Finally, before you can successfully send these test responses to your
-application, you must sign in to the device or emulator on which the application
+<p>Before you can successfully receive a test response for a license check,
+you must sign in to the device or emulator on which the application
 is installed, and from which it is querying the server. Specifically, you must
 sign using either your publisher account or one of the test accounts that you
 have set up. For more information about test accounts, see the next section.</p>
@@ -1799,7 +1802,7 @@
 <p>The licensing server handles static test responses in the normal way,
 including signing the license response data, adding extras parameters, and so
 on. To support developers who are implementing licensing using test accounts,
-rather than having access to the publisher account, you will need to distribute
+rather than the publisher account, you will need to distribute
 your public key to them. Developers without access to the publisher site do not
 have access to your public key, and without the key they won't be able to
 verify license responses. </p>
@@ -2176,7 +2179,7 @@
 <td>No </td>
 <td></td>
 <td><em>Do not retry the license check.</em>
-<p style="margin-top:.5em;">Typically caused by a developement error.</p>
+<p style="margin-top:.5em;">Typically caused by a development error.</p>
 </td>
 </tr>
 <tr>
@@ -2187,7 +2190,7 @@
 <td>No </td>
 <td></td>
 <td><em>Do not retry the license check.</em>
-<p style="margin-top:.5em;">Typically caused by a developement error.</p>
+<p style="margin-top:.5em;">Typically caused by a development error.</p>
 </td>
 </tr>
 <tr>
@@ -2295,7 +2298,7 @@
 
 <ul>
 <li>For a paid application, the server sets the initial license validity period
-so that the license reponse remains valid for as long as the application is
+so that the license response remains valid for as long as the application is
 refundable. A licensing Policy in the application may cache the
 result of the initial license check and does not need to recheck the license
 until the validity period has expired.</li>
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 01940e8..f37a122 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -163,12 +163,11 @@
       'img':"devphone-large.png",
       'title':"Android Dev Phones",
       'desc': "<p>Run and debug your Android applications directly on one of these "
- + "device. Modify and rebuild the Android operating system, and flash it onto "
- + "the phone. The Android Dev Phones are carrier independent, and available for "
- + "purchase by any developer registered with <a "
- + "href='http://market.android.com/publish'>Android Market</a>.</p><p><a "
- + "href='/guide/developing/device.html#dev-phone-1'>Learn more about the "
- + "Android Dev Phones &raquo;</a></p>"
+ + "devices. Modify and rebuild the Android operating system, and flash it onto "
+ + "the phone. The Android Dev Phones are carrier-independent, and available for "
+ + "purchase by developers through their Android Market publisher accounts.</p><p> "
+ + "<a href='http://market.android.com/publish'>Visit Android Market "
+ + "to learn more &raquo;</a></p>"
     },
 
     'mapskey': {
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index d4b6db5..ec47796 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,8 +52,9 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="460"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.3,18.9,22.1,55.5,3.3&chl=Other*|
-Android%201.5|Android%201.6|Android%202.1|Android%202.2&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:15.3,20.3,0.2,59.7,4.5&chl=
+Android%201.5|Android%201.6|Other*|Android%202.1|Android%202.2&chco=c4df9b,
+6fad0c" />
 
 <table>
 <tr>
@@ -61,14 +62,14 @@
   <th>API Level</th>
   <th>Distribution</th>
 </tr>
-<tr><td>Android 1.5</td><td>3</td><td>18.9%</td></tr>
-<tr><td>Android 1.6</td><td>4</td><td>22.1%</td></tr>
-<tr><td>Android 2.1</td><td>7</td><td>55.5%</td></tr>
-<tr><td>Android 2.2</td><td>8</td><td>3.3%</td></tr>
+<tr><td>Android 1.5</td><td>3</td><td>15.3%</td></tr>
+<tr><td>Android 1.6</td><td>4</td><td>20.3%</td></tr>
+<tr><td>Android 2.1</td><td>7</td><td>59.7%</td></tr>
+<tr><td>Android 2.2</td><td>8</td><td>4.5%</td></tr>
 </table>
 
-<p><em>Data collected during two weeks ending on July 15, 2010</em></p>
-<p style="font-size:.9em">* <em>Other: 0.3% of devices running obsolete versions</em></p>
+<p><em>Data collected during two weeks ending on August 2, 2010</em></p>
+<p style="font-size:.9em">* <em>Other: 0.2% of devices running obsolete versions</em></p>
 
 </div><!-- end dashboard-panel -->
 
@@ -94,21 +95,20 @@
 
 <div class="dashboard-panel">
 
-<img alt="" height="265" width="700" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=700x265&chxt=x,y,r&chxr=0,0,10%7C1,0,100%7C2,0,
-100&chxl=0%3A%7C2010/02/01%7C02/15%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%
-7C2010/07/01%7C1%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%
-7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10&chxtc=0,5&chd=t:99.0,99.2,99.4,99.5,99.6,99.6,99.6,99.7,100.6
-,101.1,99.9%7C63.4,62.5,61.6,60.6,61.5,61.7,62.3,63.5,73.0,76.4,78.6%7C22.6,23.2,24.3,25.4,29.4,30.2
-,32.7,35.3,46.2,51.3,55.1%7C0.0,0.0,0.0,0.0,4.0,28.3,32.0,34.9,45.9,51.0,54.9%7C0.0,0.0,0.0,0.0,0.0,
-0.0,0.0,0.0,0.8,1.2,1.8&chm=tAndroid%201.5,7caa36,0,0,15,,t::-5%7Cb,c3df9b,0,1,0%7CtAndroid%201.6,
-638d23,1,0,15,,t::-5%7Cb,b0db6e,1,2,0%7CtAndroid%202.0.1,496c13,2,0,15,,t::-5%7Cb,9ddb3d,2,3,0%
-7CtAndroid%202.1,2f4708,3,5,15,,t::-5%7Cb,89cf19,3,4,0%7CB,6fad0c,4,5,0&chg=9,25&chdl=Android%201.5%
-20(API%20Level%203)%7CAndroid%201.6%20(API%20Level%204)%7CAndroid%202.0.1%20(API%20Level%206)%
-7CAndroid%202.1%20(API%20Level%207)%7CAndroid%202.2%20(API%20Level %208)&chco=add274,
-9ad145,84c323,6ba213,507d08" />
+<img alt="" height="250" width="660" style="padding:5px;background:#fff"
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,y,r&chxr=0,0,12|1,0,100|2,0,100&
+chxl=0%3A%7C2010/02/01%7C02/15%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/
+01%7C07/15%7C2010/08/01%7C1%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C2%3A%7C0%25%7C25%25%7C50%25
+%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.0,99.2,99.4,99.5,99.6,99.6,
+99.6,99.7,100.6,101.1,99.9,100.0,100.0|63.4,62.5,61.6,60.6,61.5,61.7,62.3,63.5,73.0,76.4,78.6,81.1,
+84.5|22.6,23.2,24.3,25.4,29.4,30.2,32.7,35.3,46.2,51.3,55.1,59.0,64.1|0.0,0.0,0.0,0.0,4.0,28.3,32.0,
+34.9,45.9,51.0,54.9,58.8,64.0|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.8,1.2,1.8,3.3,4.3&chm=tAndroid%201.5
+,7caa36,0,0,15,,t::-5|b,c3df9b,0,1,0|tAndroid%201.6,638d23,1,0,15,,t::-5|b,b0db6e,1,2,0|tAndroid%202
+.0.1,496c13,2,0,15,,t::-5|b,9ddb3d,2,3,0|tAndroid%202.1,2f4708,3,5,15,,t::-5|b,89cf19,3,4,0|B,6fad0c
+,4,5,0&chg=7,25&chdl=Android%201.5|Android%201.6|Android%202.0.1|Android%202.1|Android%202.2&chco=
+add274,9ad145,84c323,6ba213,507d08" />
 
-<p><em>Last historical dataset collected during two weeks ending on July 1, 2010</em></p>
+<p><em>Last historical dataset collected during two weeks ending on August 2, 2010</em></p>
 
 
 </div><!-- end dashboard-panel -->
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index b20b17d..90f3f1a 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -49,8 +49,8 @@
 <div class="dashboard-panel">
 
 <img alt="" width="460" height="250"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.8,51.5,46.6&chl=Small%20/%20ldpi|
-Normal%20/%20mdpi|Normal%20/%20hdpi&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:2.3,0.4,45.9,51.2&chl=Small%20/%
+20ldpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Normal%20/%20hdpi&chco=c4df9b,6fad0c" />
 
 <table>
 <tr>
@@ -60,22 +60,22 @@
 <th scope="col">High Density</th>
 </tr>
 <tr><th scope="row">Small</th> 
-<td class='cent hi'>1.8%</td> 
+<td class='cent hi'>2.3%</td> 
 <td></td> 
 <td></td> 
 </tr> 
 <tr><th scope="row">Normal</th> 
-<td></td> 
-<td class='cent hi'>51.5%</td> 
-<td class='cent hi'>46.6%</td> 
+<td class='cent '>0.4%</td> 
+<td class='cent hi'>45.9%</td> 
+<td class='cent hi'>51.2%</td> 
 </tr> 
 <tr><th scope="row">Large</th> 
 <td></td> 
 <td></td> 
 <td></td> 
-</tr>
+</tr> 
 </table>
 
-<p><em>Data collected during two weeks ending on July 15, 2010</em></p>
+<p><em>Data collected during two weeks ending on August 2, 2010</em></p>
 </div>
 
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 628200d..f1d45d2 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -57,11 +57,10 @@
 
     bool mCollectStats;
     bool mTrackMaxAmplitude;
-    int64_t mTotalReadTimeUs;
-    int64_t mTotalReadBytes;
-    int64_t mTotalReads;
     int64_t mStartTimeUs;
     int16_t mMaxAmplitude;
+    int64_t mPrevSampleTimeUs;
+    int64_t mNumLostFrames;
 
     MediaBufferGroup *mGroup;
 
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 50c0edc..99978e8 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -26,8 +26,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 #include <cutils/properties.h>
-#include <sys/time.h>
-#include <time.h>
+#include <stdlib.h>
 
 namespace android {
 
@@ -35,9 +34,8 @@
         int inputSource, uint32_t sampleRate, uint32_t channels)
     : mStarted(false),
       mCollectStats(false),
-      mTotalReadTimeUs(0),
-      mTotalReadBytes(0),
-      mTotalReads(0),
+      mPrevSampleTimeUs(0),
+      mNumLostFrames(0),
       mGroup(NULL) {
 
     LOGV("sampleRate: %d, channels: %d", sampleRate, channels);
@@ -110,10 +108,7 @@
     mStarted = false;
 
     if (mCollectStats) {
-        LOGI("%lld reads: %.2f bps in %lld us",
-                mTotalReads,
-                (mTotalReadBytes * 8000000.0) / mTotalReadTimeUs,
-                mTotalReadTimeUs);
+        LOGI("Total lost audio frames: %lld", mNumLostFrames);
     }
 
     return OK;
@@ -129,67 +124,113 @@
     return meta;
 }
 
+/*
+ * Returns -1 if frame skipping request is too long.
+ * Returns  0 if there is no need to skip frames.
+ * Returns  1 if we need to skip frames.
+ */
+static int skipFrame(int64_t timestampUs,
+        const MediaSource::ReadOptions *options) {
+
+    int64_t skipFrameUs;
+    if (!options || !options->getSkipFrame(&skipFrameUs)) {
+        return 0;
+    }
+
+    if (skipFrameUs <= timestampUs) {
+        return 0;
+    }
+
+    // Safe guard against the abuse of the kSkipFrame_Option.
+    if (skipFrameUs - timestampUs >= 1E6) {
+        LOGE("Frame skipping requested is way too long: %lld us",
+            skipFrameUs - timestampUs);
+
+        return -1;
+    }
+
+    LOGV("skipFrame: %lld us > timestamp: %lld us",
+        skipFrameUs, timestampUs);
+
+    return 1;
+
+}
+
 status_t AudioSource::read(
         MediaBuffer **out, const ReadOptions *options) {
     *out = NULL;
-    ++mTotalReads;
 
     MediaBuffer *buffer;
     CHECK_EQ(mGroup->acquire_buffer(&buffer), OK);
 
+    int err = 0;
     while (mStarted) {
+
         uint32_t numFramesRecorded;
         mRecord->getPosition(&numFramesRecorded);
-        int64_t latency = mRecord->latency() * 1000;
 
-        int64_t readTime = systemTime() / 1000;
 
-        if (numFramesRecorded == 0) {
+        if (numFramesRecorded == 0 && mPrevSampleTimeUs == 0) {
             // Initial delay
             if (mStartTimeUs > 0) {
-                mStartTimeUs = readTime - mStartTimeUs;
+                mStartTimeUs = systemTime() / 1000 - mStartTimeUs;
             } else {
-                mStartTimeUs += latency;
+                // Assume latency is constant.
+                mStartTimeUs += mRecord->latency() * 1000;
             }
-        }
-
-        ssize_t n = 0;
-        if (mCollectStats) {
-            n = mRecord->read(buffer->data(), buffer->size());
-            int64_t endTime = systemTime() / 1000;
-            mTotalReadTimeUs += (endTime - readTime);
-            if (n >= 0) {
-                mTotalReadBytes += n;
-            }
-        } else {
-            n = mRecord->read(buffer->data(), buffer->size());
-        }
-
-        if (n < 0) {
-            buffer->release();
-            buffer = NULL;
-
-            return (status_t)n;
+            mPrevSampleTimeUs = mStartTimeUs;
         }
 
         uint32_t sampleRate = mRecord->getSampleRate();
-        int64_t timestampUs = (1000000LL * numFramesRecorded) / sampleRate +
-                                 mStartTimeUs;
-        int64_t skipFrameUs;
-        if (!options || !options->getSkipFrame(&skipFrameUs)) {
-            skipFrameUs = timestampUs;  // Don't skip frame
-        }
 
-        if (skipFrameUs > timestampUs) {
-            // Safe guard against the abuse of the kSkipFrame_Option.
-            if (skipFrameUs - timestampUs >= 1E6) {
-                LOGE("Frame skipping requested is way too long: %lld us",
-                    skipFrameUs - timestampUs);
+        // Insert null frames when lost frames are detected.
+        int64_t timestampUs = mPrevSampleTimeUs;
+        uint32_t numLostBytes = mRecord->getInputFramesLost() << 1;
+#if 0
+        // Simulate lost frames
+        numLostBytes = ((rand() * 1.0 / RAND_MAX)) * kMaxBufferSize;
+        numLostBytes &= 0xFFFFFFFE; // Alignment request
+
+        // Reduce the chance to lose
+        if (rand() * 1.0 / RAND_MAX >= 0.05) {
+            numLostBytes = 0;
+        }
+#endif
+        if (numLostBytes > 0) {
+            // Not expect too many lost frames!
+            CHECK(numLostBytes <= kMaxBufferSize);
+
+            timestampUs += (1000000LL * numLostBytes >> 1) / sampleRate;
+            CHECK(timestampUs > mPrevSampleTimeUs);
+            if (mCollectStats) {
+                mNumLostFrames += (numLostBytes >> 1);
+            }
+            if ((err = skipFrame(timestampUs, options)) == -1) {
                 buffer->release();
                 return UNKNOWN_ERROR;
+            } else if (err != 0) {
+                continue;
             }
-            LOGV("skipFrame: %lld us > timestamp: %lld us, samples %d",
-                skipFrameUs, timestampUs, numFramesRecorded);
+            memset(buffer->data(), 0, numLostBytes);
+            buffer->set_range(0, numLostBytes);
+            buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
+            mPrevSampleTimeUs = timestampUs;
+            *out = buffer;
+            return OK;
+        }
+
+        ssize_t n = mRecord->read(buffer->data(), buffer->size());
+        if (n < 0) {
+            buffer->release();
+            return (status_t)n;
+        }
+
+        int64_t recordDurationUs = (1000000LL * n >> 1) / sampleRate;
+        timestampUs += recordDurationUs;
+        if ((err = skipFrame(timestampUs, options)) == -1) {
+            buffer->release();
+            return UNKNOWN_ERROR;
+        } else if (err != 0) {
             continue;
         }
 
@@ -197,7 +238,13 @@
             trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
         }
 
-        buffer->meta_data()->setInt64(kKeyTime, timestampUs);
+        buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
+        CHECK(timestampUs > mPrevSampleTimeUs);
+        if (mNumLostFrames == 0) {
+            CHECK_EQ(mPrevSampleTimeUs,
+                mStartTimeUs + (1000000LL * numFramesRecorded) / sampleRate);
+        }
+        mPrevSampleTimeUs = timestampUs;
         LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
                 mStartTimeUs, sampleRate, timestampUs);
 
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 8abd6499..b5c018f 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -6,9 +6,6 @@
 
 include $(CLEAR_VARS)
 
-# Set to 1 to use gralloc and copybits
-LIBAGL_USE_GRALLOC_COPYBITS := 1
-
 LOCAL_SRC_FILES:= \
 	egl.cpp                     \
 	state.cpp		            \
@@ -51,13 +48,6 @@
     LOCAL_C_INCLUDES += bionic/libc/private
 endif
 
-ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1)
-    LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS
-    LOCAL_SRC_FILES += copybit.cpp
-    LOCAL_SHARED_LIBRARIES += libui
-endif
-
-
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
 LOCAL_MODULE:= libGLES_android
 
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index 255ccac..bbb82fc 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -55,9 +55,6 @@
     memset(crop_rect, 0, sizeof(crop_rect));
     generate_mipmap = GL_FALSE;
     direct = GL_FALSE;
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    try_copybit = false;
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
     buffer = 0;
 }
 
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
index 279e040..70e3bef 100644
--- a/opengl/libagl/TextureObjectManager.h
+++ b/opengl/libagl/TextureObjectManager.h
@@ -80,9 +80,6 @@
     GLint               crop_rect[4];
     GLint               generate_mipmap;
     GLint               direct;
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    bool                try_copybit;
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
     android_native_buffer_t* buffer;
 };
 
diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
index 71825c5..4997dc8 100644
--- a/opengl/libagl/array.cpp
+++ b/opengl/libagl/array.cpp
@@ -26,9 +26,6 @@
 #include "primitives.h"
 #include "texture.h"
 #include "BufferObjectManager.h"
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include "copybit.h"
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 
 // ----------------------------------------------------------------------------
 
@@ -707,12 +704,6 @@
 
 void drawPrimitivesTriangleFan(ogles_context_t* c,
         GLint first, GLsizei count) {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (drawTriangleFanWithCopybit(c, first, count)) {
-        return;
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     drawPrimitivesTriangleFanOrStrip(c, first, count, 2);
 }
 
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
deleted file mode 100644
index 67d1ce7..0000000
--- a/opengl/libagl/copybit.cpp
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "context.h"
-#include "fp.h"
-#include "state.h"
-#include "matrix.h"
-#include "vertex.h"
-#include "light.h"
-#include "primitives.h"
-#include "texture.h"
-#include "BufferObjectManager.h"
-#include "TextureObjectManager.h"
-
-#include <hardware/gralloc.h>
-#include <hardware/copybit.h>
-#include <private/ui/android_natives_priv.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/Region.h>
-#include <ui/Rect.h>
-
-
-#define DEBUG_COPYBIT false
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-static void textureToCopyBitImage(
-        const GGLSurface* surface, int32_t opFormat, 
-        android_native_buffer_t* buffer, copybit_image_t* img)
-{
-    img->w      = surface->stride;
-    img->h      = surface->height;
-    img->format = opFormat;
-    img->base   = surface->data;
-    img->handle = (native_handle_t *)buffer->handle;
-}
-
-struct clipRectRegion : public copybit_region_t {
-    clipRectRegion(ogles_context_t* c) 
-    {
-        scissor_t const* scissor = &c->rasterizer.state.scissor;
-        r.l = scissor->left;
-        r.t = scissor->top;
-        r.r = scissor->right;
-        r.b = scissor->bottom;
-        next = iterate; 
-    }
-private:
-    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
-        *rect = static_cast<clipRectRegion const*>(self)->r;
-        const_cast<copybit_region_t *>(self)->next = iterate_done;
-        return 1;
-    }
-    static int iterate_done(copybit_region_t const *, copybit_rect_t*) {
-        return 0;
-    }
-public:
-    copybit_rect_t r;
-};
-
-static bool supportedCopybitsFormat(int format) {
-    switch (format) {
-    case COPYBIT_FORMAT_RGBA_8888:
-    case COPYBIT_FORMAT_RGBX_8888:
-    case COPYBIT_FORMAT_RGB_888:
-    case COPYBIT_FORMAT_RGB_565:
-    case COPYBIT_FORMAT_BGRA_8888:
-    case COPYBIT_FORMAT_RGBA_5551:
-    case COPYBIT_FORMAT_RGBA_4444:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static bool hasAlpha(int format) {
-    switch (format) {
-    case COPYBIT_FORMAT_RGBA_8888:
-    case COPYBIT_FORMAT_BGRA_8888:
-    case COPYBIT_FORMAT_RGBA_5551:
-    case COPYBIT_FORMAT_RGBA_4444:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static inline int fixedToByte(GGLfixed val) {
-    return (val - (val >> 8)) >> 8;
-}
-
-/**
- * Performs a quick check of the rendering state. If this function returns
- * false we cannot use the copybit driver.
- */
-
-static bool checkContext(ogles_context_t* c) {
-
-	// By convention copybitQuickCheckContext() has already returned true.
-	// avoid checking the same information again.
-	
-    if (c->copybits.blitEngine == NULL) {
-        LOGD_IF(DEBUG_COPYBIT, "no copybit hal");
-        return false;
-    }
-
-    if (c->rasterizer.state.enables
-                    & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) {
-        LOGD_IF(DEBUG_COPYBIT, "depth test and/or fog");
-        return false;
-    }
-
-    // Note: The drawSurfaceBuffer is only set for destination
-    // surfaces types that are supported by the hardware and
-    // do not have an alpha channel. So we don't have to re-check that here.
-
-    static const int tmu = 0;
-    texture_unit_t& u(c->textures.tmu[tmu]);
-    EGLTextureObject* textureObject = u.texture;
-
-    if (!supportedCopybitsFormat(textureObject->surface.format)) {
-        LOGD_IF(DEBUG_COPYBIT, "texture format not supported");
-        return false;
-    }
-    return true;
-}
-
-
-static bool copybit(GLint x, GLint y,
-        GLint w, GLint h,
-        EGLTextureObject* textureObject,
-        const GLint* crop_rect,
-        int transform,
-        ogles_context_t* c)
-{
-    status_t err = NO_ERROR;
-
-    // We assume checkContext has already been called and has already
-    // returned true.
-
-    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
-
-    y = cbSurface.height - (y + h);
-
-    const GLint Ucr = crop_rect[0];
-    const GLint Vcr = crop_rect[1];
-    const GLint Wcr = crop_rect[2];
-    const GLint Hcr = crop_rect[3];
-
-    GLint screen_w = w;
-    GLint screen_h = h;
-    int32_t dsdx = Wcr << 16;   // dsdx =  ((Wcr/screen_w)/Wt)*Wt
-    int32_t dtdy = Hcr << 16;   // dtdy = -((Hcr/screen_h)/Ht)*Ht
-    if (transform & COPYBIT_TRANSFORM_ROT_90) {
-        swap(screen_w, screen_h);
-    }
-    if (dsdx!=screen_w || dtdy!=screen_h) {
-        // in most cases the divide is not needed
-        dsdx /= screen_w;
-        dtdy /= screen_h;
-    }
-    dtdy = -dtdy; // see equation of dtdy above
-
-    // copybit doesn't say anything about filtering, so we can't
-    // discriminate. On msm7k, copybit will always filter.
-    // the code below handles min/mag filters, we keep it as a reference.
-    
-#ifdef MIN_MAG_FILTER
-    int32_t texelArea = gglMulx(dtdy, dsdx);
-    if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) {
-        // Non-linear filtering on a texture enlargement.
-        LOGD_IF(DEBUG_COPYBIT, "mag filter is not GL_LINEAR");
-        return false;
-    }
-    if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) {
-        // Non-linear filtering on an texture shrink.
-        LOGD_IF(DEBUG_COPYBIT, "min filter is not GL_LINEAR");
-        return false;
-    }
-#endif
-    
-    const uint32_t enables = c->rasterizer.state.enables;
-    int planeAlpha = 255;
-    bool alphaPlaneWorkaround = false;
-    static const int tmu = 0;
-    texture_t& tev(c->rasterizer.state.texture[tmu]);
-    int32_t opFormat = textureObject->surface.format;
-    const bool srcTextureHasAlpha = hasAlpha(opFormat);
-    if (!srcTextureHasAlpha) {
-        planeAlpha = fixedToByte(c->currentColorClamped.a);
-    }
-
-    const bool cbHasAlpha = hasAlpha(cbSurface.format);
-    bool blending = false;
-    if ((enables & GGL_ENABLE_BLENDING)
-            && !(c->rasterizer.state.blend.src == GL_ONE
-                    && c->rasterizer.state.blend.dst == GL_ZERO)) {
-        // Blending is OK if it is
-        // the exact kind of blending that the copybits hardware supports.
-        // Note: The hardware only supports
-        // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA,
-        // But the surface flinger uses GL_ONE / GL_ONE_MINUS_SRC_ALPHA.
-        // We substitute GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA in that case,
-        // because the performance is worth it, even if the results are
-        // not correct.
-        if (!((c->rasterizer.state.blend.src == GL_SRC_ALPHA
-                || c->rasterizer.state.blend.src == GL_ONE)
-                && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA
-                && c->rasterizer.state.blend.alpha_separate == 0)) {
-            // Incompatible blend mode.
-            LOGD_IF(DEBUG_COPYBIT, "incompatible blend mode");
-            return false;
-        }
-        blending = true;
-    } else {
-        if (cbHasAlpha) {
-            // NOTE: the result will be slightly wrong in this case because
-            // the destination alpha channel will be set to 1.0 instead of
-            // the iterated alpha value. *shrug*.
-        }
-        // disable plane blending and src blending for supported formats
-        planeAlpha = 255;
-        if (opFormat == COPYBIT_FORMAT_RGBA_8888) {
-            opFormat = COPYBIT_FORMAT_RGBX_8888;
-        } else {
-            if (srcTextureHasAlpha) {
-                LOGD_IF(DEBUG_COPYBIT, "texture format requires blending");
-                return false;
-            }
-        }
-    }
-
-    switch (tev.env) {
-    case GGL_REPLACE:
-        break;
-    case GGL_MODULATE:
-        // only cases allowed is:
-        // RGB  source, color={1,1,1,a} -> can be done with GL_REPLACE
-        // RGBA source, color={1,1,1,1} -> can be done with GL_REPLACE
-        if (blending) {
-            if (c->currentColorClamped.r == c->currentColorClamped.a &&
-                c->currentColorClamped.g == c->currentColorClamped.a &&
-                c->currentColorClamped.b == c->currentColorClamped.a) {
-                // TODO: RGBA source, color={1,1,1,a} / regular-blending
-                // is equivalent
-                alphaPlaneWorkaround = true;
-                break;
-            }
-        }
-        LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE");
-        return false;
-    default:
-        // Incompatible texture environment.
-        LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment");
-        return false;
-    }
-
-    copybit_device_t* copybit = c->copybits.blitEngine;
-    copybit_image_t src;
-    textureToCopyBitImage(&textureObject->surface, opFormat,
-            textureObject->buffer, &src);
-    copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
-
-    /*
-     *  Below we perform extra passes needed to emulate things the h/w
-     * cannot do.
-     */
-
-    const GLfixed minScaleInv = gglDivQ(0x10000, c->copybits.minScale, 16);
-    const GLfixed maxScaleInv = gglDivQ(0x10000, c->copybits.maxScale, 16);
-
-    sp<GraphicBuffer> tempBitmap;
-
-    if (dsdx < maxScaleInv || dsdx > minScaleInv ||
-        dtdy < maxScaleInv || dtdy > minScaleInv)
-    {
-        // The requested scale is out of the range the hardware
-        // can support.
-        LOGD_IF(DEBUG_COPYBIT,
-                "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
-                "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
-                dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
-
-        int32_t xscale=0x10000, yscale=0x10000;
-        if (dsdx > minScaleInv)         xscale = c->copybits.minScale;
-        else if (dsdx < maxScaleInv)    xscale = c->copybits.maxScale;
-        if (dtdy > minScaleInv)         yscale = c->copybits.minScale;
-        else if (dtdy < maxScaleInv)    yscale = c->copybits.maxScale;
-        dsdx = gglMulx(dsdx, xscale);
-        dtdy = gglMulx(dtdy, yscale);
-
-        /* we handle only one step of resizing below. Handling an arbitrary
-         * number is relatively easy (replace "if" above by "while"), but requires
-         * two intermediate buffers and so far we never had the need.
-         */
-
-        if (dsdx < maxScaleInv || dsdx > minScaleInv ||
-            dtdy < maxScaleInv || dtdy > minScaleInv) {
-            LOGD_IF(DEBUG_COPYBIT,
-                    "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
-                    "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
-                    dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
-            return false;
-        }
-
-        const int tmp_w = gglMulx(srect.r - srect.l, xscale, 16);
-        const int tmp_h = gglMulx(srect.b - srect.t, yscale, 16);
-
-        LOGD_IF(DEBUG_COPYBIT,
-                "xscale=%08x, yscale=%08x, dsdx=%08x, dtdy=%08x, tmp_w=%d, tmp_h=%d",
-                xscale, yscale, dsdx, dtdy, tmp_w, tmp_h);
-
-        tempBitmap = new GraphicBuffer(
-                    tmp_w, tmp_h, src.format,
-                    GraphicBuffer::USAGE_HW_2D);
-
-        err = tempBitmap->initCheck();
-        if (err == NO_ERROR) {
-            copybit_image_t tmp_dst;
-            copybit_rect_t tmp_rect;
-            tmp_dst.w = tmp_w;
-            tmp_dst.h = tmp_h;
-            tmp_dst.format = tempBitmap->format;
-            tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle;
-            tmp_rect.l = 0;
-            tmp_rect.t = 0;
-            tmp_rect.r = tmp_dst.w;
-            tmp_rect.b = tmp_dst.h;
-            region_iterator tmp_it(Region(Rect(tmp_rect.r, tmp_rect.b)));
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-            err = copybit->stretch(copybit,
-                    &tmp_dst, &src, &tmp_rect, &srect, &tmp_it);
-            src = tmp_dst;
-            srect = tmp_rect;
-        }
-    }
-
-    copybit_image_t dst;
-    textureToCopyBitImage(&cbSurface, cbSurface.format,
-            c->copybits.drawSurfaceBuffer, &dst);
-    copybit_rect_t drect = {x, y, x+w, y+h};
-
-
-    /* and now the alpha-plane hack. This handles the "Fade" case of a
-     * texture with an alpha channel.
-     */
-    if (alphaPlaneWorkaround) {
-        sp<GraphicBuffer> tempCb = new GraphicBuffer(
-                    w, h, COPYBIT_FORMAT_RGB_565,
-                    GraphicBuffer::USAGE_HW_2D);
-
-        err = tempCb->initCheck();
-
-        copybit_image_t tmpCbImg;
-        copybit_rect_t tmpCbRect;
-        copybit_rect_t tmpdrect = drect;
-        tmpCbImg.w = w;
-        tmpCbImg.h = h;
-        tmpCbImg.format = tempCb->format;
-        tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle;
-        tmpCbRect.l = 0;
-        tmpCbRect.t = 0;
-
-        if (drect.l < 0) {
-            tmpCbRect.l = -tmpdrect.l;
-            tmpdrect.l = 0;
-        }
-        if (drect.t < 0) {
-            tmpCbRect.t = -tmpdrect.t;
-            tmpdrect.t = 0;
-        }
-        if (drect.l + tmpCbImg.w > dst.w) {
-            tmpCbImg.w = dst.w - drect.l;
-            tmpdrect.r = dst.w;
-        }
-        if (drect.t + tmpCbImg.h > dst.h) {
-            tmpCbImg.h = dst.h - drect.t;
-            tmpdrect.b = dst.h;
-        }
-
-        tmpCbRect.r = tmpCbImg.w;
-        tmpCbRect.b = tmpCbImg.h;
-
-        if (!err) {
-            // first make a copy of the destination buffer
-            region_iterator tmp_it(Region(Rect(w, h)));
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-            err = copybit->stretch(copybit,
-                    &tmpCbImg, &dst, &tmpCbRect, &tmpdrect, &tmp_it);
-        }
-        if (!err) {
-            // then proceed as usual, but without the alpha plane
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER,
-                    (enables & GGL_ENABLE_DITHER) ?
-                            COPYBIT_ENABLE : COPYBIT_DISABLE);
-            clipRectRegion it(c);
-            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-        }
-        if (!err) {
-            // finally copy back the destination on top with 1-alphaplane
-            int invPlaneAlpha = 0xFF - fixedToByte(c->currentColorClamped.a);
-            clipRectRegion it(c);
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-            err = copybit->stretch(copybit,
-                    &dst, &tmpCbImg, &tmpdrect, &tmpCbRect, &it);
-        }
-    } else {
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
-        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
-        copybit->set_parameter(copybit, COPYBIT_DITHER,
-                (enables & GGL_ENABLE_DITHER) ?
-                        COPYBIT_ENABLE : COPYBIT_DISABLE);
-        clipRectRegion it(c);
-
-        LOGD_IF(0,
-             "dst={%d, %d, %d, %p, %p}, "
-             "src={%d, %d, %d, %p, %p}, "
-             "drect={%d,%d,%d,%d}, "
-             "srect={%d,%d,%d,%d}, "
-             "it={%d,%d,%d,%d}, " ,
-             dst.w, dst.h, dst.format, dst.base, dst.handle,
-             src.w, src.h, src.format, src.base, src.handle,
-             drect.l, drect.t, drect.r, drect.b,
-             srect.l, srect.t, srect.r, srect.b,
-             it.r.l, it.r.t, it.r.r, it.r.b
-        );
-
-        err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-    }
-    if (err != NO_ERROR) {
-        c->textures.tmu[0].texture->try_copybit = false;
-    }
-    return err == NO_ERROR ? true : false;
-}
-
-/*
- * Try to draw a triangle fan with copybit, return false if we fail.
- */
-bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count)
-{
-    if (!checkContext(c)) {
-        return false;
-    }
-
-    // FIXME: we should handle culling  here
-    c->arrays.compileElements(c, c->vc.vBuffer, 0, 4);
-
-    // we detect if we're dealing with a rectangle, by comparing the
-    // rectangles {v0,v2} and {v1,v3} which should be identical.
-    
-    // NOTE: we should check that the rectangle is window aligned, however
-    // if we do that, the optimization won't be taken in a lot of cases.
-    // Since this code is intended to be used with SurfaceFlinger only,
-    // so it's okay...
-    
-    const vec4_t& v0 = c->vc.vBuffer[0].window;
-    const vec4_t& v1 = c->vc.vBuffer[1].window;
-    const vec4_t& v2 = c->vc.vBuffer[2].window;
-    const vec4_t& v3 = c->vc.vBuffer[3].window;
-    int l = min(v0.x, v2.x);
-    int b = min(v0.y, v2.y);
-    int r = max(v0.x, v2.x);
-    int t = max(v0.y, v2.y);
-    if ((l != min(v1.x, v3.x)) || (b != min(v1.y, v3.y)) ||
-        (r != max(v1.x, v3.x)) || (t != max(v1.y, v3.y))) {
-        LOGD_IF(DEBUG_COPYBIT, "geometry not a rectangle");
-        return false;
-    }
-
-    // fetch and transform texture coordinates
-    // NOTE: maybe it would be better to have a "compileElementsAll" method
-    // that would ensure all vertex data are fetched and transformed
-    const transform_t& tr = c->transforms.texture[0].transform; 
-    for (size_t i=0 ; i<4 ; i++) {
-        const GLubyte* tp = c->arrays.texture[0].element(i);
-        vertex_t* const v = &c->vc.vBuffer[i];
-        c->arrays.texture[0].fetch(c, v->texture[0].v, tp);
-        // FIXME: we should bail if q!=1
-        c->arrays.tex_transform[0](&tr, &v->texture[0], &v->texture[0]);
-    }
-    
-    const vec4_t& t0 = c->vc.vBuffer[0].texture[0];
-    const vec4_t& t1 = c->vc.vBuffer[1].texture[0];
-    const vec4_t& t2 = c->vc.vBuffer[2].texture[0];
-    const vec4_t& t3 = c->vc.vBuffer[3].texture[0];
-    int txl = min(t0.x, t2.x);
-    int txb = min(t0.y, t2.y);
-    int txr = max(t0.x, t2.x);
-    int txt = max(t0.y, t2.y);
-    if ((txl != min(t1.x, t3.x)) || (txb != min(t1.y, t3.y)) ||
-        (txr != max(t1.x, t3.x)) || (txt != max(t1.y, t3.y))) {
-        LOGD_IF(DEBUG_COPYBIT, "texcoord not a rectangle");
-        return false;
-    }
-    if ((txl != 0) || (txb != 0) ||
-        (txr != FIXED_ONE) || (txt != FIXED_ONE)) {
-        // we could probably handle this case, if we wanted to
-        LOGD_IF(DEBUG_COPYBIT, "texture is cropped: %08x,%08x,%08x,%08x",
-                txl, txb, txr, txt);
-        return false;
-    }
-
-    // at this point, we know we are dealing with a rectangle, so we 
-    // only need to consider 3 vertices for computing the jacobians
-    
-    const int dx01 = v1.x - v0.x;
-    const int dx02 = v2.x - v0.x;
-    const int dy01 = v1.y - v0.y;
-    const int dy02 = v2.y - v0.y;
-    const int ds01 = t1.S - t0.S;
-    const int ds02 = t2.S - t0.S;
-    const int dt01 = t1.T - t0.T;
-    const int dt02 = t2.T - t0.T;
-    const int area = dx01*dy02 - dy01*dx02;
-    int dsdx, dsdy, dtdx, dtdy;
-    if (area >= 0) {
-        dsdx = ds01*dy02 - ds02*dy01;
-        dtdx = dt01*dy02 - dt02*dy01;
-        dsdy = ds02*dx01 - ds01*dx02;
-        dtdy = dt02*dx01 - dt01*dx02;
-    } else {
-        dsdx = ds02*dy01 - ds01*dy02;
-        dtdx = dt02*dy01 - dt01*dy02;
-        dsdy = ds01*dx02 - ds02*dx01;
-        dtdy = dt01*dx02 - dt02*dx01;
-    }
-
-    // here we rely on the fact that we know the transform is
-    // a rigid-body transform AND that it can only rotate in 90 degrees
-    // increments
-
-    int transform = 0;
-    if (dsdx == 0) {
-        // 90 deg rotation case
-        // [ 0    dtdx  ]
-        // [ dsdx    0  ]
-        transform |= COPYBIT_TRANSFORM_ROT_90;
-        // FIXME: not sure if FLIP_H and FLIP_V shouldn't be inverted
-        if (dtdx > 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_H;
-        if (dsdy < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_V;
-    } else {
-        // [ dsdx    0  ]
-        // [ 0     dtdy ]
-        if (dsdx < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_H;
-        if (dtdy < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_V;
-    }
-
-    //LOGD("l=%d, b=%d, w=%d, h=%d, tr=%d", x, y, w, h, transform);
-    //LOGD("A=%f\tB=%f\nC=%f\tD=%f",
-    //      dsdx/65536.0, dtdx/65536.0, dsdy/65536.0, dtdy/65536.0);
-
-    int x = l >> 4;
-    int y = b >> 4;
-    int w = (r-l) >> 4;
-    int h = (t-b) >> 4;
-    texture_unit_t& u(c->textures.tmu[0]);
-    EGLTextureObject* textureObject = u.texture;
-    GLint tWidth = textureObject->surface.width;
-    GLint tHeight = textureObject->surface.height;
-    GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight};
-    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
-    y = cbSurface.height - (y + h);
-    return copybit(x, y, w, h, textureObject, crop_rect, transform, c);
-}
-
-/*
- * Try to drawTexiOESWithCopybit, return false if we fail.
- */
-
-bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c)
-{
-    // quickly process empty rects
-    if ((w|h) <= 0) {
-        return true;
-    }
-    if (!checkContext(c)) {
-        return false;
-    }
-    texture_unit_t& u(c->textures.tmu[0]);
-    EGLTextureObject* textureObject = u.texture;
-    return copybit(x, y, w, h, textureObject, textureObject->crop_rect, 0, c);
-}
-
-} // namespace android
-
diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h
deleted file mode 100644
index b8b5afd..0000000
--- a/opengl/libagl/copybit.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef ANDROID_OPENGLES_COPYBIT_H
-#define ANDROID_OPENGLES_COPYBIT_H
-
-#include <stdlib.h>
-
-#include <GLES/gl.h>
-
-#include "TextureObjectManager.h"
-namespace android {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-
-bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c);
-
-bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first,
-        GLsizei count);
-
-inline bool copybitQuickCheckContext(ogles_context_t* c) {
-        return  c->copybits.drawSurfaceBuffer != 0
-            && c->rasterizer.state.enabled_tmu == 1
-            && c->textures.tmu[0].texture->try_copybit;
-}
-
-/*
- * Tries to draw a drawTexiOES using copybit hardware.
- * Returns true if successful.
- */
-inline bool drawTexiOESWithCopybit(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c) {
-    if (!copybitQuickCheckContext(c)) {
-    	return false;
-   	}
-   	
-   	return drawTexiOESWithCopybit_impl(x, y, z, w, h, c);
-}
-
-/*
- * Tries to draw a triangle fan using copybit hardware.
- * Returns true if successful.
- */
-inline bool drawTriangleFanWithCopybit(ogles_context_t* c, GLint first,
-        GLsizei count) {
-    /*
-     * We are looking for the glDrawArrays call made by SurfaceFlinger.
-     */
-
-    if ((count!=4) || first || !copybitQuickCheckContext(c))
-        return false;
-    
-    return drawTriangleFanWithCopybit_impl(c, first, count);
-}
-
-
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
-} // namespace android
-
-#endif // ANDROID_OPENGLES_COPYBIT_H
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 54d7307..5bbe441 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -628,23 +628,6 @@
     return buffer;
 }
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-
-static bool supportedCopybitsDestinationFormat(int format) {
-    // Hardware supported
-    switch (format) {
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-        return true;
-    }
-    return false;
-}
-#endif
-
 EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
@@ -658,18 +641,6 @@
     if (depth.data != gl->rasterizer.state.buffers.depth.data)
         gl->rasterizer.procs.depthBuffer(gl, &depth);
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    gl->copybits.drawSurfaceBuffer = 0;
-    if (gl->copybits.blitEngine != NULL) {
-        if (supportedCopybitsDestinationFormat(buffer.format)) {
-            buffer_handle_t handle = this->buffer->handle;
-            if (handle != NULL) {
-                gl->copybits.drawSurfaceBuffer = this->buffer;
-            }
-        }
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     return EGL_TRUE;
 }
 EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl)
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
index 27bb545..a0f720a 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -28,10 +28,6 @@
 #include "BufferObjectManager.h"
 #include "TextureObjectManager.h"
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include <hardware/copybit.h>
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -101,35 +97,6 @@
     // OpenGL enables dithering by default
     c->rasterizer.procs.enable(c, GL_DITHER);
 
-    c->copybits.blitEngine = NULL;
-    c->copybits.minScale = 0;
-    c->copybits.maxScale = 0;
-    c->copybits.drawSurfaceBuffer = 0;
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    hw_module_t const* module;
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        struct copybit_device_t* copyBits;
-        if (copybit_open(module, &copyBits) == 0) {
-            c->copybits.blitEngine = copyBits;
-            {
-                int minLim = copyBits->get(copyBits,
-                        COPYBIT_MINIFICATION_LIMIT);
-                if (minLim != -EINVAL && minLim > 0) {
-                    c->copybits.minScale = (1 << 16) / minLim;
-                }
-            }
-            {
-                int magLim = copyBits->get(copyBits,
-                        COPYBIT_MAGNIFICATION_LIMIT);
-                if (magLim != -EINVAL && magLim > 0) {
-                    c->copybits.maxScale = min(32*1024-1, magLim) << 16;
-                }
-            }
-        }
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     return c;
 }
 
@@ -144,11 +111,6 @@
     c->bufferObjectManager->decStrong(c);
     ggl_uninit_context(&(c->rasterizer));
     free(c->rasterizer.base);
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (c->copybits.blitEngine != NULL) {
-        copybit_close((struct copybit_device_t*) c->copybits.blitEngine);
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void _ogles_error(ogles_context_t* c, GLenum error)
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index d67612e..eb96895 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -26,10 +26,6 @@
 #include <private/ui/android_natives_priv.h>
 #include <ETC1/etc1.h>
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include "copybit.h"
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -763,17 +759,10 @@
 static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
         ogles_context_t* c)
 {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (drawTexiOESWithCopybit(gglFixedToIntRound(x),
-            gglFixedToIntRound(y), gglFixedToIntRound(z),
-            gglFixedToIntRound(w), gglFixedToIntRound(h), c)) {
-        return;
-    }
-#else
     // quickly reject empty rects
     if ((w|h) <= 0)
         return;
-#endif
+
     drawTexxOESImp(x, y, z, w, h, c);
 }
 
@@ -785,11 +774,6 @@
     // which is a lot faster.
 
     if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-        if (drawTexiOESWithCopybit(x, y, z, w, h, c)) {
-            return;
-        }
-#endif
         const int tmu = 0;
         texture_unit_t& u(c->textures.tmu[tmu]);
         EGLTextureObject* textureObject = u.texture;
@@ -797,9 +781,7 @@
         const GLint Hcr = textureObject->crop_rect[3];
 
         if ((w == Wcr) && (h == -Hcr)) {
-#ifndef LIBAGL_USE_GRALLOC_COPYBITS
             if ((w|h) <= 0) return; // quickly reject empty rects
-#endif
 
             if (u.dirty) {
                 c->rasterizer.procs.activeTexture(c, tmu);
@@ -1646,13 +1628,6 @@
     // bind it to the texture unit
     sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
     tex->setImage(native_buffer);
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    tex->try_copybit = false;
-    if (c->copybits.blitEngine != NULL) {
-        tex->try_copybit = true;
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 6eaf0cc..f1c6532 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -125,8 +125,6 @@
             metrics.setToDefaults();
             PackageParser.PackageLite pkg = packageParser.parsePackageLite(
                     archiveFilePath, 0);
-            ret.packageName = pkg.packageName;
-            ret.installLocation = pkg.installLocation;
             // Nuke the parser reference right away and force a gc
             packageParser = null;
             Runtime.getRuntime().gc();
@@ -136,6 +134,7 @@
                 return ret;
             }
             ret.packageName = pkg.packageName;
+            ret.installLocation = pkg.installLocation;
             ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation, archiveFilePath, flags);
             return ret;
         }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 75045d7..0fccbe7 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -7,6 +7,7 @@
     <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
 
     <application
+        android:persistent="true"
         android:allowClearUserData="false"
         android:label="@string/app_label"
         android:icon="@drawable/ic_launcher_settings">
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 5615232..4940311 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -5514,7 +5514,7 @@
                 throw new SecurityException(
                         "Injecting to another application requires INJECT_EVENTS permission");
             case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
-                Slog.v(TAG, "Input event injection succeeded.");
+                //Slog.v(TAG, "Input event injection succeeded.");
                 return true;
             case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
                 Slog.w(TAG, "Input event injection timed out.");
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index a60d2be..03194ff 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -135,9 +135,9 @@
         }
 
         // TODO: We don't check for SecurityException here (requires
-        // READ_PHONE_STATE permission).
+        // CALL_PRIVILEGED permission).
         if (scheme.equals("voicemail")) {
-            return TelephonyManager.getDefault().getVoiceMailNumber();
+            return TelephonyManager.getDefault().getCompleteVoiceMailNumber();
         }
 
         if (context == null) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ab63017..aa916e0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -665,6 +665,25 @@
     }
 
     /**
+     * Returns the complete voice mail number. Return null if it is unavailable.
+     * <p>
+     * Requires Permission:
+     *   {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED}
+     *
+     * @hide
+     */
+    public String getCompleteVoiceMailNumber() {
+        try {
+            return getSubscriberInfo().getCompleteVoiceMailNumber();
+        } catch (RemoteException ex) {
+            return null;
+        } catch (NullPointerException ex) {
+            // This could happen before phone restarts due to crashing
+            return null;
+        }
+    }
+
+    /**
      * Returns the voice mail count. Return 0 if unavailable.
      * <p>
      * Requires Permission:
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
new file mode 100644
index 0000000..9822694
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -0,0 +1,983 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RegistrantList;
+import android.telephony.PhoneStateListener;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @hide
+ *
+ * CallManager class provides an abstract layer for PhoneApp to access
+ * and control calls. It implements Phone interface.
+ *
+ * CallManager provides call and connection control as well as
+ * channel capability.
+ *
+ * There are three categories of APIs CallManager provided
+ *
+ *  1. Call control and operation, such as dial() and hangup()
+ *  2. Channel capabilities, such as CanConference()
+ *  3. Register notification
+ *
+ *
+ */
+public final class CallManager {
+
+    private static final int EVENT_DISCONNECT = 100;
+    private static final int EVENT_CALL_STATE_CHANGED = 101;
+
+
+    // Singleton instance
+    private static final CallManager INSTANCE = new CallManager();
+
+    // list of registered phones
+    private final ArrayList<Phone> mPhones;
+
+    // list of supported ringing calls
+    private final ArrayList<Call> mRingingCalls;
+
+    // list of supported background calls
+    private final ArrayList<Call> mBackgroundCalls;
+
+    // list of supported foreground calls
+    private final ArrayList<Call> mForegroundCalls;
+
+    // empty connection list
+    private final ArrayList<Connection> emptyConnections = new ArrayList<Connection>();
+
+    // default phone as the first phone registered
+    private Phone mDefaultPhone;
+
+    // state registrants
+    protected final RegistrantList mPreciseCallStateRegistrants
+    = new RegistrantList();
+
+    protected final RegistrantList mNewRingingConnectionRegistrants
+    = new RegistrantList();
+
+    protected final RegistrantList mIncomingRingRegistrants
+    = new RegistrantList();
+
+    protected final RegistrantList mDisconnectRegistrants
+    = new RegistrantList();
+
+    protected final RegistrantList mServiceStateRegistrants
+    = new RegistrantList();
+
+    protected final RegistrantList mMmiCompleteRegistrants
+    = new RegistrantList();
+
+    protected final RegistrantList mMmiRegistrants
+    = new RegistrantList();
+
+    protected final RegistrantList mUnknownConnectionRegistrants
+    = new RegistrantList();
+
+    protected final RegistrantList mSuppServiceFailedRegistrants
+    = new RegistrantList();
+
+    private CallManager() {
+        mPhones = new ArrayList<Phone>();
+        mRingingCalls = new ArrayList<Call>();
+        mBackgroundCalls = new ArrayList<Call>();
+        mForegroundCalls = new ArrayList<Call>();
+        mDefaultPhone = null;
+    }
+
+    /**
+     * get singleton instance of CallManager
+     * @return CallManager
+     */
+    public static CallManager getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * Register phone to CallManager
+     * @param phone
+     * @return
+     */
+    public boolean registerPhone(Phone phone) {
+        if (phone != null && !mPhones.contains(phone)) {
+            if (mPhones.isEmpty()) {
+                mDefaultPhone = phone;
+            }
+            mPhones.add(phone);
+            mRingingCalls.add(phone.getRingingCall());
+            mBackgroundCalls.add(phone.getBackgroundCall());
+            mForegroundCalls.add(phone.getForegroundCall());
+            registerForPhoneStates(phone);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * unregister phone from CallManager
+     * @param phone
+     */
+    public void unregisterPhone(Phone phone) {
+        if (phone != null && !mPhones.contains(phone)) {
+            mPhones.remove(phone);
+            mRingingCalls.remove(phone.getRingingCall());
+            mBackgroundCalls.remove(phone.getBackgroundCall());
+            mForegroundCalls.remove(phone.getForegroundCall());
+            unregisterForPhoneStates(phone);
+            if (phone == mDefaultPhone) {
+                if (mPhones.isEmpty()) {
+                    mDefaultPhone = null;
+                } else {
+                    mDefaultPhone = mPhones.get(0);
+                }
+            }
+        }
+    }
+
+    private void registerForPhoneStates(Phone phone) {
+        phone.registerForPreciseCallStateChanged(mHandler, EVENT_CALL_STATE_CHANGED, null);
+        phone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
+    }
+
+    private void unregisterForPhoneStates(Phone phone) {
+        phone.unregisterForPreciseCallStateChanged(mHandler);
+        phone.unregisterForDisconnect(mHandler);
+    }
+
+    /**
+     * Answers a ringing or waiting call.
+     *
+     * Active call, if any, go on hold.
+     * If active call can't be held, i.e., a background call of the same channel exists,
+     * the active call will be hang up.
+     *
+     * Answering occurs asynchronously, and final notification occurs via
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
+     *
+     * @exception CallStateException when call is not ringing or waiting
+     */
+    public void acceptCall(Call ringingCall) throws CallStateException {
+        Phone ringingPhone = ringingCall.getPhone();
+
+        if ( hasActiveFgCall() ) {
+            Phone activePhone = getActiveFgCall().getPhone();
+            boolean hasBgCall = activePhone.getBackgroundCall().isIdle();
+            boolean sameChannel = (activePhone == ringingPhone);
+
+            if (sameChannel && hasBgCall) {
+                getActiveFgCall().hangup();
+            } else if (!sameChannel && !hasBgCall) {
+                activePhone.switchHoldingAndActive();
+            } else if (!sameChannel && hasBgCall) {
+                getActiveFgCall().hangup();
+            }
+        }
+
+        ringingPhone.acceptCall();
+    }
+
+    /**
+     * Reject (ignore) a ringing call. In GSM, this means UDUB
+     * (User Determined User Busy). Reject occurs asynchronously,
+     * and final notification occurs via
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
+     *
+     * @exception CallStateException when no call is ringing or waiting
+     */
+    public void rejectCall(Call ringingCall) throws CallStateException {
+        Phone ringingPhone = ringingCall.getPhone();
+
+        ringingPhone.rejectCall();
+    }
+
+    /**
+     * Places any active calls on hold, and makes any held calls
+     *  active. Switch occurs asynchronously and may fail.
+     * Final notification occurs via
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
+     *
+     * @exception CallStateException if active call is ringing, waiting, or
+     * dialing/alerting, or heldCall can�t be active.
+     * In these cases, this operation may not be performed.
+     */
+    public void switchHoldingAndActive(Call heldCall) throws CallStateException {
+        Phone activePhone = null;
+        Phone heldPhone = null;
+
+        if (hasActiveFgCall()) {
+            activePhone = getActiveFgCall().getPhone();
+        }
+
+        if (heldCall != null) {
+            heldPhone = heldCall.getPhone();
+        }
+
+        if (activePhone != heldPhone) {
+            activePhone.switchHoldingAndActive();
+        }
+
+        heldPhone.switchHoldingAndActive();
+    }
+
+    /**
+     * Whether or not the phone can conference in the current phone
+     * state--that is, one call holding and one call active.
+     * @return true if the phone can conference; false otherwise.
+     */
+    public boolean canConference(Call heldCall) {
+        Phone activePhone = null;
+        Phone heldPhone = null;
+
+        if (hasActiveFgCall()) {
+            activePhone = getActiveFgCall().getPhone();
+        }
+
+        if (heldCall != null) {
+            heldPhone = heldCall.getPhone();
+        }
+
+        return (heldPhone == activePhone);
+    }
+
+    /**
+     * Conferences holding and active. Conference occurs asynchronously
+     * and may fail. Final notification occurs via
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
+     *
+     * @exception CallStateException if canConference() would return false.
+     * In these cases, this operation may not be performed.
+     */
+    public void conference(Call heldCall) throws CallStateException {
+        if (canConference(heldCall))
+            throw(new CallStateException("Can't conference foreground and selected background call"));
+
+        heldCall.getPhone().conference();
+    }
+
+    /**
+     * Initiate a new voice connection. This happens asynchronously, so you
+     * cannot assume the audio path is connected (or a call index has been
+     * assigned) until PhoneStateChanged notification has occurred.
+     *
+     * @exception CallStateException if a new outgoing call is not currently
+     * possible because no more call slots exist or a call exists that is
+     * dialing, alerting, ringing, or waiting.  Other errors are
+     * handled asynchronously.
+     */
+    public Connection dial(Phone phone, String dialString) throws CallStateException {
+        return phone.dial(dialString);
+    }
+
+    /**
+     * Initiate a new voice connection. This happens asynchronously, so you
+     * cannot assume the audio path is connected (or a call index has been
+     * assigned) until PhoneStateChanged notification has occurred.
+     *
+     * @exception CallStateException if a new outgoing call is not currently
+     * possible because no more call slots exist or a call exists that is
+     * dialing, alerting, ringing, or waiting.  Other errors are
+     * handled asynchronously.
+     */
+    public Connection dial(Phone phone, String dialString, UUSInfo uusInfo) throws CallStateException {
+        return phone.dial(dialString, uusInfo);
+    }
+
+    /**
+     * clear disconnect connection for each phone
+     */
+    public void clearDisconnected() {
+        for(Phone phone : mPhones) {
+            phone.clearDisconnected();
+        }
+    }
+
+    /**
+     * Whether or not the phone can do explicit call transfer in the current
+     * phone state--that is, one call holding and one call active.
+     * @return true if the phone can do explicit call transfer; false otherwise.
+     */
+    public boolean canTransfer(Call heldCall) {
+        Phone activePhone = null;
+        Phone heldPhone = null;
+
+        if (hasActiveFgCall()) {
+            activePhone = getActiveFgCall().getPhone();
+        }
+
+        if (heldCall != null) {
+            heldPhone = heldCall.getPhone();
+        }
+
+        return (heldPhone == activePhone && activePhone.canTransfer());
+    }
+
+    /**
+     * Connects the held call and active call
+     * Disconnects the subscriber from both calls
+     *
+     * Explicit Call Transfer occurs asynchronously
+     * and may fail. Final notification occurs via
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}.
+     *
+     * @exception CallStateException if canTransfer() would return false.
+     * In these cases, this operation may not be performed.
+     */
+    public void explicitCallTransfer(Call heldCall) throws CallStateException {
+        if (canTransfer(heldCall)) {
+            heldCall.getPhone().explicitCallTransfer();
+        }
+    }
+
+    /**
+     * Returns a list of MMI codes that are pending for a phone. (They have initiated
+     * but have not yet completed).
+     * Presently there is only ever one.
+     *
+     * Use <code>registerForMmiInitiate</code>
+     * and <code>registerForMmiComplete</code> for change notification.
+     * @return null if phone doesn't have or support mmi code
+     */
+    public List<? extends MmiCode> getPendingMmiCodes(Phone phone) {
+        return null;
+    }
+
+    /**
+     * Sends user response to a USSD REQUEST message.  An MmiCode instance
+     * representing this response is sent to handlers registered with
+     * registerForMmiInitiate.
+     *
+     * @param ussdMessge    Message to send in the response.
+     * @return false if phone doesn't support ussd service
+     */
+    public boolean sendUssdResponse(Phone phone, String ussdMessge) {
+        return false;
+    }
+
+    /**
+     * Mutes or unmutes the microphone for the active call. The microphone
+     * is automatically unmuted if a call is answered, dialed, or resumed
+     * from a holding state.
+     *
+     * @param muted true to mute the microphone,
+     * false to activate the microphone.
+     */
+
+    public void setMute(boolean muted) {
+        if (hasActiveFgCall()) {
+            getActiveFgCall().getPhone().setMute(muted);
+        }
+    }
+
+    /**
+     * Gets current mute status. Use
+     * {@link #registerForPreciseCallStateChanged(android.os.Handler, int,
+     * java.lang.Object) registerForPreciseCallStateChanged()}
+     * as a change notifcation, although presently phone state changed is not
+     * fired when setMute() is called.
+     *
+     * @return true is muting, false is unmuting
+     */
+    public boolean getMute() {
+        if (hasActiveFgCall()) {
+            return getActiveFgCall().getPhone().getMute();
+        }
+        return false;
+    }
+
+    /**
+     * Play a DTMF tone on the active call.
+     *
+     * @param c should be one of 0-9, '*' or '#'. Other values will be
+     * silently ignored.
+     * @return false if no active call or the active call doesn't support
+     *         dtmf tone
+     */
+    public boolean sendDtmf(char c) {
+        if (hasActiveFgCall()) {
+            getActiveFgCall().getPhone().sendDtmf(c);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Start to paly a DTMF tone on the active call.
+     * or there is a playing DTMF tone.
+     * @param c should be one of 0-9, '*' or '#'. Other values will be
+     * silently ignored.
+     *
+     * @return false if no active call or the active call doesn't support
+     *         dtmf tone
+     */
+    public boolean startDtmf(char c) {
+        if (hasActiveFgCall()) {
+            getActiveFgCall().getPhone().sendDtmf(c);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Stop the playing DTMF tone. Ignored if there is no playing DTMF
+     * tone or no active call.
+     */
+    public void stopDtmf(Phone phone) {
+        phone.stopDtmf();
+    }
+
+    /**
+     * send burst DTMF tone, it can send the string as single character or multiple character
+     * ignore if there is no active call or not valid digits string.
+     * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
+     * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
+     * this api can send single character and multiple character, also, this api has response
+     * back to caller.
+     *
+     * @param dtmfString is string representing the dialing digit(s) in the active call
+     * @param on the DTMF ON length in milliseconds, or 0 for default
+     * @param off the DTMF OFF length in milliseconds, or 0 for default
+     * @param onComplete is the callback message when the action is processed by BP
+     *
+     */
+    public boolean sendBurstDtmf(Phone phone, String dtmfString, int on, int off, Message onComplete) {
+        if (hasActiveFgCall()) {
+            getActiveFgCall().getPhone().sendBurstDtmf(dtmfString, on, off, onComplete);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Notifies when a voice connection has disconnected, either due to local
+     * or remote hangup or error.
+     *
+     *  Messages received from this will have the following members:<p>
+     *  <ul><li>Message.obj will be an AsyncResult</li>
+     *  <li>AsyncResult.userObj = obj</li>
+     *  <li>AsyncResult.result = a Connection object that is
+     *  no longer connected.</li></ul>
+     */
+    public void registerForDisconnect(Handler h, int what, Object obj) {
+        mDisconnectRegistrants.addUnique(h, what, obj);
+    }
+
+    /**
+     * Unregisters for voice disconnection notification.
+     * Extraneous calls are tolerated silently
+     */
+    public void unregisterForDisconnect(Handler h){
+        mDisconnectRegistrants.remove(h);
+    }
+
+    /**
+     * Register for getting notifications for change in the Call State {@link Call.State}
+     * This is called PreciseCallState because the call state is more precise than the
+     * {@link Phone.State} which can be obtained using the {@link PhoneStateListener}
+     *
+     * Resulting events will have an AsyncResult in <code>Message.obj</code>.
+     * AsyncResult.userData will be set to the obj argument here.
+     * The <em>h</em> parameter is held only by a weak reference.
+     */
+    public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){
+        mPreciseCallStateRegistrants.addUnique(h, what, obj);
+    }
+
+    /**
+     * Unregisters for voice call state change notifications.
+     * Extraneous calls are tolerated silently.
+     */
+    public void unregisterForPreciseCallStateChanged(Handler h){
+        mPreciseCallStateRegistrants.remove(h);
+    }
+
+    /**
+     * Notifies when a previously untracked non-ringing/waiting connection has appeared.
+     * This is likely due to some other entity (eg, SIM card application) initiating a call.
+     */
+    public void registerForUnknownConnection(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for unknown connection notifications.
+     */
+    public void unregisterForUnknownConnection(Handler h){}
+
+
+    /**
+     * Notifies when a new ringing or waiting connection has appeared.<p>
+     *
+     *  Messages received from this:
+     *  Message.obj will be an AsyncResult
+     *  AsyncResult.userObj = obj
+     *  AsyncResult.result = a Connection. <p>
+     *  Please check Connection.isRinging() to make sure the Connection
+     *  has not dropped since this message was posted.
+     *  If Connection.isRinging() is true, then
+     *   Connection.getCall() == Phone.getRingingCall()
+     */
+    public void registerForNewRingingConnection(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for new ringing connection notification.
+     * Extraneous calls are tolerated silently
+     */
+
+    public void unregisterForNewRingingConnection(Handler h){}
+
+    /**
+     * Notifies when an incoming call rings.<p>
+     *
+     *  Messages received from this:
+     *  Message.obj will be an AsyncResult
+     *  AsyncResult.userObj = obj
+     *  AsyncResult.result = a Connection. <p>
+     */
+    public void registerForIncomingRing(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for ring notification.
+     * Extraneous calls are tolerated silently
+     */
+
+    public void unregisterForIncomingRing(Handler h){}
+
+    /**
+     * Notifies when out-band ringback tone is needed.<p>
+     *
+     *  Messages received from this:
+     *  Message.obj will be an AsyncResult
+     *  AsyncResult.userObj = obj
+     *  AsyncResult.result = boolean, true to start play ringback tone
+     *                       and false to stop. <p>
+     */
+    public void registerForRingbackTone(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for ringback tone notification.
+     */
+
+    public void unregisterForRingbackTone(Handler h){}
+
+    /**
+     * Registers the handler to reset the uplink mute state to get
+     * uplink audio.
+     */
+    public void registerForResendIncallMute(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for resend incall mute notifications.
+     */
+    public void unregisterForResendIncallMute(Handler h){}
+
+
+
+    /**
+     * Register for notifications of initiation of a new MMI code request.
+     * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
+     *
+     * Example: If Phone.dial is called with "*#31#", then the app will
+     * be notified here.<p>
+     *
+     * The returned <code>Message.obj</code> will contain an AsyncResult.
+     *
+     * <code>obj.result</code> will be an "MmiCode" object.
+     */
+    public void registerForMmiInitiate(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for new MMI initiate notification.
+     * Extraneous calls are tolerated silently
+     */
+    public void unregisterForMmiInitiate(Handler h){}
+
+    /**
+     * Register for notifications that an MMI request has completed
+     * its network activity and is in its final state. This may mean a state
+     * of COMPLETE, FAILED, or CANCELLED.
+     *
+     * <code>Message.obj</code> will contain an AsyncResult.
+     * <code>obj.result</code> will be an "MmiCode" object
+     */
+    public void registerForMmiComplete(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for MMI complete notification.
+     * Extraneous calls are tolerated silently
+     */
+    public void unregisterForMmiComplete(Handler h){}
+
+    /**
+     * Registration point for Ecm timer reset
+     * @param h handler to notify
+     * @param what user-defined message code
+     * @param obj placed in Message.obj
+     */
+    public void registerForEcmTimerReset(Handler h, int what, Object obj){}
+
+    /**
+     * Unregister for notification for Ecm timer reset
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForEcmTimerReset(Handler h){}
+
+
+
+    /**
+     * Register for ServiceState changed.
+     * Message.obj will contain an AsyncResult.
+     * AsyncResult.result will be a ServiceState instance
+     */
+    public void registerForServiceStateChanged(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for ServiceStateChange notification.
+     * Extraneous calls are tolerated silently
+     */
+    public void unregisterForServiceStateChanged(Handler h){}
+
+    /**
+     * Register for Supplementary Service notifications from the network.
+     * Message.obj will contain an AsyncResult.
+     * AsyncResult.result will be a SuppServiceNotification instance.
+     *
+     * @param h Handler that receives the notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSuppServiceNotification(Handler h, int what, Object obj){}
+
+    /**
+     * Unregisters for Supplementary Service notifications.
+     * Extraneous calls are tolerated silently
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSuppServiceNotification(Handler h){}
+
+    /**
+     * Register for notifications when a supplementary service attempt fails.
+     * Message.obj will contain an AsyncResult.
+     *
+     * @param h Handler that receives the notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForSuppServiceFailed(Handler h, int what, Object obj){}
+
+    /**
+     * Unregister for notifications when a supplementary service attempt fails.
+     * Extraneous calls are tolerated silently
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSuppServiceFailed(Handler h){}
+
+    /**
+     * Register for notifications when a sInCall VoicePrivacy is enabled
+     *
+     * @param h Handler that receives the notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){}
+
+    /**
+     * Unegister for notifications when a sInCall VoicePrivacy is enabled
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForInCallVoicePrivacyOn(Handler h){}
+
+    /**
+     * Register for notifications when a sInCall VoicePrivacy is disabled
+     *
+     * @param h Handler that receives the notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){}
+
+    /**
+     * Unegister for notifications when a sInCall VoicePrivacy is disabled
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForInCallVoicePrivacyOff(Handler h){}
+
+    /**
+     * Register for notifications when CDMA OTA Provision status change
+     *
+     * @param h Handler that receives the notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj){}
+
+    /**
+     * Unegister for notifications when CDMA OTA Provision status change
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForCdmaOtaStatusChange(Handler h){}
+
+    /**
+     * Registration point for subscription info ready
+     * @param h handler to notify
+     * @param what what code of message when delivered
+     * @param obj placed in Message.obj
+     */
+    public void registerForSubscriptionInfoReady(Handler h, int what, Object obj){}
+
+    /**
+     * Unregister for notifications for subscription info
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForSubscriptionInfoReady(Handler h){}
+
+    /* APIs to access foregroudCalls, backgroudCalls, and ringingCalls
+     * 1. APIs to access list of calls
+     * 2. APIs to check if any active call, which has connection other than
+     * disconnected ones, pleaser refer to Call.isIdle()
+     * 3. APIs to return first active call
+     * 4. APIs to return the connections of first active call
+     * 5. APIs to return other property of first active call
+     */
+
+    /**
+     * @return list of ringing calls
+     */
+    public ArrayList<Call> getRingingCalls() {
+        return mBackgroundCalls;
+    }
+
+    /**
+     * @return list of background calls
+     */
+    public ArrayList<Call> getBackgroundCalls() {
+        return mBackgroundCalls;
+    }
+
+    /**
+     * Return true if there is at least one active foreground call
+     */
+    public boolean hasActiveFgCall() {
+        return (getFirstActiveCall(mForegroundCalls) != null);
+    }
+
+    /**
+     * Return true if there is at least one active background call
+     */
+    public boolean hasActiveBgCall() {
+        // TODO since hasActiveBgCall may get called often
+        // better to cache it to improve performance
+        return (getFirstActiveCall(mBackgroundCalls) != null);
+    }
+
+    /**
+     * Return true if there is at least one active ringing call
+     *
+     */
+    public boolean hasActiveRingingCall() {
+        return (getFirstActiveCall(mRingingCalls) != null);
+    }
+
+    /**
+     * return the active foreground call from foreground calls
+     *
+     * Active call means the call is NOT in Call.State.IDLE
+     *
+     * 1. If there is active foreground call, return it
+     * 2. If there is no active foreground call, return the
+     *    foreground call associated with default phone, which state is IDLE.
+     * 3. If there is no phone registered at all, return null.
+     *
+     */
+    public Call getActiveFgCall() {
+        for (Call call : mForegroundCalls) {
+            if (call.getState() != Call.State.IDLE) {
+                return call;
+            }
+        }
+        return (mDefaultPhone == null) ?
+                null : mDefaultPhone.getForegroundCall();
+    }
+
+    /**
+     * return one active background call from background calls
+     *
+     * Active call means the call is NOT idle defined by Call.isIdle()
+     *
+     * 1. If there is only one active background call, return it
+     * 2. If there is more than one active background call, return the first one
+     * 3. If there is no active background call, return the background call
+     *    associated with default phone, which state is IDLE.
+     * 4. If there is no background call at all, return null.
+     *
+     * Complete background calls list can be get by getBackgroundCalls()
+     */
+    public Call getFirstActiveBgCall() {
+        for (Call call : mBackgroundCalls) {
+            if (!call.isIdle()) {
+                return call;
+            }
+        }
+        return (mDefaultPhone == null) ?
+                null : mDefaultPhone.getBackgroundCall();
+    }
+
+    /**
+     * return one active ringing call from ringing calls
+     *
+     * Active call means the call is NOT idle defined by Call.isIdle()
+     *
+     * 1. If there is only one active ringing call, return it
+     * 2. If there is more than one active ringing call, return the first one
+     * 3. If there is no active ringing call, return the ringing call
+     *    associated with default phone, which state is IDLE.
+     * 4. If there is no ringing call at all, return null.
+     *
+     * Complete ringing calls list can be get by getRingingCalls()
+     */
+    public Call getFirstActiveRingingCall() {
+        for (Call call : mRingingCalls) {
+            if (!call.isIdle()) {
+                return call;
+            }
+        }
+        return (mDefaultPhone == null) ?
+                null : mDefaultPhone.getRingingCall();
+    }
+
+    /**
+     * @return the state of active foreground call
+     * return IDLE if there is no active foreground call
+     */
+    public Call.State getActiveFgCallState() {
+        Call fgCall = getActiveFgCall();
+
+        if (fgCall != null) {
+            return fgCall.getState();
+        }
+
+        return Call.State.IDLE;
+    }
+
+    /**
+     * @return the connections of active foreground call
+     * return null if there is no active foreground call
+     */
+    public List<Connection> getFgCallConnections() {
+        Call fgCall = getActiveFgCall();
+        if ( fgCall != null) {
+            return fgCall.getConnections();
+        }
+        return emptyConnections;
+    }
+
+    /**
+     * @return the connections of active background call
+     * return empty list if there is no active background call
+     */
+    public List<Connection> getBgCallConnections() {
+        Call bgCall = getActiveFgCall();
+        if ( bgCall != null) {
+            return bgCall.getConnections();
+        }
+        return emptyConnections;
+    }
+
+    /**
+     * @return the latest connection of active foreground call
+     * return null if there is no active foreground call
+     */
+    public Connection getFgCallLatestConnection() {
+        Call fgCall = getActiveFgCall();
+        if ( fgCall != null) {
+            return fgCall.getLatestConnection();
+        }
+        return null;
+    }
+
+    /**
+     * @return true if there is at least one Foreground call in disconnected state
+     */
+    public boolean hasDisconnectedFgCall() {
+        return (getFirstCallOfState(mForegroundCalls, Call.State.DISCONNECTED) != null);
+    }
+
+    /**
+     * @return true if there is at least one background call in disconnected state
+     */
+    public boolean hasDisconnectedBgCall() {
+        return (getFirstCallOfState(mBackgroundCalls, Call.State.DISCONNECTED) != null);
+    }
+
+    /**
+     * @return the first active call from a call list
+     */
+    private  Call getFirstActiveCall(ArrayList<Call> calls) {
+        for (Call call : calls) {
+            if (!call.isIdle()) {
+                return call;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @return the first call in a the Call.state from a call list
+     */
+    private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state) {
+        for (Call call : calls) {
+            if (call.getState() == state) {
+                return call;
+            }
+        }
+        return null;
+    }
+
+
+
+
+    private Handler mHandler = new Handler() {
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_DISCONNECT:
+                    mDisconnectRegistrants.notifyRegistrants((AsyncResult) msg.obj);
+                    break;
+                case EVENT_CALL_STATE_CHANGED:
+                    mPreciseCallStateRegistrants.notifyRegistrants((AsyncResult) msg.obj);
+                    break;
+            }
+        }
+    };
+}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index e74b9e4..5cba2e1 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -59,6 +59,11 @@
     String getVoiceMailNumber();
 
     /**
+     * Retrieves the complete voice mail number.
+     */
+    String getCompleteVoiceMailNumber();
+
+    /**
      * Retrieves the alpha identifier associated with the voice mail number.
      */
     String getVoiceMailAlphaTag();
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
index 4f71bb1..86c86bb 100644
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
+++ b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.telephony.PhoneNumberUtils;
 import android.util.Log;
 
 public class PhoneSubInfo extends IPhoneSubInfo.Stub {
@@ -29,6 +30,9 @@
     private Context mContext;
     private static final String READ_PHONE_STATE =
         android.Manifest.permission.READ_PHONE_STATE;
+    private static final String CALL_PRIVILEGED =
+        // TODO Add core/res/AndriodManifest.xml#READ_PRIVILEGED_PHONE_STATE
+        android.Manifest.permission.CALL_PRIVILEGED;
 
     public PhoneSubInfo(Phone phone) {
         mPhone = phone;
@@ -101,7 +105,22 @@
      */
     public String getVoiceMailNumber() {
         mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
-        return (String) mPhone.getVoiceMailNumber();
+        String number = PhoneNumberUtils.extractNetworkPortion(mPhone.getVoiceMailNumber());
+        Log.d(LOG_TAG, "VM: PhoneSubInfo.getVoiceMailNUmber: "); // + number);
+        return number;
+    }
+
+    /**
+     * Retrieves the compelete voice mail number.
+     *
+     * @hide
+     */
+    public String getCompleteVoiceMailNumber() {
+        mContext.enforceCallingOrSelfPermission(CALL_PRIVILEGED,
+                "Requires CALL_PRIVILEGED");
+        String number = mPhone.getVoiceMailNumber();
+        Log.d(LOG_TAG, "VM: PhoneSubInfo.getCompleteVoiceMailNUmber: "); // + number);
+        return number;
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
index 202ded2..7009893 100644
--- a/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneSubInfoProxy.java
@@ -82,6 +82,13 @@
     }
 
     /**
+     * Retrieves the complete voice mail number.
+     */
+    public String getCompleteVoiceMailNumber() {
+        return mPhoneSubInfo.getCompleteVoiceMailNumber();
+    }
+
+    /**
      * Retrieves the alpha identifier associated with the voice mail number.
      */
     public String getVoiceMailAlphaTag() {