diff options
Diffstat (limited to 'services')
7 files changed, 172 insertions, 57 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index cd9b07e..84dd022 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -5808,7 +5808,8 @@ uint32_t AudioFlinger::EffectModule::deviceAudioSystemToEffectApi(uint32_t devic const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = { AUDIO_MODE_NORMAL, // AudioSystem::MODE_NORMAL AUDIO_MODE_RINGTONE, // AudioSystem::MODE_RINGTONE - AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_CALL + AUDIO_MODE_IN_CALL, // AudioSystem::MODE_IN_CALL + AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_COMMUNICATION, same conversion as for MODE_IN_CALL }; int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode) diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp index b17584a..e3b5db1 100644 --- a/services/audioflinger/AudioPolicyManagerBase.cpp +++ b/services/audioflinger/AudioPolicyManagerBase.cpp @@ -246,7 +246,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) // if leaving call state, handle special case of active streams // pertaining to sonification strategy see handleIncallSonification() - if (mPhoneState == AudioSystem::MODE_IN_CALL) { + if (isInCall()) { LOGV("setPhoneState() in call state management: new state is %d", state); for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { handleIncallSonification(stream, false, true); @@ -259,16 +259,21 @@ void AudioPolicyManagerBase::setPhoneState(int state) bool force = false; // are we entering or starting a call - if ((oldState != AudioSystem::MODE_IN_CALL) && (state == AudioSystem::MODE_IN_CALL)) { + if (!isStateInCall(oldState) && isStateInCall(state)) { LOGV(" Entering call in setPhoneState()"); // force routing command to audio hardware when starting a call // even if no device change is needed force = true; - } else if ((oldState == AudioSystem::MODE_IN_CALL) && (state != AudioSystem::MODE_IN_CALL)) { + } else if (isStateInCall(oldState) && !isStateInCall(state)) { LOGV(" Exiting call in setPhoneState()"); // force routing command to audio hardware when exiting a call // even if no device change is needed force = true; + } else if (isStateInCall(state) && (state != oldState)) { + LOGV(" Switching between telephony and VoIP in setPhoneState()"); + // force routing command to audio hardware when switching between telephony and VoIP + // even if no device change is needed + force = true; } // check for device and output changes triggered by new phone state @@ -290,7 +295,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) // force routing command to audio hardware when ending call // even if no device change is needed - if (oldState == AudioSystem::MODE_IN_CALL && newDevice == 0) { + if (isStateInCall(oldState) && newDevice == 0) { newDevice = hwOutputDesc->device(); } @@ -298,7 +303,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) // immediately and delay the route change to avoid sending the ring tone // tail into the earpiece or headset. int delayMs = 0; - if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) { + if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) { // delay the device change command by twice the output latency to have some margin // and be sure that audio buffers not yet affected by the mute are out when // we actually apply the route change @@ -311,7 +316,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) // if entering in call state, handle special case of active streams // pertaining to sonification strategy see handleIncallSonification() - if (state == AudioSystem::MODE_IN_CALL) { + if (isStateInCall(state)) { LOGV("setPhoneState() in call state management: new state is %d", state); // unmute the ringing tone after a sufficient delay if it was muted before // setting output device above @@ -586,7 +591,7 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, setOutputDevice(output, getNewDevice(output)); // handle special case for sonification while in call - if (mPhoneState == AudioSystem::MODE_IN_CALL) { + if (isInCall()) { handleIncallSonification(stream, true, false); } @@ -611,7 +616,7 @@ status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream); // handle special case for sonification while in call - if (mPhoneState == AudioSystem::MODE_IN_CALL) { + if (isInCall()) { handleIncallSonification(stream, false, false); } @@ -1478,7 +1483,7 @@ uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fro // use device for strategy media // 4: the strategy DTMF is active on the hardware output: // use device for strategy DTMF - if (mPhoneState == AudioSystem::MODE_IN_CALL || + if (isInCall() || outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { @@ -1533,7 +1538,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, switch (strategy) { case STRATEGY_DTMF: - if (mPhoneState != AudioSystem::MODE_IN_CALL) { + if (!isInCall()) { // when off call, DTMF strategy follows the same rules as MEDIA strategy device = getDeviceForStrategy(STRATEGY_MEDIA, false); break; @@ -1546,7 +1551,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, // of priority switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) { case AudioSystem::FORCE_BT_SCO: - if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) { + if (!isInCall() || strategy != STRATEGY_DTMF) { device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; if (device) break; } @@ -1566,7 +1571,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, if (device) break; #ifdef WITH_A2DP // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP - if (mPhoneState != AudioSystem::MODE_IN_CALL) { + if (!isInCall()) { device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP; if (device) break; device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; @@ -1580,14 +1585,14 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, break; case AudioSystem::FORCE_SPEAKER: - if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) { + if (!isInCall() || strategy != STRATEGY_DTMF) { device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT; if (device) break; } #ifdef WITH_A2DP // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to // A2DP speaker when forcing to speaker output - if (mPhoneState != AudioSystem::MODE_IN_CALL) { + if (!isInCall()) { device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; if (device) break; } @@ -1604,7 +1609,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by // handleIncallSonification(). - if (mPhoneState == AudioSystem::MODE_IN_CALL) { + if (isInCall()) { device = getDeviceForStrategy(STRATEGY_PHONE, false); break; } @@ -1971,6 +1976,16 @@ void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, } } +bool AudioPolicyManagerBase::isInCall() +{ + return isStateInCall(mPhoneState); +} + +bool AudioPolicyManagerBase::isStateInCall(int state) { + return ((state == AudioSystem::MODE_IN_CALL) || + (state == AudioSystem::MODE_IN_COMMUNICATION)); +} + bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream, uint32_t samplingRate, uint32_t format, diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 6a86076..bebd013 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -2399,15 +2399,45 @@ class BackupManagerService extends IBackupManager.Stub { } // Hand off a restore session - public IRestoreSession beginRestoreSession(String transport) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "beginRestoreSession"); + public IRestoreSession beginRestoreSession(String packageName, String transport) { + if (DEBUG) Slog.v(TAG, "beginRestoreSession: pkg=" + packageName + + " transport=" + transport); + + boolean needPermission = true; + if (transport == null) { + transport = mCurrentTransport; + + if (packageName != null) { + PackageInfo app = null; + try { + app = mPackageManager.getPackageInfo(packageName, 0); + } catch (NameNotFoundException nnf) { + Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName); + throw new IllegalArgumentException("Package " + packageName + " not found"); + } + + if (app.applicationInfo.uid == Binder.getCallingUid()) { + // So: using the current active transport, and the caller has asked + // that its own package will be restored. In this narrow use case + // we do not require the caller to hold the permission. + needPermission = false; + } + } + } + + if (needPermission) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, + "beginRestoreSession"); + } else { + if (DEBUG) Slog.d(TAG, "restoring self on current transport; no permission needed"); + } synchronized(this) { if (mActiveRestoreSession != null) { Slog.d(TAG, "Restore session requested but one already active"); return null; } - mActiveRestoreSession = new ActiveRestoreSession(transport); + mActiveRestoreSession = new ActiveRestoreSession(packageName, transport); } return mActiveRestoreSession; } @@ -2427,10 +2457,12 @@ class BackupManagerService extends IBackupManager.Stub { class ActiveRestoreSession extends IRestoreSession.Stub { private static final String TAG = "RestoreSession"; + private String mPackageName; private IBackupTransport mRestoreTransport = null; RestoreSet[] mRestoreSets = null; - ActiveRestoreSession(String transport) { + ActiveRestoreSession(String packageName, String transport) { + mPackageName = packageName; mRestoreTransport = getTransport(transport); } @@ -2466,11 +2498,16 @@ class BackupManagerService extends IBackupManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "performRestore"); - if (DEBUG) Slog.d(TAG, "performRestore token=" + Long.toHexString(token) + if (DEBUG) Slog.d(TAG, "restoreAll token=" + Long.toHexString(token) + " observer=" + observer); if (mRestoreTransport == null || mRestoreSets == null) { - Slog.e(TAG, "Ignoring performRestore() with no restore set"); + Slog.e(TAG, "Ignoring restoreAll() with no restore set"); + return -1; + } + + if (mPackageName != null) { + Slog.e(TAG, "Ignoring restoreAll() on single-package session"); return -1; } @@ -2495,6 +2532,14 @@ class BackupManagerService extends IBackupManager.Stub { public synchronized int restorePackage(String packageName, IRestoreObserver observer) { if (DEBUG) Slog.v(TAG, "restorePackage pkg=" + packageName + " obs=" + observer); + if (mPackageName != null) { + if (! mPackageName.equals(packageName)) { + Slog.e(TAG, "Ignoring attempt to restore pkg=" + packageName + + " on session for package " + mPackageName); + return -1; + } + } + PackageInfo app = null; try { app = mPackageManager.getPackageInfo(packageName, 0); @@ -2529,6 +2574,7 @@ class BackupManagerService extends IBackupManager.Stub { // the app has never been backed up from this device -- there's nothing // to do but return failure. if (token == 0) { + if (DEBUG) Slog.w(TAG, "No data available for this package; not restoring"); return -1; } @@ -2543,9 +2589,6 @@ class BackupManagerService extends IBackupManager.Stub { } public synchronized void endRestoreSession() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "endRestoreSession"); - if (DEBUG) Slog.d(TAG, "endRestoreSession"); synchronized (this) { diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 4f8862c..84bc100 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -555,6 +555,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } + public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi) { + synchronized (mMethodMap) { + if (imi == null && mCurMethodId != null) { + imi = mMethodMap.get(mCurMethodId); + } + return mSettings.getEnabledInputMethodSubtypeListLocked(imi); + } + } + public void addClient(IInputMethodClient client, IInputContext inputContext, int uid, int pid) { synchronized (mMethodMap) { @@ -1607,7 +1616,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub synchronized (mMethodMap) { final List<Pair<InputMethodInfo, ArrayList<String>>> immis = - mSettings.getEnabledInputMethodAndSubtypeListLocked(); + mSettings.getEnabledInputMethodAndSubtypeHashCodeListLocked(); ArrayList<Integer> subtypeIds = new ArrayList<Integer>(); if (immis == null || immis.size() == 0) { @@ -2026,11 +2035,36 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } public List<Pair<InputMethodInfo, ArrayList<String>>> - getEnabledInputMethodAndSubtypeListLocked() { - return createEnabledInputMethodAndSubtypeListLocked( + getEnabledInputMethodAndSubtypeHashCodeListLocked() { + return createEnabledInputMethodAndSubtypeHashCodeListLocked( getEnabledInputMethodsAndSubtypeListLocked()); } + public List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked( + InputMethodInfo imi) { + List<Pair<String, ArrayList<String>>> imsList = + getEnabledInputMethodsAndSubtypeListLocked(); + ArrayList<InputMethodSubtype> enabledSubtypes = + new ArrayList<InputMethodSubtype>(); + if (imi != null) { + for (Pair<String, ArrayList<String>> imsPair : imsList) { + InputMethodInfo info = mMethodMap.get(imsPair.first); + if (info != null && info.getId().equals(imi.getId())) { + ArrayList<InputMethodSubtype> subtypes = info.getSubtypes(); + for (InputMethodSubtype ims: subtypes) { + for (String s: imsPair.second) { + if (String.valueOf(ims.hashCode()).equals(s)) { + enabledSubtypes.add(ims); + } + } + } + break; + } + } + } + return enabledSubtypes; + } + // At the initial boot, the settings for input methods are not set, // so we need to enable IME in that case. public void enableAllIMEsIfThereIsNoEnabledIME() { @@ -2128,7 +2162,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } private List<Pair<InputMethodInfo, ArrayList<String>>> - createEnabledInputMethodAndSubtypeListLocked( + createEnabledInputMethodAndSubtypeHashCodeListLocked( List<Pair<String, ArrayList<String>>> imsList) { final ArrayList<Pair<InputMethodInfo, ArrayList<String>>> res = new ArrayList<Pair<InputMethodInfo, ArrayList<String>>>(); diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index cd58284..a0a1974 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -7327,16 +7327,22 @@ class PackageManagerService extends IPackageManager.Stub { pw.println(" "); pw.println("Package warning messages:"); File fname = getSettingsProblemFile(); - FileInputStream in; + FileInputStream in = null; try { in = new FileInputStream(fname); int avail = in.available(); byte[] data = new byte[avail]; in.read(data); pw.print(new String(data)); - in.close(); } catch (FileNotFoundException e) { } catch (IOException e) { + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } } } } diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java index 43dbcc0..1a12a84 100644 --- a/services/java/com/android/server/ProcessStats.java +++ b/services/java/com/android/server/ProcessStats.java @@ -799,8 +799,9 @@ public class ProcessStats { } private String readFile(String file, char endChar) { + FileInputStream is = null; try { - FileInputStream is = new FileInputStream(file); + is = new FileInputStream(file); int len = is.read(mBuffer); is.close(); @@ -815,6 +816,13 @@ public class ProcessStats { } } catch (java.io.FileNotFoundException e) { } catch (java.io.IOException e) { + } finally { + if (is != null) { + try { + is.close(); + } catch (java.io.IOException e) { + } + } } return null; } @@ -841,4 +849,3 @@ public class ProcessStats { } } } - diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java index 4a85aff..0529080 100644 --- a/services/java/com/android/server/WiredAccessoryObserver.java +++ b/services/java/com/android/server/WiredAccessoryObserver.java @@ -86,33 +86,40 @@ class WiredAccessoryObserver extends UEventObserver { if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString()); try { - if ((event.get("SWITCH_NAME")).equals("usb_audio")) { - if (Integer.parseInt(event.get("SWITCH_STATE")) == 1) { - switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| - BIT_USB_HEADSET_DGTL)) | - (Integer.parseInt(event.get("SWITCH_STATE")) << 2)); - } else if (Integer.parseInt(event.get("SWITCH_STATE")) == 2) { - switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| - BIT_USB_HEADSET_ANLG)) | - (Integer.parseInt(event.get("SWITCH_STATE")) << 3)); - } - else switchState = (mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC)); - } - else if ((event.get("SWITCH_NAME")).equals("hdmi")) { - switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| - BIT_USB_HEADSET_DGTL|BIT_USB_HEADSET_ANLG)) | - (Integer.parseInt(event.get("SWITCH_STATE")) << 4)); - } - else { - switchState = ((mHeadsetState & (BIT_USB_HEADSET_ANLG|BIT_USB_HEADSET_DGTL)) | - (Integer.parseInt(event.get("SWITCH_STATE")))); - } - update(event.get("SWITCH_NAME"), switchState); + String name = event.get("SWITCH_NAME"); + int state = Integer.parseInt(event.get("SWITCH_STATE")); + updateState(name, state); } catch (NumberFormatException e) { Slog.e(TAG, "Could not parse switch state from event " + event); } } + private synchronized final void updateState(String name, int state) + { + if (name.equals("usb_audio")) { + if (state == 1) { + switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| + BIT_USB_HEADSET_DGTL|BIT_HDMI_AUDIO)) | + (state << 2)); + } else if (state == 2) { + switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| + BIT_USB_HEADSET_ANLG|BIT_HDMI_AUDIO)) | + (state << 3)); + } else switchState = (mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC|BIT_HDMI_AUDIO)); + } + else if (name.equals("hdmi")) { + switchState = ((mHeadsetState & (BIT_HEADSET|BIT_HEADSET_NO_MIC| + BIT_USB_HEADSET_DGTL|BIT_USB_HEADSET_ANLG)) | + (state << 4)); + } + else { + switchState = ((mHeadsetState & (BIT_HDMI_AUDIO|BIT_USB_HEADSET_ANLG| + BIT_USB_HEADSET_DGTL)) | + state); + } + update(name, switchState); + } + private synchronized final void init() { char[] buffer = new char[1024]; @@ -132,13 +139,15 @@ class WiredAccessoryObserver extends UEventObserver { file.close(); newName = new String(buffer, 0, len).trim(); + if (newState > 0) { + updateState(newName, newState); + } + } catch (FileNotFoundException e) { Slog.w(TAG, "This kernel does not have wired headset support"); } catch (Exception e) { Slog.e(TAG, "" , e); } - - update(newName, newState); } } |