OSDN Git Service

resolved conflicts for merge of 534f3e94 to jb-mr1-dev
authorMarco Nelissen <marcone@google.com>
Thu, 20 Mar 2014 17:27:58 +0000 (10:27 -0700)
committerMarco Nelissen <marcone@google.com>
Thu, 20 Mar 2014 17:27:58 +0000 (10:27 -0700)
Change-Id: I48ef81bc77d5ececbe9b0cf7d5e905512ca16394

1  2 
media/java/android/media/AudioService.java
media/java/android/media/IAudioService.aidl

@@@ -5819,154 -5323,43 +5825,191 @@@ public class AudioService extends IAudi
          }
      }
  
 +
 +    //==========================================================================================
 +    // Safe media volume management.
 +    // MUSIC stream volume level is limited when headphones are connected according to safety
 +    // regulation. When the user attempts to raise the volume above the limit, a warning is
 +    // displayed and the user has to acknowlegde before the volume is actually changed.
 +    // The volume index corresponding to the limit is stored in config_safe_media_volume_index
 +    // property. Platforms with a different limit must set this property accordingly in their
 +    // overlay.
 +    //==========================================================================================
 +
 +    // mSafeMediaVolumeState indicates whether the media volume is limited over headphones.
 +    // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected
 +    // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or
 +    // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it
 +    // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume()
 +    // (when user opts out).
 +    private final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;
 +    private final int SAFE_MEDIA_VOLUME_DISABLED = 1;
 +    private final int SAFE_MEDIA_VOLUME_INACTIVE = 2;
 +    private final int SAFE_MEDIA_VOLUME_ACTIVE = 3;
 +    private Integer mSafeMediaVolumeState;
 +
 +    private int mMcc = 0;
 +    // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
 +    private int mSafeMediaVolumeIndex;
 +    // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
 +    private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET |
 +                                                AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
 +    // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.
 +    // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled
 +    // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS.
 +    private int mMusicActiveMs;
 +    private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours
 +    private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling interval
 +    private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed
 +
 +    private void setSafeMediaVolumeEnabled(boolean on) {
 +        synchronized (mSafeMediaVolumeState) {
 +            if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
 +                    (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) {
 +                if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) {
 +                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
 +                    enforceSafeMediaVolume();
 +                } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) {
 +                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
 +                    mMusicActiveMs = 0;
 +                    sendMsg(mAudioHandler,
 +                            MSG_CHECK_MUSIC_ACTIVE,
 +                            SENDMSG_REPLACE,
 +                            0,
 +                            0,
 +                            null,
 +                            MUSIC_ACTIVE_POLL_PERIOD_MS);
 +                }
 +            }
 +        }
 +    }
 +
 +    private void enforceSafeMediaVolume() {
 +        VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
 +        boolean lastAudible = (streamState.muteCount() != 0);
 +        int devices = mSafeMediaVolumeDevices;
 +        int i = 0;
 +
 +        while (devices != 0) {
 +            int device = 1 << i++;
 +            if ((device & devices) == 0) {
 +                continue;
 +            }
 +            int index = streamState.getIndex(device, lastAudible);
 +            if (index > mSafeMediaVolumeIndex) {
 +                if (lastAudible) {
 +                    streamState.setLastAudibleIndex(mSafeMediaVolumeIndex, device);
 +                    sendMsg(mAudioHandler,
 +                            MSG_PERSIST_VOLUME,
 +                            SENDMSG_QUEUE,
 +                            PERSIST_LAST_AUDIBLE,
 +                            device,
 +                            streamState,
 +                            PERSIST_DELAY);
 +                } else {
 +                    streamState.setIndex(mSafeMediaVolumeIndex, device, true);
 +                    sendMsg(mAudioHandler,
 +                            MSG_SET_DEVICE_VOLUME,
 +                            SENDMSG_QUEUE,
 +                            device,
 +                            0,
 +                            streamState,
 +                            0);
 +                }
 +            }
 +            devices &= ~device;
 +        }
 +    }
 +
 +    private boolean checkSafeMediaVolume(int streamType, int index, int device) {
 +        synchronized (mSafeMediaVolumeState) {
 +            if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
 +                    (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
 +                    ((device & mSafeMediaVolumeDevices) != 0) &&
 +                    (index > mSafeMediaVolumeIndex)) {
 +                mVolumePanel.postDisplaySafeVolumeWarning();
 +                return false;
 +            }
 +            return true;
 +        }
 +    }
 +
 +    public void disableSafeMediaVolume() {
 +        synchronized (mSafeMediaVolumeState) {
 +            setSafeMediaVolumeEnabled(false);
 +        }
 +    }
 +
 +
 +    //==========================================================================================
 +    // Camera shutter sound policy.
 +    // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
 +    // sound is forced (sound even if the device is in silent mode) or not. This option is false by
 +    // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
 +    //==========================================================================================
 +
 +    // cached value of com.android.internal.R.bool.config_camera_sound_forced
 +    private Boolean mCameraSoundForced;
 +
 +    // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
 +    public boolean isCameraSoundForced() {
 +        synchronized (mCameraSoundForced) {
 +            return mCameraSoundForced;
 +        }
 +    }
 +
 +    private static final String[] RINGER_MODE_NAMES = new String[] {
 +            "SILENT",
 +            "VIBRATE",
 +            "NORMAL"
 +    };
 +
 +    private void dumpRingerMode(PrintWriter pw) {
 +        pw.println("\nRinger mode: ");
 +        pw.println("- mode: "+RINGER_MODE_NAMES[mRingerMode]);
 +        pw.print("- ringer mode affected streams = 0x");
 +        pw.println(Integer.toHexString(mRingerModeAffectedStreams));
 +        pw.print("- ringer mode muted streams = 0x");
 +        pw.println(Integer.toHexString(mRingerModeMutedStreams));
 +    }
 +
+     public int verifyX509CertChain(int numcerts, byte [] chain, String domain, String authType) {
+         if (DEBUG_CERTS) {
+             Log.v(TAG, "java side verify for "
+                     + numcerts + " certificates (" + chain.length + " bytes"
+                             + ")for "+ domain + "/" + authType);
+         }
+         byte[][] certChain = new byte[numcerts][];
+         ByteBuffer buf = ByteBuffer.wrap(chain);
+         for (int i = 0; i < numcerts; i++) {
+             int certlen = buf.getInt();
+             if (DEBUG_CERTS) {
+                 Log.i(TAG, "cert " + i +": " + certlen);
+             }
+             certChain[i] = new byte[certlen];
+             buf.get(certChain[i]);
+         }
+         try {
+             SslError err = CertificateChainValidator.verifyServerCertificates(certChain,
+                     domain, authType);
+             if (DEBUG_CERTS) {
+                 Log.i(TAG, "verified: " + err);
+             }
+             if (err == null) {
+                 return -1;
+             } else {
+                 return err.getPrimaryError();
+             }
+         } catch (Exception e) {
+             Log.e(TAG, "failed to verify chain: " + e);
+         }
+         return SslError.SSL_INVALID;
+     }
      @Override
      protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
          mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);