Merge "resolved conflicts for merge of 05be6d6f to master"
diff --git a/api/current.txt b/api/current.txt
index 1f6d673..2eda26f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22991,7 +22991,7 @@
 
   public class WebHistoryItem implements java.lang.Cloneable {
     method public android.graphics.Bitmap getFavicon();
-    method public int getId();
+    method public deprecated int getId();
     method public java.lang.String getOriginalUrl();
     method public java.lang.String getTitle();
     method public java.lang.String getUrl();
@@ -23042,13 +23042,13 @@
     method public synchronized java.lang.String getFixedFontFamily();
     method public synchronized boolean getJavaScriptCanOpenWindowsAutomatically();
     method public synchronized boolean getJavaScriptEnabled();
-    method public synchronized android.webkit.WebSettings.LayoutAlgorithm getLayoutAlgorithm();
+    method public deprecated synchronized android.webkit.WebSettings.LayoutAlgorithm getLayoutAlgorithm();
     method public boolean getLightTouchEnabled();
     method public boolean getLoadWithOverviewMode();
     method public synchronized boolean getLoadsImagesAutomatically();
     method public synchronized int getMinimumFontSize();
     method public synchronized int getMinimumLogicalFontSize();
-    method public boolean getNavDump();
+    method public deprecated boolean getNavDump();
     method public synchronized android.webkit.WebSettings.PluginState getPluginState();
     method public deprecated synchronized boolean getPluginsEnabled();
     method public deprecated synchronized java.lang.String getPluginsPath();
@@ -23059,7 +23059,7 @@
     method public synchronized java.lang.String getStandardFontFamily();
     method public synchronized android.webkit.WebSettings.TextSize getTextSize();
     method public deprecated synchronized boolean getUseDoubleTree();
-    method public boolean getUseWebViewBackgroundForOverscrollBackground();
+    method public deprecated boolean getUseWebViewBackgroundForOverscrollBackground();
     method public synchronized boolean getUseWideViewPort();
     method public deprecated synchronized int getUserAgent();
     method public synchronized java.lang.String getUserAgentString();
@@ -23088,13 +23088,13 @@
     method public synchronized void setGeolocationEnabled(boolean);
     method public synchronized void setJavaScriptCanOpenWindowsAutomatically(boolean);
     method public synchronized void setJavaScriptEnabled(boolean);
-    method public synchronized void setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm);
+    method public deprecated synchronized void setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm);
     method public void setLightTouchEnabled(boolean);
     method public void setLoadWithOverviewMode(boolean);
     method public synchronized void setLoadsImagesAutomatically(boolean);
     method public synchronized void setMinimumFontSize(int);
     method public synchronized void setMinimumLogicalFontSize(int);
-    method public void setNavDump(boolean);
+    method public deprecated void setNavDump(boolean);
     method public void setNeedInitialFocus(boolean);
     method public synchronized void setPluginState(android.webkit.WebSettings.PluginState);
     method public deprecated synchronized void setPluginsEnabled(boolean);
@@ -23109,7 +23109,7 @@
     method public void setSupportZoom(boolean);
     method public synchronized void setTextSize(android.webkit.WebSettings.TextSize);
     method public deprecated synchronized void setUseDoubleTree(boolean);
-    method public void setUseWebViewBackgroundForOverscrollBackground(boolean);
+    method public deprecated void setUseWebViewBackgroundForOverscrollBackground(boolean);
     method public synchronized void setUseWideViewPort(boolean);
     method public deprecated synchronized void setUserAgent(int);
     method public synchronized void setUserAgentString(java.lang.String);
@@ -23122,7 +23122,7 @@
     field public static final int LOAD_NO_CACHE = 2; // 0x2
   }
 
-  public static final class WebSettings.LayoutAlgorithm extends java.lang.Enum {
+  public static final deprecated class WebSettings.LayoutAlgorithm extends java.lang.Enum {
     method public static android.webkit.WebSettings.LayoutAlgorithm valueOf(java.lang.String);
     method public static final android.webkit.WebSettings.LayoutAlgorithm[] values();
   }
@@ -23200,12 +23200,12 @@
     method public void clearSslPreferences();
     method public void clearView();
     method public android.webkit.WebBackForwardList copyBackForwardList();
-    method public void debugDump();
+    method public deprecated void debugDump();
     method public void destroy();
-    method public static void disablePlatformNotifications();
+    method public static deprecated void disablePlatformNotifications();
     method public void documentHasImages(android.os.Message);
-    method public void emulateShiftHeld();
-    method public static void enablePlatformNotifications();
+    method public deprecated void emulateShiftHeld();
+    method public static deprecated void enablePlatformNotifications();
     method public static java.lang.String findAddress(java.lang.String);
     method public int findAll(java.lang.String);
     method public void findNext(boolean);
@@ -23248,11 +23248,11 @@
     method public void removeJavascriptInterface(java.lang.String);
     method public void requestFocusNodeHref(android.os.Message);
     method public void requestImageRef(android.os.Message);
-    method public boolean restorePicture(android.os.Bundle, java.io.File);
+    method public deprecated boolean restorePicture(android.os.Bundle, java.io.File);
     method public android.webkit.WebBackForwardList restoreState(android.os.Bundle);
     method public void resumeTimers();
     method public void savePassword(java.lang.String, java.lang.String, java.lang.String);
-    method public boolean savePicture(android.os.Bundle, java.io.File);
+    method public deprecated boolean savePicture(android.os.Bundle, java.io.File);
     method public android.webkit.WebBackForwardList saveState(android.os.Bundle);
     method public void saveWebArchive(java.lang.String);
     method public void saveWebArchive(java.lang.String, boolean, android.webkit.ValueCallback<java.lang.String>);
@@ -23263,7 +23263,7 @@
     method public void setInitialScale(int);
     method public void setMapTrackballToArrowKeys(boolean);
     method public void setNetworkAvailable(boolean);
-    method public void setPictureListener(android.webkit.WebView.PictureListener);
+    method public deprecated void setPictureListener(android.webkit.WebView.PictureListener);
     method public void setVerticalScrollbarOverlay(boolean);
     method public void setWebChromeClient(android.webkit.WebChromeClient);
     method public void setWebViewClient(android.webkit.WebViewClient);
@@ -23291,8 +23291,8 @@
     field public static final int UNKNOWN_TYPE = 0; // 0x0
   }
 
-  public static abstract interface WebView.PictureListener {
-    method public abstract void onNewPicture(android.webkit.WebView, android.graphics.Picture);
+  public static abstract deprecated interface WebView.PictureListener {
+    method public abstract deprecated void onNewPicture(android.webkit.WebView, android.graphics.Picture);
   }
 
   public class WebView.WebViewTransport {
diff --git a/core/java/android/webkit/JniUtil.java b/core/java/android/webkit/JniUtil.java
index 62b415c..b5d4933 100644
--- a/core/java/android/webkit/JniUtil.java
+++ b/core/java/android/webkit/JniUtil.java
@@ -48,6 +48,12 @@
         initialized = true;
     }
 
+    protected static synchronized Context getContext() {
+        if (!initialized)
+            return null;
+        return sContext;
+    }
+
     /**
      * Called by JNI. Gets the application's database directory, excluding the trailing slash.
      * @return String The application's database directory
diff --git a/core/java/android/webkit/WebHistoryItem.java b/core/java/android/webkit/WebHistoryItem.java
index 7c0e478..ccf3d6b 100644
--- a/core/java/android/webkit/WebHistoryItem.java
+++ b/core/java/android/webkit/WebHistoryItem.java
@@ -90,7 +90,9 @@
      * another item, the identifiers will be the same even if they are not the
      * same object.
      * @return The id for this item.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public int getId() {
         return mId;
     }
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 4755362..8ffbda2 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -42,8 +42,10 @@
      * SINGLE_COLUMN moves all content into one column that is the width of the
      * view.
      * NARROW_COLUMNS makes all columns no wider than the screen if possible.
+     * @deprecated This enum is now obsolete.
      */
     // XXX: These must match LayoutAlgorithm in Settings.h in WebCore.
+    @Deprecated
     public enum LayoutAlgorithm {
         NORMAL,
         SINGLE_COLUMN,
@@ -520,14 +522,18 @@
 
     /**
      * Enables dumping the pages navigation cache to a text file.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public void setNavDump(boolean enabled) {
         mNavDump = enabled;
     }
 
     /**
      * Returns true if dumping the navigation cache is enabled.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public boolean getNavDump() {
         return mNavDump;
     }
@@ -665,7 +671,9 @@
      * Set whether the WebView uses its background for over scroll background.
      * If true, it will use the WebView's background. If false, it will use an
      * internal pattern. Default is true.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public void setUseWebViewBackgroundForOverscrollBackground(boolean view) {
         mUseWebViewBackgroundForOverscroll = view;
     }
@@ -673,7 +681,9 @@
     /**
      * Returns true if this WebView uses WebView's background instead of
      * internal pattern for over scroll background.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public boolean getUseWebViewBackgroundForOverscrollBackground() {
         return mUseWebViewBackgroundForOverscroll;
     }
@@ -876,7 +886,9 @@
      * WebView.
      * @param l A LayoutAlgorithm enum specifying the algorithm to use.
      * @see WebSettings.LayoutAlgorithm
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
         // XXX: This will only be affective if libwebcore was built with
         // ANDROID_LAYOUT defined.
@@ -891,7 +903,9 @@
      * @return LayoutAlgorithm enum value describing the layout algorithm
      *         being used.
      * @see WebSettings.LayoutAlgorithm
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public synchronized LayoutAlgorithm getLayoutAlgorithm() {
         return mLayoutAlgorithm;
     }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 0504532..0acd748 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -822,6 +822,8 @@
 
     private WebViewCore.AutoFillData mAutoFillData;
 
+    private static boolean sNotificationsEnabled = true;
+
     /**
      * URI scheme for telephone number
      */
@@ -854,13 +856,17 @@
     private PictureListener mPictureListener;
     /**
      * Interface to listen for new pictures as they change.
+     * @deprecated This interface is now obsolete.
      */
+    @Deprecated
     public interface PictureListener {
         /**
          * Notify the listener that the picture has changed.
          * @param view The WebView that owns the picture.
          * @param picture The new picture.
+         * @deprecated This method is now obsolete.
          */
+        @Deprecated
         public void onNewPicture(WebView view, Picture picture);
     }
 
@@ -1024,24 +1030,38 @@
     }
 
     /*
-     * A variable to track if there is a receiver added for PROXY_CHANGE_ACTION
+     * Receiver for PROXY_CHANGE_ACTION, will be null when it is not added handling broadcasts.
      */
-    private static boolean sProxyReceiverAdded;
+    private static ProxyReceiver sProxyReceiver;
 
+    /*
+     * @param context This method expects this to be a valid context
+     */
     private static synchronized void setupProxyListener(Context context) {
-        if (sProxyReceiverAdded) {
+        if (sProxyReceiver != null || sNotificationsEnabled == false) {
             return;
         }
         IntentFilter filter = new IntentFilter();
         filter.addAction(Proxy.PROXY_CHANGE_ACTION);
+        sProxyReceiver = new ProxyReceiver();
         Intent currentProxy = context.getApplicationContext().registerReceiver(
-                new ProxyReceiver(), filter);
-        sProxyReceiverAdded = true;
+                sProxyReceiver, filter);
         if (currentProxy != null) {
             handleProxyBroadcast(currentProxy);
         }
     }
 
+    /*
+     * @param context This method expects this to be a valid context
+     */
+    private static synchronized void disableProxyListener(Context context) {
+        if (sProxyReceiver == null)
+            return;
+
+        context.getApplicationContext().unregisterReceiver(sProxyReceiver);
+        sProxyReceiver = null;
+    }
+
     private static void handleProxyBroadcast(Intent intent) {
         ProxyProperties proxyProperties = (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
         if (proxyProperties == null || proxyProperties.getHost() == null) {
@@ -1530,19 +1550,38 @@
 
     /**
      * Enables platform notifications of data state and proxy changes.
+     * Notifications are enabled by default.
+     *
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public static void enablePlatformNotifications() {
         checkThread();
-        Network.enablePlatformNotifications();
+        synchronized (WebView.class) {
+            Network.enablePlatformNotifications();
+            sNotificationsEnabled = true;
+            Context context = JniUtil.getContext();
+            if (context != null)
+                setupProxyListener(context);
+        }
     }
 
     /**
-     * If platform notifications are enabled, this should be called
-     * from the Activity's onPause() or onStop().
+     * Disables platform notifications of data state and proxy changes.
+     * Notifications are enabled by default.
+     *
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public static void disablePlatformNotifications() {
         checkThread();
-        Network.disablePlatformNotifications();
+        synchronized (WebView.class) {
+            Network.disablePlatformNotifications();
+            sNotificationsEnabled = false;
+            Context context = JniUtil.getContext();
+            if (context != null)
+                disableProxyListener(context);
+        }
     }
 
     /**
@@ -1647,7 +1686,9 @@
      * @param dest The file to store the serialized picture data. Will be
      *             overwritten with this WebView's picture data.
      * @return True if the picture was successfully saved.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public boolean savePicture(Bundle b, final File dest) {
         checkThread();
         if (dest == null || b == null) {
@@ -1710,7 +1751,9 @@
      * @param b A Bundle containing the saved display data.
      * @param src The file where the picture data was stored.
      * @return True if the picture was successfully restored.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public boolean restorePicture(Bundle b, File src) {
         checkThread();
         if (src == null || b == null) {
@@ -3729,7 +3772,9 @@
      * Set the Picture listener. This is an interface used to receive
      * notifications of a new Picture.
      * @param listener An implementation of WebView.PictureListener.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public void setPictureListener(PictureListener listener) {
         checkThread();
         mPictureListener = listener;
@@ -5095,7 +5140,9 @@
     /**
      * Use this method to put the WebView into text selection mode.
      * Do not rely on this functionality; it will be deprecated in the future.
+     * @deprecated This method is now obsolete.
      */
+    @Deprecated
     public void emulateShiftHeld() {
         checkThread();
         setUpSelect(false, 0, 0);
@@ -8798,6 +8845,10 @@
         mWebViewCore.sendMessage(EventHub.SET_BACKGROUND_COLOR, color);
     }
 
+    /**
+     * @deprecated This method is now obsolete.
+     */
+    @Deprecated
     public void debugDump() {
         checkThread();
         nativeDebugDump();
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fa662ed..358e0e0 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1839,7 +1839,7 @@
 
     <!-- Do not translate.  WebView User Agent string -->
     <string name="web_user_agent" translatable="false">Mozilla/5.0 (Linux; U; <xliff:g id="x">Android %s</xliff:g>)
-        AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.13</string>
+        AppleWebKit/534.16 (KHTML, like Gecko) Version/4.0 <xliff:g id="mobile">%s</xliff:g>Safari/534.16</string>
     <!-- Do not translate.  WebView User Agent targeted content -->
     <string name="web_user_agent_target_content" translatable="false">"Mobile "</string>
 
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 089577d..59093c9 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -161,8 +161,24 @@
     MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME     = 1001,
     MEDIA_RECORDER_TRACK_INFO_TYPE                 = 1002,
     MEDIA_RECORDER_TRACK_INFO_DURATION_MS          = 1003,
+
+    // The time to measure the max chunk duration
     MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS     = 1004,
+
     MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES       = 1005,
+
+    // The time to measure how well the audio and video
+    // track data is interleaved.
+    MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS       = 1006,
+
+    // The time to measure system response. Note that
+    // the delay does not include the intentional delay
+    // we use to eliminate the recording sound.
+    MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS     = 1007,
+
+    // The time used to compensate for initial A/V sync.
+    MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS      = 1008,
+
     MEDIA_RECORDER_TRACK_INFO_LIST_END             = 2000,
 };
 
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 57624e9..4b5674e 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -108,6 +108,13 @@
     struct ChunkInfo {
         Track               *mTrack;        // Owner
         List<Chunk>         mChunks;        // Remaining chunks to be written
+
+        // Previous chunk timestamp that has been written
+        int64_t mPrevChunkTimestampUs;
+
+        // Max time interval between neighboring chunks
+        int64_t mMaxInterChunkDurUs;
+
     };
 
     bool            mIsFirstChunk;
@@ -162,6 +169,7 @@
     void writeMvhdBox(int64_t durationUs);
     void writeMoovBox(int64_t durationUs);
     void writeFtypBox(const MetaData *param);
+    void sendSessionSummary();
 
     MPEG4Writer(const MPEG4Writer &);
     MPEG4Writer &operator=(const MPEG4Writer &);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 9ed08a3..fd60f06 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -45,6 +45,7 @@
 static const int64_t kMax32BitFileSize = 0x007fffffffLL;
 static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
 static const uint8_t kNalUnitTypePicParamSet = 0x08;
+static const int64_t kInitialDelayTimeUs     = 700000LL;
 
 // Using longer adjustment period to suppress fluctuations in
 // the audio encoding paths
@@ -69,6 +70,7 @@
     bool isAudio() const { return mIsAudio; }
     bool isMPEG4() const { return mIsMPEG4; }
     void addChunkOffset(off64_t offset);
+    int32_t getTrackId() const { return mTrackId; }
     status_t dump(int fd, const Vector<String16>& args) const;
 
 private:
@@ -157,6 +159,8 @@
 
     bool mReachedEOS;
     int64_t mStartTimestampUs;
+    int64_t mStartTimeRealUs;
+    int64_t mFirstSampleTimeRealUs;
     int64_t mPreviousTrackTimeUs;
     int64_t mTrackEveryTimeDurationUs;
 
@@ -688,6 +692,7 @@
     mFd = -1;
     mInitCheck = NO_INIT;
     mStarted = false;
+
     return err;
 }
 
@@ -744,6 +749,16 @@
     endBox();
 }
 
+void MPEG4Writer::sendSessionSummary() {
+    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
+         it != mChunkInfos.end(); ++it) {
+        int trackNum = it->mTrack->getTrackId() << 28;
+        notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+                trackNum | MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS,
+                it->mMaxInterChunkDurUs);
+    }
+}
+
 status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
     mInterleaveDurationUs = durationUs;
     return OK;
@@ -1188,18 +1203,13 @@
 void MPEG4Writer::writeAllChunks() {
     LOGV("writeAllChunks");
     size_t outstandingChunks = 0;
-    while (!mChunkInfos.empty()) {
-        List<ChunkInfo>::iterator it = mChunkInfos.begin();
-        while (!it->mChunks.empty()) {
-            Chunk chunk;
-            if (findChunkToWrite(&chunk)) {
-                writeChunkToFile(&chunk);
-                ++outstandingChunks;
-            }
-        }
-        it->mTrack = NULL;
-        mChunkInfos.erase(it);
+    Chunk chunk;
+    while (findChunkToWrite(&chunk)) {
+        ++outstandingChunks;
     }
+
+    sendSessionSummary();
+
     mChunkInfos.clear();
     LOGD("%d chunks are written in the last batch", outstandingChunks);
 }
@@ -1207,8 +1217,6 @@
 bool MPEG4Writer::findChunkToWrite(Chunk *chunk) {
     LOGV("findChunkToWrite");
 
-    // Find the smallest timestamp, and write that chunk out
-    // XXX: What if some track is just too slow?
     int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL;
     Track *track = NULL;
     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
@@ -1237,6 +1245,13 @@
             *chunk = *(it->mChunks.begin());
             it->mChunks.erase(it->mChunks.begin());
             CHECK_EQ(chunk->mTrack, track);
+
+            int64_t interChunkTimeUs =
+                chunk->mTimeStampUs - it->mPrevChunkTimestampUs;
+            if (interChunkTimeUs > it->mPrevChunkTimestampUs) {
+                it->mMaxInterChunkDurUs = interChunkTimeUs;
+            }
+
             return true;
         }
     }
@@ -1280,6 +1295,8 @@
          it != mTracks.end(); ++it) {
         ChunkInfo info;
         info.mTrack = *it;
+        info.mPrevChunkTimestampUs = 0;
+        info.mMaxInterChunkDurUs = 0;
         mChunkInfos.push_back(info);
     }
 
@@ -1303,6 +1320,7 @@
     if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
         startTimeUs = 0;
     }
+    mStartTimeRealUs = startTimeUs;
 
     int32_t rotationDegrees;
     if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) {
@@ -1330,7 +1348,7 @@
          * Ideally, this platform-specific value should be defined
          * in media_profiles.xml file
          */
-        startTimeUs += 700000;
+        startTimeUs += kInitialDelayTimeUs;
     }
 
     meta->setInt64(kKeyTime, startTimeUs);
@@ -1937,7 +1955,8 @@
         LOGV("%s timestampUs: %lld", mIsAudio? "Audio": "Video", timestampUs);
 
 ////////////////////////////////////////////////////////////////////////////////
-        if (mSampleSizes.empty()) {
+        if (mNumSamples == 0) {
+            mFirstSampleTimeRealUs = systemTime() / 1000;
             mStartTimestampUs = timestampUs;
             mOwner->setStartTimestampUs(mStartTimestampUs);
             previousPausedDurationUs = mStartTimestampUs;
@@ -2135,10 +2154,26 @@
                     trackNum | MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES,
                     mNumSamples);
 
+    // The system delay time excluding the requested initial delay that
+    // is used to eliminate the recording sound.
+    int64_t initialDelayUs =
+        mFirstSampleTimeRealUs - mStartTimeRealUs - kInitialDelayTimeUs;
+    mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+                    trackNum | MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS,
+                    (initialDelayUs) / 1000);
+
     if (hasMultipleTracks) {
         mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
                     trackNum | MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS,
                     mMaxChunkDurationUs / 1000);
+
+        int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
+        if (mStartTimestampUs != moovStartTimeUs) {
+            int64_t startTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
+            mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+                    trackNum | MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS,
+                    startTimeOffsetUs / 1000);
+        }
     }
 }
 
@@ -2604,6 +2639,7 @@
     mOwner->beginBox("stts");
     mOwner->writeInt32(0);  // version=0, flags=0
     mOwner->writeInt32(mNumSttsTableEntries);
+
     // Compensate for small start time difference from different media tracks
     int64_t trackStartTimeOffsetUs = 0;
     int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 27ff656..ce67390 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -458,6 +458,9 @@
         Registrant r = new Registrant (h, what, obj);
         mIccRefreshRegistrants.add(r);
     }
+    public void setOnIccRefresh(Handler h, int what, Object obj) {
+        registerForIccRefresh(h, what, obj);
+    }
 
     public void setEmergencyCallbackMode(Handler h, int what, Object obj) {
         mEmergencyCallbackModeRegistrant = new Registrant (h, what, obj);
@@ -466,6 +469,9 @@
     public void unregisterForIccRefresh(Handler h) {
         mIccRefreshRegistrants.remove(h);
     }
+    public void unsetOnIccRefresh(Handler h) {
+        unregisterForIccRefresh(h);
+    }
 
     public void setOnCallRing(Handler h, int what, Object obj) {
         mRingRegistrant = new Registrant (h, what, obj);
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index f87d188..96788ef 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -360,6 +360,9 @@
     void registerForIccRefresh(Handler h, int what, Object obj);
     void unregisterForIccRefresh(Handler h);
 
+    void setOnIccRefresh(Handler h, int what, Object obj);
+    void unsetOnIccRefresh(Handler h);
+
     /**
      * Sets the handler for RING notifications.
      * Unlike the register* methods, there's only one notification handler