Merge "Move ApplicationPackageManager out of ContextImpl.java"
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index b535fc1..5bfa1b2 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -17,11 +17,38 @@
 package com.android.internal.backup;
 
 import android.app.backup.RestoreSet;
+import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.os.ParcelFileDescriptor;
 
 /** {@hide} */
 interface IBackupTransport {
+	/**
+	 * Ask the transport for an Intent that can be used to launch any internal
+	 * configuration Activity that it wishes to present.  For example, the transport
+	 * may offer a UI for allowing the user to supply login credentials for the
+	 * transport's off-device backend.
+	 *
+	 * If the transport does not supply any user-facing configuration UI, it should
+	 * return null from this method.
+	 *
+	 * @return An Intent that can be passed to Context.startActivity() in order to
+	 *         launch the transport's configuration UI.  This method will return null
+	 *         if the transport does not offer any user-facing configuration UI.
+	 */
+	Intent configurationIntent();
+
+	/**
+	 * On demand, supply a one-line string that can be shown to the user that
+	 * describes the current backend destination.  For example, a transport that
+	 * can potentially associate backup data with arbitrary user accounts should
+	 * include the name of the currently-active account here.
+	 *
+	 * @return A string describing the destination to which the transport is currently
+	 *         sending data.  This method should not return null.
+	 */
+	String currentDestinationString();
+
     /**
      * Ask the transport where, on local device storage, to keep backup state blobs.
      * This is per-transport so that mock transports used for testing can coexist with
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index b436363..45f8599 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -20,6 +20,7 @@
 import android.app.backup.BackupDataOutput;
 import android.app.backup.RestoreSet;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -49,11 +50,13 @@
     private static final String TRANSPORT_DIR_NAME
             = "com.android.internal.backup.LocalTransport";
 
+    private static final String TRANSPORT_DESTINATION_STRING
+            = "Backing up to debug-only private cache";
+
     // The single hardcoded restore set always has the same (nonzero!) token
     private static final long RESTORE_TOKEN = 1;
 
     private Context mContext;
-    private PackageManager mPackageManager;
     private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup");
     private PackageInfo[] mRestorePackages = null;
     private int mRestorePackage = -1;  // Index into mRestorePackages
@@ -61,9 +64,16 @@
 
     public LocalTransport(Context context) {
         mContext = context;
-        mPackageManager = context.getPackageManager();
     }
 
+    public Intent configurationIntent() {
+        // The local transport is not user-configurable
+        return null;
+    }
+
+    public String currentDestinationString() {
+        return TRANSPORT_DESTINATION_STRING;
+    }
 
     public String transportDirName() {
         return TRANSPORT_DIR_NAME;
diff --git a/media/java/android/media/videoeditor/VideoEditorTestImpl.java b/media/java/android/media/videoeditor/VideoEditorTestImpl.java
index 157dd62..ca896c3 100644
--- a/media/java/android/media/videoeditor/VideoEditorTestImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorTestImpl.java
@@ -748,121 +748,126 @@
      */
     private void load() throws FileNotFoundException, XmlPullParserException, IOException {
         final File file = new File(mProjectPath, PROJECT_FILENAME);
-        // Load the metadata
-        final XmlPullParser parser = Xml.newPullParser();
         final FileInputStream fis = new FileInputStream(file);
-        parser.setInput(fis, "UTF-8");
-        int eventType = parser.getEventType();
-        String name;
-        MediaItem currentMediaItem = null;
-        Overlay currentOverlay = null;
-        while (eventType != XmlPullParser.END_DOCUMENT) {
-            switch (eventType) {
-                case XmlPullParser.START_TAG: {
-                    name = parser.getName();
-                    if (TAG_PROJECT.equals(name)) {
-                        mAspectRatio = Integer.parseInt(parser.getAttributeValue("",
-                                ATTR_ASPECT_RATIO));
-                    } else if (TAG_MEDIA_ITEM.equals(name)) {
-                        final String mediaItemId = parser.getAttributeValue("", ATTR_ID);
-                        final String type = parser.getAttributeValue("", ATTR_TYPE);
-                        final String filename = parser.getAttributeValue("", ATTR_FILENAME);
-                        final int renderingMode = Integer.parseInt(parser.getAttributeValue("",
-                                ATTR_RENDERING_MODE));
 
-                        if (MediaImageItem.class.getSimpleName().equals(type)) {
-                            final long durationMs = Long.parseLong(parser.getAttributeValue("",
-                                    ATTR_DURATION));
-                            currentMediaItem = new MediaImageItem(this, mediaItemId, filename,
-                                    durationMs, renderingMode);
-                        } else if (MediaVideoItem.class.getSimpleName().equals(type)) {
-                            final long beginMs = Long.parseLong(parser.getAttributeValue("",
-                                    ATTR_BEGIN_TIME));
-                            final long endMs = Long.parseLong(parser.getAttributeValue("",
-                                    ATTR_END_TIME));
-                            final int volume = Integer.parseInt(parser.getAttributeValue("",
-                                    ATTR_VOLUME));
-                            final boolean muted = Boolean.parseBoolean(parser.getAttributeValue("",
-                                    ATTR_MUTED));
-                            final String audioWaveformFilename = parser.getAttributeValue("",
-                                    ATTR_AUDIO_WAVEFORM_FILENAME);
-                            currentMediaItem = new MediaVideoItem(this, mediaItemId, filename,
-                                    renderingMode, beginMs, endMs, volume, muted,
-                                    audioWaveformFilename);
+        try {
+            // Load the metadata
+            final XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(fis, "UTF-8");
+            int eventType = parser.getEventType();
+            String name;
+            MediaItem currentMediaItem = null;
+            Overlay currentOverlay = null;
+            while (eventType != XmlPullParser.END_DOCUMENT) {
+                switch (eventType) {
+                    case XmlPullParser.START_TAG: {
+                        name = parser.getName();
+                        if (TAG_PROJECT.equals(name)) {
+                            mAspectRatio = Integer.parseInt(parser.getAttributeValue("",
+                                    ATTR_ASPECT_RATIO));
+                        } else if (TAG_MEDIA_ITEM.equals(name)) {
+                            final String mediaItemId = parser.getAttributeValue("", ATTR_ID);
+                            final String type = parser.getAttributeValue("", ATTR_TYPE);
+                            final String filename = parser.getAttributeValue("", ATTR_FILENAME);
+                            final int renderingMode = Integer.parseInt(
+                                    parser.getAttributeValue("", ATTR_RENDERING_MODE));
 
-                            final long beginTimeMs = Long.parseLong(parser.getAttributeValue("",
-                                    ATTR_BEGIN_TIME));
-                            final long endTimeMs = Long.parseLong(parser.getAttributeValue("",
-                                    ATTR_END_TIME));
-                            ((MediaVideoItem)currentMediaItem).setExtractBoundaries(beginTimeMs,
-                                    endTimeMs);
+                            if (MediaImageItem.class.getSimpleName().equals(type)) {
+                                final long durationMs = Long.parseLong(
+                                        parser.getAttributeValue("", ATTR_DURATION));
+                                currentMediaItem = new MediaImageItem(this, mediaItemId, filename,
+                                        durationMs, renderingMode);
+                            } else if (MediaVideoItem.class.getSimpleName().equals(type)) {
+                                final long beginMs = Long.parseLong(
+                                        parser.getAttributeValue("", ATTR_BEGIN_TIME));
+                                final long endMs = Long.parseLong(
+                                        parser.getAttributeValue("", ATTR_END_TIME));
+                                final int volume = Integer.parseInt(
+                                        parser.getAttributeValue("", ATTR_VOLUME));
+                                final boolean muted = Boolean.parseBoolean(
+                                        parser.getAttributeValue("", ATTR_MUTED));
+                                final String audioWaveformFilename =
+                                        parser.getAttributeValue("", ATTR_AUDIO_WAVEFORM_FILENAME);
+                                currentMediaItem = new MediaVideoItem(this, mediaItemId, filename,
+                                        renderingMode, beginMs, endMs, volume, muted,
+                                        audioWaveformFilename);
 
-                            final int volumePercent = Integer.parseInt(parser.getAttributeValue("",
-                                    ATTR_VOLUME));
-                            ((MediaVideoItem)currentMediaItem).setVolume(volumePercent);
-                        } else {
-                            Log.e(TAG, "Unknown media item type: " + type);
-                            currentMediaItem = null;
-                        }
+                                final long beginTimeMs = Long.parseLong(
+                                        parser.getAttributeValue("", ATTR_BEGIN_TIME));
+                                final long endTimeMs = Long.parseLong(
+                                        parser.getAttributeValue("", ATTR_END_TIME));
+                                ((MediaVideoItem)currentMediaItem).setExtractBoundaries(
+                                        beginTimeMs, endTimeMs);
 
-                        if (currentMediaItem != null) {
-                            mMediaItems.add(currentMediaItem);
-                        }
-                    } else if (TAG_TRANSITION.equals(name)) {
-                        final Transition transition = parseTransition(parser);
-                        if (transition != null) {
-                            mTransitions.add(transition);
-                        }
-                    } else if (TAG_OVERLAY.equals(name)) {
-                        if (currentMediaItem != null) {
-                            currentOverlay = parseOverlay(parser, currentMediaItem);
+                                final int volumePercent = Integer.parseInt(
+                                        parser.getAttributeValue("", ATTR_VOLUME));
+                                ((MediaVideoItem)currentMediaItem).setVolume(volumePercent);
+                            } else {
+                                Log.e(TAG, "Unknown media item type: " + type);
+                                currentMediaItem = null;
+                            }
+
+                            if (currentMediaItem != null) {
+                                mMediaItems.add(currentMediaItem);
+                            }
+                        } else if (TAG_TRANSITION.equals(name)) {
+                            final Transition transition = parseTransition(parser);
+                            if (transition != null) {
+                                mTransitions.add(transition);
+                            }
+                        } else if (TAG_OVERLAY.equals(name)) {
+                            if (currentMediaItem != null) {
+                                currentOverlay = parseOverlay(parser, currentMediaItem);
+                                if (currentOverlay != null) {
+                                    currentMediaItem.addOverlay(currentOverlay);
+                                }
+                            }
+                        } else if (TAG_OVERLAY_USER_ATTRIBUTES.equals(name)) {
                             if (currentOverlay != null) {
-                                currentMediaItem.addOverlay(currentOverlay);
+                                final int attributesCount = parser.getAttributeCount();
+                                for (int i = 0; i < attributesCount; i++) {
+                                    currentOverlay.setUserAttribute(parser.getAttributeName(i),
+                                            parser.getAttributeValue(i));
+                                }
+                            }
+                        } else if (TAG_EFFECT.equals(name)) {
+                            if (currentMediaItem != null) {
+                                final Effect effect = parseEffect(parser, currentMediaItem);
+                                if (effect != null) {
+                                    currentMediaItem.addEffect(effect);
+                                }
+                            }
+                        } else if (TAG_AUDIO_TRACK.equals(name)) {
+                            final AudioTrack audioTrack = parseAudioTrack(parser);
+                            if (audioTrack != null) {
+                                addAudioTrack(audioTrack);
                             }
                         }
-                    } else if (TAG_OVERLAY_USER_ATTRIBUTES.equals(name)) {
-                        if (currentOverlay != null) {
-                            final int attributesCount = parser.getAttributeCount();
-                            for (int i = 0; i < attributesCount; i++) {
-                                currentOverlay.setUserAttribute(parser.getAttributeName(i),
-                                        parser.getAttributeValue(i));
-                            }
-                        }
-                    } else if (TAG_EFFECT.equals(name)) {
-                        if (currentMediaItem != null) {
-                            final Effect effect = parseEffect(parser, currentMediaItem);
-                            if (effect != null) {
-                                currentMediaItem.addEffect(effect);
-                            }
-                        }
-                    } else if (TAG_AUDIO_TRACK.equals(name)) {
-                        final AudioTrack audioTrack = parseAudioTrack(parser);
-                        if (audioTrack != null) {
-                            addAudioTrack(audioTrack);
-                        }
+                        break;
                     }
-                    break;
-                }
 
-                case XmlPullParser.END_TAG: {
-                    name = parser.getName();
-                    if (TAG_MEDIA_ITEM.equals(name)) {
-                        currentMediaItem = null;
-                    } else if (TAG_OVERLAY.equals(name)) {
-                        currentOverlay = null;
+                    case XmlPullParser.END_TAG: {
+                        name = parser.getName();
+                        if (TAG_MEDIA_ITEM.equals(name)) {
+                            currentMediaItem = null;
+                        } else if (TAG_OVERLAY.equals(name)) {
+                            currentOverlay = null;
+                        }
+                        break;
                     }
-                    break;
-                }
 
-                default: {
-                    break;
+                    default: {
+                        break;
+                    }
                 }
+                eventType = parser.next();
             }
-            eventType = parser.next();
+            computeTimelineDuration();
+        } finally {
+            if (fis != null) {
+                fis.close();
+            }
         }
-
-        fis.close();
-        computeTimelineDuration();
     }
 
     /**
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 9da5f01..5f9b6e6 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1442,6 +1442,7 @@
     mCameraSourceTimeLapse = NULL;
     mIsMetaDataStoredInVideoBuffers = false;
     mEncoderProfiles = MediaProfiles::getInstance();
+    mRotationDegrees = 0;
 
     mOutputFd = -1;
     mOutputFdAux = -1;