diff options
22 files changed, 290 insertions, 178 deletions
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 8f7b983..b2c1c71 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -60,9 +60,17 @@ import java.util.Objects; * high-resolution still capture would also include a Surface from a ImageReader * configured for high-resolution JPEG images.</p> * - * @see CameraDevice#capture - * @see CameraDevice#setRepeatingRequest + * <p>A reprocess capture request allows a previously-captured image from the camera device to be + * sent back to the device for further processing. It can be created with + * {@link CameraDevice#createReprocessCaptureRequest}, and used with a reprocessable capture session + * created with {@link CameraDevice#createReprocessableCaptureSession}.</p> + * + * @see CameraCaptureSession#capture + * @see CameraCaptureSession#setRepeatingRequest + * @see CameraCaptureSession#captureBurst + * @see CameraCaptureSession#setRepeatingBurst * @see CameraDevice#createCaptureRequest + * @see CameraDevice#createReprocessCaptureRequest */ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> implements Parcelable { diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl index b0779c0..30ea8e7 100644 --- a/core/java/android/security/IKeystoreService.aidl +++ b/core/java/android/security/IKeystoreService.aidl @@ -30,33 +30,29 @@ import android.security.KeystoreArguments; * @hide */ interface IKeystoreService { - int test(); + int getState(int userId); byte[] get(String name); int insert(String name, in byte[] item, int uid, int flags); int del(String name, int uid); int exist(String name, int uid); - String[] saw(String namePrefix, int uid); + String[] list(String namePrefix, int uid); int reset(); int onUserPasswordChanged(int userId, String newPassword); - int lock(); + int lock(int userId); int unlock(int userId, String userPassword); - int zero(); + int isEmpty(int userId); int generate(String name, int uid, int keyType, int keySize, int flags, in KeystoreArguments args); int import_key(String name, in byte[] data, int uid, int flags); byte[] sign(String name, in byte[] data); int verify(String name, in byte[] data, in byte[] signature); byte[] get_pubkey(String name); - int del_key(String name, int uid); int grant(String name, int granteeUid); int ungrant(String name, int granteeUid); long getmtime(String name); int duplicate(String srcKey, int srcUid, String destKey, int destUid); int is_hardware_backed(String string); int clear_uid(long uid); - int reset_uid(int uid); - int sync_uid(int sourceUid, int targetUid); - int password_uid(String password, int uid); // Keymaster 0.4 methods int addRngEntropy(in byte[] data); diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java index 9f00455..4b9b590 100644 --- a/core/java/android/view/ActionMode.java +++ b/core/java/android/view/ActionMode.java @@ -343,7 +343,9 @@ public abstract class ActionMode { * @param mode The ActionMode that requires positioning. * @param view The View that originated the ActionMode, in whose coordinates the Rect should * be provided. - * @param outRect The Rect to be populated with the content position. + * @param outRect The Rect to be populated with the content position. Use this to specify + * where the content in your app lives within the given view. This will be used + * to avoid occluding the given content Rect with the created ActionMode. */ public void onGetContentRect(ActionMode mode, View view, Rect outRect) { if (view != null) { diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index e5c4ba9..5928c69 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -623,7 +623,7 @@ static jboolean android_media_AudioRecord_setInputDevice( sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == 0) { - return 0; + return false; } return lpRecorder->setInputDevice(device_id) == NO_ERROR; } diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index eab5668..1cd07d1 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -1554,6 +1554,11 @@ exit: return jStatus; } +static jint +android_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz) +{ + return nativeToJavaStatus(AudioSystem::systemReady()); +} // ---------------------------------------------------------------------------- @@ -1601,6 +1606,7 @@ static JNINativeMethod gMethods[] = { (void *)android_media_AudioSystem_registerPolicyMixes}, {"native_register_dynamic_policy_callback", "()V", (void *)android_media_AudioSystem_registerDynPolicyCallback}, + {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady}, }; diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index daafd5e..5b52a49 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -998,6 +998,9 @@ static jboolean android_media_AudioTrack_setOutputDevice( JNIEnv *env, jobject thiz, jint device_id) { sp<AudioTrack> lpTrack = getAudioTrack(env, thiz); + if (lpTrack == 0) { + return false; + } return lpTrack->setOutputDevice(device_id) == NO_ERROR; } diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 06f5b06..72eda23 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -146,10 +146,10 @@ public class KeyStore { } } - public State state() { + public State state(int userId) { final int ret; try { - ret = mBinder.test(); + ret = mBinder.getState(userId); } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); throw new AssertionError(e); @@ -163,6 +163,10 @@ public class KeyStore { } } + public State state() { + return state(UserHandle.myUserId()); + } + public boolean isUnlocked() { return state() == State.UNLOCKED; } @@ -211,15 +215,26 @@ public class KeyStore { return contains(key, UID_SELF); } - public String[] saw(String prefix, int uid) { + /** + * List all entries in the keystore for {@code uid} starting with {@code prefix}. + */ + public String[] list(String prefix, int uid) { try { - return mBinder.saw(prefix, uid); + return mBinder.list(prefix, uid); } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return null; } } + public String[] list(String prefix) { + return list(prefix, UID_SELF); + } + + public String[] saw(String prefix, int uid) { + return list(prefix, uid); + } + public String[] saw(String prefix) { return saw(prefix, UID_SELF); } @@ -233,15 +248,25 @@ public class KeyStore { } } - public boolean lock() { + /** + * Attempt to lock the keystore for {@code user}. + * + * @param user Android user to lock. + * @return whether {@code user}'s keystore was locked. + */ + public boolean lock(int userId) { try { - return mBinder.lock() == NO_ERROR; + return mBinder.lock(userId) == NO_ERROR; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return false; } } + public boolean lock() { + return lock(UserHandle.myUserId()); + } + /** * Attempt to unlock the keystore for {@code user} with the password {@code password}. * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or @@ -267,15 +292,22 @@ public class KeyStore { return unlock(UserHandle.getUserId(Process.myUid()), password); } - public boolean isEmpty() { + /** + * Check if the keystore for {@code userId} is empty. + */ + public boolean isEmpty(int userId) { try { - return mBinder.zero() == KEY_NOT_FOUND; + return mBinder.isEmpty(userId) != 0; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return false; } } + public boolean isEmpty() { + return isEmpty(UserHandle.myUserId()); + } + public boolean generate(String key, int uid, int keyType, int keySize, int flags, byte[][] args) { try { @@ -306,12 +338,7 @@ public class KeyStore { } public boolean delKey(String key, int uid) { - try { - return mBinder.del_key(key, uid) == NO_ERROR; - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } + return delete(key, uid); } public boolean delKey(String key) { @@ -404,36 +431,6 @@ public class KeyStore { } } - public boolean resetUid(int uid) { - try { - mError = mBinder.reset_uid(uid); - return mError == NO_ERROR; - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } - } - - public boolean syncUid(int sourceUid, int targetUid) { - try { - mError = mBinder.sync_uid(sourceUid, targetUid); - return mError == NO_ERROR; - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } - } - - public boolean passwordUid(String password, int uid) { - try { - mError = mBinder.password_uid(password, uid); - return mError == NO_ERROR; - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } - } - public int getLastError() { return mError; } diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index ee12374..373f3fd 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -634,6 +634,7 @@ public class AudioSystem public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register); + public static native int systemReady(); // Items shared with audio service diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index bd7a247..f76189c 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -1519,7 +1519,7 @@ public class AudioTrack } private boolean isRestricted() { - if ((mAttributes.getFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { + if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { return false; } try { diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index f148606..2e92c40 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1757,7 +1757,7 @@ public class MediaPlayer implements SubtitleController.Listener throw new IllegalArgumentException(msg); } mUsage = attributes.getUsage(); - mBypassInterruptionPolicy = (attributes.getFlags() + mBypassInterruptionPolicy = (attributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0; Parcel pattributes = Parcel.obtain(); attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS); diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index e211b99..a1b8a3b 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -158,7 +158,16 @@ public class RingtoneManager { * in most cases. */ public static final String EXTRA_RINGTONE_TITLE = "android.intent.extra.ringtone.TITLE"; - + + /** + * @hide + * Given to the ringtone picker as an int. Additional AudioAttributes flags to use + * when playing the ringtone in the picker. + * @see #ACTION_RINGTONE_PICKER + */ + public static final String EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS = + "android.intent.extra.ringtone.AUDIO_ATTRIBUTES_FLAGS"; + /** * Returned from the ringtone picker as a {@link Uri}. * <p> @@ -221,7 +230,7 @@ public class RingtoneManager { private boolean mStopPreviousRingtone = true; private Ringtone mPreviousRingtone; - + /** * Constructs a RingtoneManager. This constructor is recommended as its * constructed instance manages cursor(s). @@ -283,7 +292,7 @@ public class RingtoneManager { return AudioManager.STREAM_RING; } } - + /** * Whether retrieving another {@link Ringtone} will stop playing the * previously retrieved {@link Ringtone}. diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java index 88d979e..64863c2 100644 --- a/media/java/android/media/SoundPool.java +++ b/media/java/android/media/SoundPool.java @@ -463,7 +463,7 @@ public class SoundPool { } private boolean isRestricted() { - if ((mAttributes.getFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { + if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { return false; } try { diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java index 54bbd5a..6295de4 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -110,7 +110,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout protected void verifyPasswordAndUnlock() { final String entry = getPasswordText(); - setPasswordEntryEnabled(false); + setPasswordEntryInputEnabled(false); if (mPendingLockCheck != null) { mPendingLockCheck.cancel(false); } @@ -121,7 +121,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout new LockPatternChecker.OnCheckCallback() { @Override public void onChecked(boolean matched) { - setPasswordEntryEnabled(true); + setPasswordEntryInputEnabled(true); mPendingLockCheck = null; onPasswordChecked(entry, matched); } @@ -152,6 +152,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout protected abstract void resetPasswordText(boolean animate); protected abstract String getPasswordText(); protected abstract void setPasswordEntryEnabled(boolean enabled); + protected abstract void setPasswordEntryInputEnabled(boolean enabled); // Prevent user from using the PIN/Password entry until scheduled deadline. protected void handleAttemptLockout(long elapsedRealtimeDeadline) { diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java index f18c451..c9ad728 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java @@ -74,7 +74,12 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView protected void resetState() { mSecurityMessageDisplay.setMessage(R.string.kg_password_instructions, false); + final boolean wasDisabled = mPasswordEntry.isEnabled(); setPasswordEntryEnabled(true); + setPasswordEntryInputEnabled(true); + if (wasDisabled) { + mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT); + } } @Override @@ -95,7 +100,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView post(new Runnable() { @Override public void run() { - if (isShown()) { + if (isShown() && mPasswordEntry.isEnabled()) { mPasswordEntry.requestFocus(); if (reason != KeyguardSecurityView.SCREEN_ON || mShowImeAtScreenOn) { mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT); @@ -190,6 +195,11 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView @Override protected void setPasswordEntryEnabled(boolean enabled) { + mPasswordEntry.setEnabled(enabled); + } + + @Override + protected void setPasswordEntryInputEnabled(boolean enabled) { mPasswordEntryDisabler.setInputEnabled(enabled); } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java index 84b4cf8..ed0d4af 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -72,6 +72,11 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView } @Override + protected void setPasswordEntryInputEnabled(boolean enabled) { + mPasswordEntry.setEnabled(enabled); + } + + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (KeyEvent.isConfirmKey(keyCode)) { performClick(mOkButton); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 1e488f3..fa172a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1848,10 +1848,10 @@ public abstract class BaseStatusBar extends SystemUI implements mKeyguardIconOverflowContainer.setVisibility(View.GONE); } + mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1); + mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 2); mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer, mStackScroller.getChildCount() - 3); - mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 2); - mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1); } private boolean shouldShowOnKeyguard(StatusBarNotification sbn) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 5a9b5b2..3599d80 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -17367,7 +17367,7 @@ public final class ActivityManagerService extends ActivityManagerNative final ActivityRecord r = app.activities.get(j); if (r.app != app) { Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " - + app + "?!?"); + + app + "?!? Using " + r.app + " instead."); continue; } if (r.visible) { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 352c499..1fd466a 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -217,6 +217,7 @@ public class AudioService extends IAudioService.Stub { private static final int MSG_PERSIST_MICROPHONE_MUTE = 23; private static final int MSG_UNMUTE_STREAM = 24; private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 25; + private static final int MSG_INDICATE_SYSTEM_READY = 26; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) @@ -229,6 +230,9 @@ public class AudioService extends IAudioService.Stub { // Timeout for connection to bluetooth headset service private static final int BT_HEADSET_CNCT_TIMEOUT_MS = 3000; + // retry delay in case of failure to indicate system ready to AudioFlinger + private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000; + /** @see AudioSystemThread */ private AudioSystemThread mAudioSystemThread; /** @see AudioHandler */ @@ -733,6 +737,108 @@ public class AudioService extends IAudioService.Stub { StreamOverride.init(mContext); mControllerService.init(); + onIndicateSystemReady(); + } + + void onIndicateSystemReady() { + if (AudioSystem.systemReady() == AudioSystem.SUCCESS) { + return; + } + sendMsg(mAudioHandler, + MSG_INDICATE_SYSTEM_READY, + SENDMSG_REPLACE, + 0, + 0, + null, + INDICATE_SYSTEM_READY_RETRY_DELAY_MS); + } + + public void onMediaServerDied() { + if (!mSystemReady || + (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { + Log.e(TAG, "Media server died."); + sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0, + null, 500); + return; + } + Log.e(TAG, "Media server started."); + + // indicate to audio HAL that we start the reconfiguration phase after a media + // server crash + // Note that we only execute this when the media server + // process restarts after a crash, not the first time it is started. + AudioSystem.setParameters("restarting=true"); + + readAndSetLowRamDevice(); + + // Restore device connection states + synchronized (mConnectedDevices) { + for (int i = 0; i < mConnectedDevices.size(); i++) { + DeviceListSpec spec = mConnectedDevices.valueAt(i); + AudioSystem.setDeviceConnectionState( + spec.mDeviceType, + AudioSystem.DEVICE_STATE_AVAILABLE, + spec.mDeviceAddress, + spec.mDeviceName); + } + } + // Restore call state + AudioSystem.setPhoneState(mMode); + + // Restore forced usage for communcations and record + AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm); + AudioSystem.setForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm); + AudioSystem.setForceUse(AudioSystem.FOR_SYSTEM, mCameraSoundForced ? + AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE); + + // Restore stream volumes + int numStreamTypes = AudioSystem.getNumStreamTypes(); + for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { + VolumeStreamState streamState = mStreamStates[streamType]; + AudioSystem.initStreamVolume(streamType, 0, (streamState.mIndexMax + 5) / 10); + + streamState.applyAllVolumes(); + } + + // Restore ringer mode + setRingerModeInt(getRingerModeInternal(), false); + + // Reset device orientation (if monitored for this device) + if (mMonitorOrientation) { + setOrientationForAudioSystem(); + } + if (mMonitorRotation) { + setRotationForAudioSystem(); + } + + synchronized (mBluetoothA2dpEnabledLock) { + AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, + mBluetoothA2dpEnabled ? + AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP); + } + + synchronized (mSettingsLock) { + AudioSystem.setForceUse(AudioSystem.FOR_DOCK, + mDockAudioMediaEnabled ? + AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE); + } + if (mHdmiManager != null) { + synchronized (mHdmiManager) { + if (mHdmiTvClient != null) { + setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); + } + } + } + + synchronized (mAudioPolicies) { + for (AudioPolicyProxy policy : mAudioPolicies.values()) { + policy.connectMixes(); + } + } + + onIndicateSystemReady(); + // indicate the end of reconfiguration phase to audio HAL + AudioSystem.setParameters("restarting=false"); } private void createAudioSystemThread() { @@ -4147,90 +4253,7 @@ public class AudioService extends IAudioService.Stub { break; case MSG_MEDIA_SERVER_DIED: - if (!mSystemReady || - (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) { - Log.e(TAG, "Media server died."); - sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0, - null, 500); - break; - } - Log.e(TAG, "Media server started."); - - // indicate to audio HAL that we start the reconfiguration phase after a media - // server crash - // Note that we only execute this when the media server - // process restarts after a crash, not the first time it is started. - AudioSystem.setParameters("restarting=true"); - - readAndSetLowRamDevice(); - - // Restore device connection states - synchronized (mConnectedDevices) { - for (int i = 0; i < mConnectedDevices.size(); i++) { - DeviceListSpec spec = mConnectedDevices.valueAt(i); - AudioSystem.setDeviceConnectionState( - spec.mDeviceType, - AudioSystem.DEVICE_STATE_AVAILABLE, - spec.mDeviceAddress, - spec.mDeviceName); - } - } - // Restore call state - AudioSystem.setPhoneState(mMode); - - // Restore forced usage for communcations and record - AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm); - AudioSystem.setForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm); - AudioSystem.setForceUse(AudioSystem.FOR_SYSTEM, mCameraSoundForced ? - AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE); - - // Restore stream volumes - int numStreamTypes = AudioSystem.getNumStreamTypes(); - for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { - VolumeStreamState streamState = mStreamStates[streamType]; - AudioSystem.initStreamVolume(streamType, 0, (streamState.mIndexMax + 5) / 10); - - streamState.applyAllVolumes(); - } - - // Restore ringer mode - setRingerModeInt(getRingerModeInternal(), false); - - // Reset device orientation (if monitored for this device) - if (mMonitorOrientation) { - setOrientationForAudioSystem(); - } - if (mMonitorRotation) { - setRotationForAudioSystem(); - } - - synchronized (mBluetoothA2dpEnabledLock) { - AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, - mBluetoothA2dpEnabled ? - AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP); - } - - synchronized (mSettingsLock) { - AudioSystem.setForceUse(AudioSystem.FOR_DOCK, - mDockAudioMediaEnabled ? - AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE); - } - if (mHdmiManager != null) { - synchronized (mHdmiManager) { - if (mHdmiTvClient != null) { - setHdmiSystemAudioSupported(mHdmiSystemAudioSupported); - } - } - } - - synchronized (mAudioPolicies) { - for(AudioPolicyProxy policy : mAudioPolicies.values()) { - policy.connectMixes(); - } - } - - // indicate the end of reconfiguration phase to audio HAL - AudioSystem.setParameters("restarting=false"); + onMediaServerDied(); break; case MSG_UNLOAD_SOUND_EFFECTS: @@ -4335,6 +4358,10 @@ public class AudioService extends IAudioService.Stub { onSystemReady(); break; + case MSG_INDICATE_SYSTEM_READY: + onIndicateSystemReady(); + break; + case MSG_PERSIST_MUSIC_ACTIVE_MS: final int musicActiveMs = msg.arg1; Settings.Secure.putIntForUser(mContentResolver, @@ -4872,7 +4899,7 @@ public class AudioService extends IAudioService.Stub { if (btDevice == null) { return; } - + address = btDevice.getAddress(); BluetoothClass btClass = btDevice.getBluetoothClass(); if (btClass != null) { @@ -5933,7 +5960,7 @@ public class AudioService extends IAudioService.Stub { final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder()); if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { // is there already one policy managing ducking? - for(AudioPolicyProxy policy : mAudioPolicies.values()) { + for (AudioPolicyProxy policy : mAudioPolicies.values()) { if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) { Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled"); return AudioManager.ERROR; @@ -5950,7 +5977,7 @@ public class AudioService extends IAudioService.Stub { private void dumpAudioPolicies(PrintWriter pw) { pw.println("\nAudio policies:"); synchronized (mAudioPolicies) { - for(AudioPolicyProxy policy : mAudioPolicies.values()) { + for (AudioPolicyProxy policy : mAudioPolicies.values()) { pw.println(policy.toLogFriendlyString()); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 6a47238..3531796 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -6347,25 +6347,16 @@ public class PackageManagerService extends IPackageManager.Stub { if ((scanFlags & SCAN_NEW_INSTALL) == 0) { deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); } else { - // Verify the ABIs haven't changed since we last deduced them. - String oldPrimaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; - String oldSecondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi; - - // TODO: The only purpose of this code is to update the native library paths - // based on the final install location. We can simplify this and avoid having - // to scan the package again. + // TODO: We need this second call to derive in two cases : + // + // - To update the native library paths based on the final install location. + // - We don't call dexopt when moving packages, and so we have to scan again. + // + // We can simplify this and avoid having to scan the package again by letting + // scanPackageLI know if the current install was a move (and deriving things only + // in that case) and by "reparenting" the native lib directory in the case of + // a normal (non-move) install. deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, false /* extract libs */); - if (!TextUtils.equals(oldPrimaryCpuAbi, pkg.applicationInfo.primaryCpuAbi)) { - throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, - "unexpected abi change for " + pkg.packageName + " (" - + oldPrimaryCpuAbi + "-> " + pkg.applicationInfo.primaryCpuAbi); - } - - if (!TextUtils.equals(oldSecondaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi)) { - throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, - "unexpected abi change for " + pkg.packageName + " (" - + oldSecondaryCpuAbi + "-> " + pkg.applicationInfo.secondaryCpuAbi); - } } if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 9bb5e40..7d14d47 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -6320,11 +6320,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { } vis = (vis & ~flags) | (oldVis & flags); } - if (windowTypeToLayerLw(type) > windowTypeToLayerLw(TYPE_INPUT_CONSUMER)) { - // We can't get into fullscreen from this window otherwise the consumer would not get - // the input events. - vis = (vis & ~View.SYSTEM_UI_FLAG_FULLSCREEN); - } if (!areTranslucentBarsAllowed() && transWin != mStatusBar) { vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT @@ -6363,6 +6358,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { vis &= ~View.SYSTEM_UI_CLEARABLE_FLAGS; } + final boolean immersive = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0; + immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; + final boolean navAllowedHidden = immersive || immersiveSticky; + + if (!navAllowedHidden + && windowTypeToLayerLw(type) > windowTypeToLayerLw(TYPE_INPUT_CONSUMER)) { + // We can't hide the navbar from this window otherwise the input consumer would not get + // the input events. + vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); + } + vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis); // update navigation bar diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 308c204..145c993 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -126,6 +126,23 @@ public class TelecomManager { "android.telecom.action.CHANGE_DEFAULT_DIALER"; /** + * Activity action: Opens the settings screen where a user can enable and disable which + * {@link PhoneAccount}s are allows to make and receive calls. Because a user must + * explicitly enable an account before the system will use it, an app may want to send the + * user to this setting after registering a {@link PhoneAccount}. + * <p> + * Input: get*Extra field {@link #EXTRA_PHONE_ACCOUNT_DESCRIPTION} contains a string-based + * reference to the {@link PhoneAccountHandle} you want to enable. get*Extra field + * {@link #EXTRA_ENABLE_PHONE_ACCOUNT_VALUE} contains a boolean value indicated whether + * the account should be enabled or disabled. + * <p> + * Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} + * @hide + */ + public static final String ACTION_ENABLE_PHONE_ACCOUNT_SETTING = + "android.telecom.action.ENABLE_PHONE_ACCOUNT_SETTING"; + + /** * Extra value used to provide the package name for {@link #ACTION_CHANGE_DEFAULT_DIALER}. */ public static final String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = @@ -161,6 +178,25 @@ public class TelecomManager { "android.telecom.extra.PHONE_ACCOUNT_HANDLE"; /** + * The extra used with {@link #ACTION_ENABLE_PHONE_ACCOUNT_SETTING} to specify a phone account + * as a string value. The value is of the form: "A;B" where A is the component name of the + * {@link PhoneAccount} (e.g., + * com.android.phone/com.android.services.telephony.TelephonyConnectionService) and B is the + * {@link PhoneAccount} ID. + * @hide + */ + public static final String EXTRA_PHONE_ACCOUNT_DESCRIPTION = + "android.telecom.extra.PHONE_ACCOUNT_DESCRIPTION"; + + /** + * Boolean extra used to specify a value for enabling and disabling a phone account. + * Used with {@link #ACTION_ENABLE_PHONE_ACCOUNT_SETTING}. + * @hide + */ + public static final String EXTRA_ENABLE_PHONE_ACCOUNT_VALUE = + "android.telecom.extra.ENABLE_PHONE_ACCOUNT_VALUE"; + + /** * Optional extra for {@link #ACTION_INCOMING_CALL} containing a {@link Bundle} which contains * metadata about the call. This {@link Bundle} will be returned to the * {@link ConnectionService}. diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index eded804..22bcbda 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -468,6 +468,20 @@ public final class BridgeContext extends Context { @Override public ClassLoader getClassLoader() { + // The documentation for this method states that it should return a class loader one can + // use to retrieve classes in this package. However, when called by LayoutInflater, we do + // not want the class loader to return app's custom views. + // This is so that the IDE can instantiate the custom views and also generate proper error + // messages in case of failure. This also enables the IDE to fallback to MockView in case + // there's an exception thrown when trying to inflate the custom view. + // To work around this issue, LayoutInflater is modified via LayoutLib Create tool to + // replace invocations of this method to a new method: getFrameworkClassLoader(). Also, + // the method is injected into Context. The implementation of getFrameworkClassLoader() is: + // "return getClass().getClassLoader();". This means that when LayoutInflater asks for + // the context ClassLoader, it gets only LayoutLib's ClassLoader which doesn't have + // access to the apps's custom views. + // This method can now return the right ClassLoader, which CustomViews can use to do the + // right thing. if (mClassLoader == null) { mClassLoader = new ClassLoader(getClass().getClassLoader()) { @Override |
