Merge "Allow nav bar height to vary between portrait and landscape." into jb-dev
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3a5fdd1..2c49bd2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3270,6 +3270,12 @@
         public static final String WIFI_FREQUENCY_BAND = "wifi_frequency_band";
 
         /**
+         * The Wi-Fi peer-to-peer device name
+         * @hide
+         */
+        public static final String WIFI_P2P_DEVICE_NAME = "wifi_p2p_device_name";
+
+        /**
          * Maximum amount of time in milliseconds to hold a wakelock while waiting for mobile
          * data connectivity to be established after a disconnect from Wi-Fi.
          */
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index c4cb3a5..300bc68 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -588,6 +588,8 @@
 
     @Override
     protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         if (mAudioDevices.isEmpty()) return;
         pw.println("Cached audio devices:");
         for (BluetoothDevice device : mAudioDevices.keySet()) {
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 7a97455..a420734 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -1775,6 +1775,8 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         if (getBluetoothStateInternal() != BluetoothAdapter.STATE_ON) {
             return;
         }
diff --git a/core/java/android/service/dreams/DreamManagerService.java b/core/java/android/service/dreams/DreamManagerService.java
index 8712fa2..4a14ced 100644
--- a/core/java/android/service/dreams/DreamManagerService.java
+++ b/core/java/android/service/dreams/DreamManagerService.java
@@ -169,6 +169,8 @@
     
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         pw.println("Dreamland:");
         pw.print("  component="); pw.println(mCurrentDreamComponent);
         pw.print("  token="); pw.println(mCurrentDreamToken);
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 012e095..2a006c6 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -701,6 +701,21 @@
     }
 
     /**
+     * Get the stream type whose volume is driving the UI sounds volume.
+     * UI sounds are screen lock/unlock, camera shutter, key clicks...
+     * @hide
+     */
+    public int getMasterStreamType() {
+        IAudioService service = getService();
+        try {
+            return service.getMasterStreamType();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in getMasterStreamType", e);
+            return STREAM_RING;
+        }
+    }
+
+    /**
      * Sets the ringer mode.
      * <p>
      * Silent mode will mute the volume and will not vibrate. Vibrate mode will
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index dcf72cc..3e958dc 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -202,22 +202,39 @@
         15, // STREAM_DTMF
         15  // STREAM_TTS
     };
-    /* STREAM_VOLUME_ALIAS[] indicates for each stream if it uses the volume settings
+    /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
      * of another stream: This avoids multiplying the volume settings for hidden
      * stream types that follow other stream behavior for volume settings
-     * NOTE: do not create loops in aliases! */
+     * NOTE: do not create loops in aliases!
+     * Some streams alias to different streams according to device category (phone or tablet) or
+     * use case (in call s off call...).See updateStreamVolumeAlias() for more details
+     *  mStreamVolumeAlias contains the default aliases for a voice capable device (phone) and
+     *  STREAM_VOLUME_ALIAS_NON_VOICE for a non voice capable device (tablet).*/
     private final int[] STREAM_VOLUME_ALIAS = new int[] {
-        AudioSystem.STREAM_VOICE_CALL,  // STREAM_VOICE_CALL
-        AudioSystem.STREAM_SYSTEM,  // STREAM_SYSTEM
-        AudioSystem.STREAM_RING,  // STREAM_RING
-        AudioSystem.STREAM_MUSIC, // STREAM_MUSIC
-        AudioSystem.STREAM_ALARM,  // STREAM_ALARM
-        AudioSystem.STREAM_RING,   // STREAM_NOTIFICATION
-        AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO
-        AudioSystem.STREAM_SYSTEM,  // STREAM_SYSTEM_ENFORCED
-        AudioSystem.STREAM_VOICE_CALL, // STREAM_DTMF
-        AudioSystem.STREAM_MUSIC  // STREAM_TTS
+        AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
+        AudioSystem.STREAM_RING,            // STREAM_SYSTEM
+        AudioSystem.STREAM_RING,            // STREAM_RING
+        AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
+        AudioSystem.STREAM_ALARM,           // STREAM_ALARM
+        AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
+        AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
+        AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
+        AudioSystem.STREAM_RING,            // STREAM_DTMF
+        AudioSystem.STREAM_MUSIC            // STREAM_TTS
     };
+    private final int[] STREAM_VOLUME_ALIAS_NON_VOICE = new int[] {
+        AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
+        AudioSystem.STREAM_MUSIC,           // STREAM_SYSTEM
+        AudioSystem.STREAM_RING,            // STREAM_RING
+        AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
+        AudioSystem.STREAM_ALARM,           // STREAM_ALARM
+        AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
+        AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
+        AudioSystem.STREAM_MUSIC,           // STREAM_SYSTEM_ENFORCED
+        AudioSystem.STREAM_MUSIC,           // STREAM_DTMF
+        AudioSystem.STREAM_MUSIC            // STREAM_TTS
+    };
+    private int[] mStreamVolumeAlias;
 
     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
         public void onError(int error) {
@@ -333,7 +350,7 @@
     // message looper for SoundPool listener
     private Looper mSoundPoolLooper = null;
     // default volume applied to sound played with playSoundEffect()
-    private static final int SOUND_EFFECT_DEFAULT_VOLUME_DB = -20;
+    private static final int SOUND_EFFECT_DEFAULT_VOLUME_DB = 0;
     // volume applied to sound played with playSoundEffect() read from ro.config.sound_fx_volume
     private int SOUND_EFFECT_VOLUME_DB;
     // getActiveStreamType() will return STREAM_NOTIFICATION during this period after a notification
@@ -374,13 +391,14 @@
                 SOUND_EFFECT_DEFAULT_VOLUME_DB);
 
         mVolumePanel = new VolumePanel(context, this);
+        mMode = AudioSystem.MODE_NORMAL;
         mForcedUseForComm = AudioSystem.FORCE_NONE;
         createAudioSystemThread();
         readPersistedSettings();
         mSettingsObserver = new SettingsObserver();
+        updateStreamVolumeAlias(false /*updateVolumes*/);
         createStreamStates();
 
-        mMode = AudioSystem.MODE_NORMAL;
         mMediaServerOk = true;
 
         // Call setRingerModeInt() to apply correct mute
@@ -459,26 +477,54 @@
         VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
 
         for (int i = 0; i < numStreamTypes; i++) {
-            streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[STREAM_VOLUME_ALIAS[i]], i);
+            streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[mStreamVolumeAlias[i]], i);
         }
 
         // Correct stream index values for streams with aliases
         for (int i = 0; i < numStreamTypes; i++) {
             int device = getDeviceForStream(i);
-            if (STREAM_VOLUME_ALIAS[i] != i) {
+            if (mStreamVolumeAlias[i] != i) {
                 int index = rescaleIndex(streams[i].getIndex(device, false  /* lastAudible */),
-                                STREAM_VOLUME_ALIAS[i],
+                                mStreamVolumeAlias[i],
                                 i);
                 streams[i].mIndex.put(device, streams[i].getValidIndex(index));
                 streams[i].applyDeviceVolume(device);
                 index = rescaleIndex(streams[i].getIndex(device, true  /* lastAudible */),
-                            STREAM_VOLUME_ALIAS[i],
+                            mStreamVolumeAlias[i],
                             i);
                 streams[i].mLastAudibleIndex.put(device, streams[i].getValidIndex(index));
             }
         }
     }
 
+
+    private void updateStreamVolumeAlias(boolean updateVolumes) {
+        int dtmfStreamAlias;
+        if (mVoiceCapable) {
+            mStreamVolumeAlias = STREAM_VOLUME_ALIAS;
+            dtmfStreamAlias = AudioSystem.STREAM_RING;
+        } else {
+            mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NON_VOICE;
+            dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
+        }
+        if (isInCommunication()) {
+            dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
+        }
+        mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
+        if (updateVolumes) {
+            mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
+                                                                 false /*lastAudible*/);
+            mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias],
+                                                                 true /*lastAudible*/);
+            sendMsg(mAudioHandler,
+                    MSG_SET_ALL_VOLUMES,
+                    SENDMSG_QUEUE,
+                    0,
+                    0,
+                    mStreamStates[AudioSystem.STREAM_DTMF], 0);
+        }
+    }
+
     private void readPersistedSettings() {
         final ContentResolver cr = mContentResolver;
 
@@ -555,7 +601,7 @@
 
         // Play sounds on STREAM_RING only and if lock screen is not on.
         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
-                ((STREAM_VOLUME_ALIAS[streamType] != AudioSystem.STREAM_RING)
+                ((mStreamVolumeAlias[streamType] != AudioSystem.STREAM_RING)
                  || (mKeyguardManager != null && mKeyguardManager.isKeyguardLocked()))) {
             flags &= ~AudioManager.FLAG_PLAY_SOUND;
         }
@@ -571,7 +617,7 @@
         // use stream type alias here so that streams with same alias have the same behavior,
         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
-        int streamTypeAlias = STREAM_VOLUME_ALIAS[streamType];
+        int streamTypeAlias = mStreamVolumeAlias[streamType];
         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
 
         final int device = getDeviceForStream(streamTypeAlias);
@@ -603,7 +649,7 @@
                 // on last audible index for an alias would not give the correct value
                 int numStreamTypes = AudioSystem.getNumStreamTypes();
                 for (int i = numStreamTypes - 1; i >= 0; i--) {
-                    if (STREAM_VOLUME_ALIAS[i] == streamTypeAlias) {
+                    if (mStreamVolumeAlias[i] == streamTypeAlias) {
                         VolumeStreamState s = mStreamStates[i];
 
                         s.adjustLastAudibleIndex(direction, device);
@@ -656,7 +702,7 @@
     /** @see AudioManager#setStreamVolume(int, int, int) */
     public void setStreamVolume(int streamType, int index, int flags) {
         ensureValidStreamType(streamType);
-        VolumeStreamState streamState = mStreamStates[STREAM_VOLUME_ALIAS[streamType]];
+        VolumeStreamState streamState = mStreamStates[mStreamVolumeAlias[streamType]];
 
         final int device = getDeviceForStream(streamType);
         // get last audible index if stream is muted, current index otherwise
@@ -665,13 +711,13 @@
 
         // setting ring or notifications volume to 0 on voice capable devices enters silent mode
         if (mVoiceCapable && (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
-                (STREAM_VOLUME_ALIAS[streamType] == AudioSystem.STREAM_RING))) {
+                (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING))) {
             int newRingerMode;
             if (index == 0) {
                 newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
                     ? AudioManager.RINGER_MODE_VIBRATE
                     : AudioManager.RINGER_MODE_SILENT;
-                setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType],
+                setStreamVolumeInt(mStreamVolumeAlias[streamType],
                                    index,
                                    device,
                                    false,
@@ -682,8 +728,8 @@
             setRingerMode(newRingerMode);
         }
 
-        index = rescaleIndex(index * 10, streamType, STREAM_VOLUME_ALIAS[streamType]);
-        setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, device, false, true);
+        index = rescaleIndex(index * 10, streamType, mStreamVolumeAlias[streamType]);
+        setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, false, true);
         // get last audible index if stream is muted, current index otherwise
         index = streamState.getIndex(device,
                                      (streamState.muteCount() != 0) /* lastAudible */);
@@ -964,6 +1010,15 @@
         return Math.round(AudioSystem.getMasterVolume() * MAX_MASTER_VOLUME);
     }
 
+    /** @see AudioManager#getMasterStreamType(int) */
+    public int getMasterStreamType() {
+        if (mVoiceCapable) {
+            return AudioSystem.STREAM_RING;
+        } else {
+            return AudioSystem.STREAM_MUSIC;
+        }
+    }
+
     /** @see AudioManager#getRingerMode() */
     public int getRingerMode() {
         synchronized(mSettingsLock) {
@@ -1004,7 +1059,7 @@
                     // ring and notifications volume should never be 0 when not silenced
                     // on voice capable devices
                     if (mVoiceCapable &&
-                            STREAM_VOLUME_ALIAS[streamType] == AudioSystem.STREAM_RING) {
+                            mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
 
                         Set set = mStreamStates[streamType].mLastAudibleIndex.entrySet();
                         Iterator i = set.iterator();
@@ -1244,8 +1299,10 @@
             }
             int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
             int device = getDeviceForStream(streamType);
-            int index = mStreamStates[STREAM_VOLUME_ALIAS[streamType]].getIndex(device, false);
-            setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, device, true, false);
+            int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device, false);
+            setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true, false);
+
+            updateStreamVolumeAlias(true /*updateVolumes*/);
         }
         return newModeOwnerPid;
     }
@@ -1978,18 +2035,23 @@
         }
     }
 
-    private int getActiveStreamType(int suggestedStreamType) {
+    private boolean isInCommunication() {
+        boolean isOffhook = false;
 
         if (mVoiceCapable) {
-            boolean isOffhook = false;
             try {
                 ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
                 if (phone != null) isOffhook = phone.isOffhook();
             } catch (RemoteException e) {
                 Log.w(TAG, "Couldn't connect to phone service", e);
             }
+        }
+        return (isOffhook || getMode() == AudioManager.MODE_IN_COMMUNICATION);
+    }
 
-            if (isOffhook || getMode() == AudioManager.MODE_IN_COMMUNICATION) {
+    private int getActiveStreamType(int suggestedStreamType) {
+        if (mVoiceCapable) {
+            if (isInCommunication()) {
                 if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
                         == AudioSystem.FORCE_BT_SCO) {
                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
@@ -2010,7 +2072,7 @@
                 return suggestedStreamType;
             }
         } else {
-            if (getMode() == AudioManager.MODE_IN_COMMUNICATION) {
+            if (isInCommunication()) {
                 if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
                         == AudioSystem.FORCE_BT_SCO) {
                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
@@ -2181,7 +2243,7 @@
                 // 0 without the device being in silent mode
                 if ((lastAudibleIndex == 0) &&
                         (mVoiceCapable ||
-                         (STREAM_VOLUME_ALIAS[mStreamType] != AudioSystem.STREAM_MUSIC))) {
+                         (mStreamVolumeAlias[mStreamType] != AudioSystem.STREAM_MUSIC))) {
                     lastAudibleIndex = AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
                     // Correct the data base
                     sendMsg(mAudioHandler,
@@ -2198,7 +2260,7 @@
                 // this is permitted on tablets for music stream type.
                 if (checkSilentVolume && (index == 0) &&
                         (mVoiceCapable ||
-                         (STREAM_VOLUME_ALIAS[mStreamType] != AudioSystem.STREAM_MUSIC))) {
+                         (mStreamVolumeAlias[mStreamType] != AudioSystem.STREAM_MUSIC))) {
                     index = lastAudibleIndex;
                     // Correct the data base
                     sendMsg(mAudioHandler,
@@ -2258,11 +2320,11 @@
                 // Apply change to all streams using this one as alias
                 int numStreamTypes = AudioSystem.getNumStreamTypes();
                 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
-                    if (streamType != mStreamType && STREAM_VOLUME_ALIAS[streamType] == mStreamType) {
+                    if (streamType != mStreamType && mStreamVolumeAlias[streamType] == mStreamType) {
                         mStreamStates[streamType].setIndex(rescaleIndex(index,
                                                                         mStreamType,
                                                                         streamType),
-                                                           device,
+                                                           getDeviceForStream(streamType),
                                                            lastAudible);
                     }
                 }
@@ -2301,6 +2363,27 @@
             return mIndexMax;
         }
 
+        public HashMap <Integer, Integer> getAllIndexes(boolean lastAudible) {
+            if (lastAudible) {
+                return mLastAudibleIndex;
+            } else {
+                return mIndex;
+            }
+        }
+
+        public void setAllIndexes(VolumeStreamState srcStream, boolean lastAudible) {
+            HashMap <Integer, Integer> indexes = srcStream.getAllIndexes(lastAudible);
+            Set set = indexes.entrySet();
+            Iterator i = set.iterator();
+            while (i.hasNext()) {
+                Map.Entry entry = (Map.Entry)i.next();
+                int device = ((Integer)entry.getKey()).intValue();
+                int index = ((Integer)entry.getValue()).intValue();
+                index = rescaleIndex(index, srcStream.getStreamType(), mStreamType);
+                setIndex(index, device, lastAudible);
+            }
+        }
+
         public void mute(IBinder cb, boolean state) {
             VolumeDeathHandler handler = getDeathHandler(cb, state);
             if (handler == null) {
@@ -2310,6 +2393,10 @@
             handler.mute(state);
         }
 
+        public int getStreamType() {
+            return mStreamType;
+        }
+
         private int getValidIndex(int index) {
             if (index < 0) {
                 return 0;
@@ -2484,8 +2571,8 @@
             int numStreamTypes = AudioSystem.getNumStreamTypes();
             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
                 if (streamType != streamState.mStreamType &&
-                        STREAM_VOLUME_ALIAS[streamType] == streamState.mStreamType) {
-                    mStreamStates[streamType].applyDeviceVolume(device);
+                        mStreamVolumeAlias[streamType] == streamState.mStreamType) {
+                    mStreamStates[streamType].applyDeviceVolume(getDeviceForStream(streamType));
                 }
             }
 
@@ -2509,7 +2596,7 @@
             int numStreamTypes = AudioSystem.getNumStreamTypes();
             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
                 if (streamType != streamState.mStreamType &&
-                        STREAM_VOLUME_ALIAS[streamType] == streamState.mStreamType) {
+                        mStreamVolumeAlias[streamType] == streamState.mStreamType) {
                     mStreamStates[streamType].applyAllVolumes();
                 }
             }
@@ -4145,6 +4232,8 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         // TODO probably a lot more to do here than just the audio focus and remote control stacks
         dumpFocusStack(pw);
         dumpRCStack(pw);
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 0311c59..df21040 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -117,4 +117,6 @@
     void stopBluetoothSco(IBinder cb);
 
     void forceVolumeControlStream(int streamType, IBinder cb);
+
+    int getMasterStreamType();
 }
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 8fbab74..b905db3 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -54,6 +54,7 @@
                 android:src="@drawable/ic_sysbar_back"
                 systemui:keyCode="4"
                 android:layout_weight="0"
+                android:scaleType="center"
                 systemui:glowBackground="@drawable/ic_sysbar_highlight"
                 android:contentDescription="@string/accessibility_back"
                 />
@@ -214,6 +215,7 @@
                 android:layout_height="80dp"
                 android:layout_width="match_parent"
                 android:src="@drawable/ic_sysbar_back_land"
+                android:scaleType="center"
                 systemui:keyCode="4"
                 android:layout_weight="0"
                 android:contentDescription="@string/accessibility_back"
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 1ae15be..ae568f8 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -111,14 +111,6 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump StatusBar from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
-            return;
-        }
-
         if (args == null || args.length == 0) {
             for (SystemUI ui: mServices) {
                 pw.println("dumping service: " + ui.getClass().getName());
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index fe7d5aa..3c30f5d 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -241,7 +241,7 @@
                 if (soundUri != null) {
                     final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
                     if (sfx != null) {
-                        sfx.setStreamType(AudioManager.STREAM_NOTIFICATION);
+                        sfx.setStreamType(AudioManager.STREAM_SYSTEM);
                         sfx.play();
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 8d9fcce6..424317a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Message;
 import android.os.ServiceManager;
@@ -71,6 +72,8 @@
     int mDisabledFlags = 0;
     int mNavigationIconHints = 0;
 
+    private Drawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon;
+
     private DelegateViewHelper mDelegateHelper;
 
     // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
@@ -146,6 +149,11 @@
         mVertical = false;
         mShowMenu = false;
         mDelegateHelper = new DelegateViewHelper(this);
+
+        mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
+        mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land);
+        mBackAltIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
+        mBackAltLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
     }
 
     View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
@@ -188,10 +196,10 @@
         getRecentsButton().setAlpha(
             (0 != (hints & StatusBarManager.NAVIGATION_HINT_RECENT_NOP)) ? 0.5f : 1.0f);
 
-        ((ImageView)getBackButton()).setImageResource(
+        ((ImageView)getBackButton()).setImageDrawable(
             (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT))
-                ? R.drawable.ic_sysbar_back_ime
-                : R.drawable.ic_sysbar_back);
+                ? (mVertical ? mBackAltLandIcon : mBackAltIcon)
+                : (mVertical ? mBackLandIcon : mBackIcon));
     }
 
     public void setDisabledFlags(int disabledFlags) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 5b9160d..fec9530 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -149,11 +149,7 @@
     private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true;
 
     /** The stream type that the lock sounds are tied to. */
-    private static final int MASTER_STREAM_TYPE = AudioManager.STREAM_RING;
-    /** Minimum volume for lock sounds, as a ratio of max MASTER_STREAM_TYPE */
-    final float MIN_LOCK_VOLUME = 0.05f;
-    /** Maximum volume for lock sounds, as a ratio of max MASTER_STREAM_TYPE */
-    final float MAX_LOCK_VOLUME = 0.4f;
+    private int mMasterStreamType;
 
     private Context mContext;
     private AlarmManager mAlarmManager;
@@ -1142,24 +1138,12 @@
             if (mAudioManager == null) {
                 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
                 if (mAudioManager == null) return;
-                mMasterStreamMaxVolume = mAudioManager.getStreamMaxVolume(MASTER_STREAM_TYPE);
+                mMasterStreamType = mAudioManager.getMasterStreamType();
             }
             // If the stream is muted, don't play the sound
-            if (mAudioManager.isStreamMute(MASTER_STREAM_TYPE)) return;
+            if (mAudioManager.isStreamMute(mMasterStreamType)) return;
 
-            // Adjust the lock sound volume from a minimum of MIN_LOCK_VOLUME to a maximum
-            // of MAX_LOCK_VOLUME, relative to the maximum level of the MASTER_STREAM_TYPE volume.
-            float lockSoundVolume;
-            int masterStreamVolume = mAudioManager.getStreamVolume(MASTER_STREAM_TYPE);
-            if (masterStreamVolume == 0) {
-                return;
-            } else {
-                lockSoundVolume = MIN_LOCK_VOLUME + (MAX_LOCK_VOLUME - MIN_LOCK_VOLUME)
-                        * ((float) masterStreamVolume / mMasterStreamMaxVolume);
-            }
-
-            mLockSoundStreamId = mLockSounds.play(whichSound, lockSoundVolume, lockSoundVolume, 1,
-                    0, 1.0f);
+            mLockSoundStreamId = mLockSounds.play(whichSound, 1.0f, 1.0f, 1, 0, 1.0f);
         }
     }
 
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index a0d5beb..a3768c6 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -5714,6 +5714,8 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         long identityToken = Binder.clearCallingIdentity();
         try {
             dumpInternal(pw);
@@ -5723,16 +5725,6 @@
     }
 
     private void dumpInternal(PrintWriter pw) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump Backup Manager service from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid()
-                    + " without permission "
-                    + android.Manifest.permission.DUMP);
-            return;
-        }
-
         synchronized (mQueueLock) {
             pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
                     + " / " + (!mProvisioned ? "not " : "") + "provisioned / "
diff --git a/services/java/com/android/server/CountryDetectorService.java b/services/java/com/android/server/CountryDetectorService.java
index 3112b50..fc76277 100644
--- a/services/java/com/android/server/CountryDetectorService.java
+++ b/services/java/com/android/server/CountryDetectorService.java
@@ -212,6 +212,8 @@
     @SuppressWarnings("unused")
     @Override
     protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         if (!DEBUG) return;
         try {
             final Printer p = new PrintWriterPrinter(fout);
diff --git a/services/java/com/android/server/DiskStatsService.java b/services/java/com/android/server/DiskStatsService.java
index 8ef974a..ac25dc5 100644
--- a/services/java/com/android/server/DiskStatsService.java
+++ b/services/java/com/android/server/DiskStatsService.java
@@ -34,6 +34,8 @@
  * statistics about the status of the disk.
  */
 public class DiskStatsService extends Binder {
+    private static final String TAG = "DiskStatsService";
+
     private final Context mContext;
 
     public DiskStatsService(Context context) {
@@ -42,7 +44,7 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        // This data is accessible to any app -- no permission check needed.
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
 
         // Run a quick-and-dirty performance test: write 512 bytes
         byte[] junk = new byte[512];
diff --git a/services/java/com/android/server/SamplingProfilerService.java b/services/java/com/android/server/SamplingProfilerService.java
index 61267d0..0034d2c 100644
--- a/services/java/com/android/server/SamplingProfilerService.java
+++ b/services/java/com/android/server/SamplingProfilerService.java
@@ -39,9 +39,11 @@
     private static final boolean LOCAL_LOGV = false;
     public static final String SNAPSHOT_DIR = SamplingProfilerIntegration.SNAPSHOT_DIR;
 
+    private final Context mContext;
     private FileObserver snapshotObserver;
 
     public SamplingProfilerService(Context context) {
+        mContext = context;
         registerSettingObserver(context);
         startWorking(context);
     }
@@ -94,6 +96,8 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         pw.println("SamplingProfilerService:");
         pw.println("Watching directory: " + SNAPSHOT_DIR);
     }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 018e0a8..b25bf91 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -381,6 +381,13 @@
     /** @hide */
     public static final int RESPONSE_SERVICE                        = BASE + 50;
 
+    /** @hide */
+    public static final int SET_DEVICE_NAME                         = BASE + 51;
+    /** @hide */
+    public static final int SET_DEVICE_NAME_FAILED                  = BASE + 52;
+    /** @hide */
+    public static final int SET_DEVICE_NAME_SUCCEEDED               = BASE + 53;
+
     /**
      * Create a new WifiP2pManager instance. Applications use
      * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -603,6 +610,7 @@
                     case WifiP2pManager.ADD_SERVICE_REQUEST_FAILED:
                     case WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED:
                     case WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED:
+                    case WifiP2pManager.SET_DEVICE_NAME_FAILED:
                         if (listener != null) {
                             ((ActionListener) listener).onFailure(message.arg1);
                         }
@@ -621,6 +629,7 @@
                     case WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED:
                     case WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED:
                     case WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED:
+                    case WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED:
                         if (listener != null) {
                             ((ActionListener) listener).onSuccess();
                         }
@@ -1104,6 +1113,21 @@
     }
 
     /**
+     * Set p2p device name.
+     * @hide
+     * @param c is the channel created at {@link #initialize}
+     * @param listener for callback when group info is available. Can be null.
+     */
+    public void setDeviceName(Channel c, String devName, ActionListener listener) {
+        checkChannel(c);
+        WifiP2pDevice d = new WifiP2pDevice();
+        d.deviceName = devName;
+        c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d);
+    }
+
+
+
+    /**
      * Get a reference to WifiP2pService handler. This is used to establish
      * an AsyncChannel communication with WifiService
      *
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 6168f0e..77e6187 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -184,7 +184,6 @@
 
         mThisDevice.primaryDeviceType = mContext.getResources().getString(
                 com.android.internal.R.string.config_wifi_p2p_device_type);
-        mThisDevice.deviceName = getDefaultDeviceName();
 
         mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported);
         mP2pStateMachine.start();
@@ -205,14 +204,6 @@
                 "WifiP2pService");
     }
 
-    /* We use the 4 digits of the ANDROID_ID to have a friendly
-     * default that has low likelihood of collision with a peer */
-    private String getDefaultDeviceName() {
-        String id = Settings.Secure.getString(mContext.getContentResolver(),
-                    Settings.Secure.ANDROID_ID);
-        return "Android_" + id.substring(0,4);
-    }
-
     /**
      * Get a reference to handler. This is used by a client to establish
      * an AsyncChannel communication with WifiP2pService
@@ -376,6 +367,10 @@
                             WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
                             WifiP2pManager.BUSY);
                     break;
+                case WifiP2pManager.SET_DEVICE_NAME:
+                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                            WifiP2pManager.BUSY);
+                    break;
                 case WifiP2pManager.REQUEST_PEERS:
                     replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
                     break;
@@ -474,6 +469,10 @@
                             WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
                             WifiP2pManager.P2P_UNSUPPORTED);
                     break;
+                case WifiP2pManager.SET_DEVICE_NAME:
+                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
                default:
                     return NOT_HANDLED;
             }
@@ -583,6 +582,16 @@
                     mWifiNative.closeSupplicantConnection();
                     transitionTo(mP2pDisablingState);
                     break;
+                case WifiP2pManager.SET_DEVICE_NAME:
+                    WifiP2pDevice d = (WifiP2pDevice) message.obj;
+                    if (d != null && setAndPersistDeviceName(d.deviceName)) {
+                        if (DBG) logd("set device name " + d.deviceName);
+                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
+                                WifiP2pManager.ERROR);
+                    }
+                    break;
                 case WifiP2pManager.DISCOVER_PEERS:
                     // do not send service discovery request while normal find operation.
                     clearSupplicantServiceRequest();
@@ -1412,8 +1421,39 @@
         }
     }
 
+    private String getPersistedDeviceName() {
+        String deviceName = Settings.Secure.getString(mContext.getContentResolver(),
+                Settings.Secure.WIFI_P2P_DEVICE_NAME);
+        if (deviceName == null) {
+            /* We use the 4 digits of the ANDROID_ID to have a friendly
+             * default that has low likelihood of collision with a peer */
+            String id = Settings.Secure.getString(mContext.getContentResolver(),
+                    Settings.Secure.ANDROID_ID);
+            return "Android_" + id.substring(0,4);
+        }
+        return deviceName;
+    }
+
+    private boolean setAndPersistDeviceName(String devName) {
+        if (devName == null) return false;
+
+        if (!mWifiNative.setDeviceName(devName)) {
+            loge("Failed to set device name " + devName);
+            return false;
+        }
+
+        mThisDevice.deviceName = devName;
+        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
+
+        Settings.Secure.putString(mContext.getContentResolver(),
+                Settings.Secure.WIFI_P2P_DEVICE_NAME, devName);
+        sendThisDeviceChangedBroadcast();
+        return true;
+    }
+
     private void initializeP2pSettings() {
         mWifiNative.setPersistentReconnect(true);
+        mThisDevice.deviceName = getPersistedDeviceName();
         mWifiNative.setDeviceName(mThisDevice.deviceName);
         //DIRECT-XY-DEVICENAME (XY is randomly generated)
         mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);