input 系统-------android 静音键的流程

最近遇到一个问题,蓝牙键盘的静音键失效,系统在播放音乐的时候,但是静音图标可以正常显示,于是我追溯了一下从input keyevent VOLUME_MUTE 到audio的前半段过程如下


Input.java:

public static void main(String[] args) {
        (new Input()).run(args);
    }

private void run(String[] args) {


else if (command.equals("keyevent")) {
                if (length >= 2) {
                    final boolean longpress = "--longpress".equals(args[index + 1]);
                    final int start = longpress ? index + 2 : index + 1;
                    inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);
                    if (length > start) {
                        for (int i = start; i < length; i++) {
                            int keyCode = KeyEvent.keyCodeFromString(args[i]);
                            if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
                                keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[i]);
                            }
 Log.i(TAG, "matt-void run ");
                            sendKeyEvent(inputSource, keyCode, longpress);
                        }
                        return;
                    }
                }
            } 


}




private void sendKeyEvent(int inputSource, int keyCode, boolean longpress) {
        long now = SystemClock.uptimeMillis();
Log.i(TAG, "matt-sendKeyEvent: ");
        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));
        if (longpress) {
            injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 1, 0,
                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_LONG_PRESS,
                    inputSource));
        }
        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,
                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));
    }




InputManagerService.java:


 private void injectKeyEvent(KeyEvent event) {
        Log.i(TAG, "matt-injectKeyEvent: " + event);
        InputManager.getInstance().injectInputEvent(event,
                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
    }






 public boolean injectInputEvent(InputEvent event, int mode) {
        return injectInputEventInternal(event, Display.DEFAULT_DISPLAY, mode);
    }


    private boolean injectInputEventInternal(InputEvent event, int displayId, int mode) {
        if (event == null) {
            throw new IllegalArgumentException("event must not be null");
        }
Slog.e(TAG, "matt-injectInputEventInternal"); 
        if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
                && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
                && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
            throw new IllegalArgumentException("mode is invalid");
        }


        final int pid = Binder.getCallingPid();
        final int uid = Binder.getCallingUid();
        final long ident = Binder.clearCallingIdentity();
        final int result;
        try {
            result = nativeInjectInputEvent(mPtr, event, displayId, pid, uid, mode,
                    INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        switch (result) {
            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
                Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
                throw new SecurityException(
                        "Injecting to another application requires INJECT_EVENTS permission");
            case INPUT_EVENT_INJECTION_SUCCEEDED:
                return true;
            case INPUT_EVENT_INJECTION_TIMED_OUT:
                Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
                return false;
            case INPUT_EVENT_INJECTION_FAILED:
            default:
                Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
                return false;
        }
    }


com_android_server_input_InputManagerService.cpp:
 
 
  static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
        jlong ptr, jobject inputEventObj, jint displayId, jint injectorPid, jint injectorUid,
        jint syncMode, jint timeoutMillis, jint policyFlags) {
    NativeInputManager* im = reinterpret_cast(ptr);


    if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
        KeyEvent keyEvent;
        status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
        if (status) {
            jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
            return INPUT_EVENT_INJECTION_FAILED;
        }


        return (jint) im->getInputManager()->getDispatcher()->injectInputEvent(
                & keyEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis,
                uint32_t(policyFlags));
    } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
        const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
        if (!motionEvent) {
            jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
            return INPUT_EVENT_INJECTION_FAILED;
        }


        return (jint) im->getInputManager()->getDispatcher()->injectInputEvent(
                motionEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis,
                uint32_t(policyFlags));    //跑到了这里
    } else {
        jniThrowRuntimeException(env, "Invalid input event type.");
        return INPUT_EVENT_INJECTION_FAILED;
    }
}




 inputdispatcher.cpp:


int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t displayId,
        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
        uint32_t policyFlags) {


  switch (event->getType()) {
    case AINPUT_EVENT_TYPE_KEY: {
ALOGE("matt-inputdispatcher-injectInputEvent");
        const KeyEvent* keyEvent = static_cast(event);
        int32_t action = keyEvent->getAction();
        if (! validateKeyEvent(action)) {
            return INPUT_EVENT_INJECTION_FAILED;
        }




  if (needWake) {
ALOGE(" matt-mLooper->wake();");
        mLooper->wake();
    }







之后怎么跳到下面的地方真的不知道
PhoneWindow.java:


 public boolean dispatchKeyEvent(KeyEvent event) {




 Log.d(TAG, "matt-dispatchKeyEvent-PhoneWindow.java  ");
            return isDown ? PhoneWindow.this.onKeyDown(mFeatureId, event.getKeyCode(), event)
                    : PhoneWindow.this.onKeyUp(mFeatureId, event.getKeyCode(), event);


}






 protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) {


    switch (keyCode) {
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_DOWN:
            case KeyEvent.KEYCODE_VOLUME_MUTE: {
Log.d(TAG, "matt-before switch (keyCode) ");
                int direction = 0;
                switch (keyCode) {
                    case KeyEvent.KEYCODE_VOLUME_UP:
                        direction = AudioManager.ADJUST_RAISE;
                        break;
                    case KeyEvent.KEYCODE_VOLUME_DOWN:
                        direction = AudioManager.ADJUST_LOWER;
                        break;
                    case KeyEvent.KEYCODE_VOLUME_MUTE:
Log.d(TAG, "matt-case KeyEvent.KEYCODE_VOLUME_MUTE ");
                        direction = AudioManager.ADJUST_TOGGLE_MUTE;
                        break;
                }


              if (mMediaController != null) {
Log.d(TAG, "matt- if (mMediaController != null)  ");
                    mMediaController.adjustVolume(direction, AudioManager.FLAG_SHOW_UI);
                } else {
                    MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy(  //跑到了这里
                            mVolumeControlStreamType, direction,
                            AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE
                                    | AudioManager.FLAG_FROM_KEY);
                }


}






MediaSessionLegacyHelper.java:
     public void sendAdjustVolumeBy(int suggestedStream, int delta, int flags) {
        mSessionManager.dispatchAdjustVolume(suggestedStream, delta, flags);
        if (DEBUG) {
            Log.d(TAG, "dispatched volume adjustment");
        }
    }




MediaSessionManager.java:


public void dispatchAdjustVolume(int suggestedStream, int direction, int flags) {
        try {
            mService.dispatchAdjustVolume(suggestedStream, direction, flags);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to send adjust volume.", e);
        }
    }




MediaSessionService.java:






 public void dispatchAdjustVolume(int suggestedStream, int delta, int flags) {
            final int pid = Binder.getCallingPid();
            final int uid = Binder.getCallingUid();
            final long token = Binder.clearCallingIdentity();
Log.d(TAG, "matt-MediaSessionService.java-dispatchAdjustVolume ");
            try {
                synchronized (mLock) {
                    MediaSessionRecord session = mPriorityStack
                            .getDefaultVolumeSession(mCurrentUserId);
                    dispatchAdjustVolumeLocked(suggestedStream, delta, flags, session);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }






 private void dispatchAdjustVolumeLocked(int suggestedStream, int direction, int flags,
                MediaSessionRecord session) {
           // if (DEBUG) {
                String description = session == null ? null : session.toString();
                Log.d(TAG, "matt-dispatchAdjustVolumeLocked-Adjusting session " + description + " by " + direction + ". flags="
                        + flags + ", suggestedStream=" + suggestedStream);


           // }
            boolean preferSuggestedStream = false;
            if (isValidLocalStreamType(suggestedStream)
                    && AudioSystem.isStreamActive(suggestedStream, 0)) {
                preferSuggestedStream = true;
            }
            if (session == null || preferSuggestedStream) {
Log.d(TAG, "matt- if (session == null");  //最后走了这边
                if ((flags & AudioManager.FLAG_ACTIVE_MEDIA_ONLY) != 0
                        && !AudioSystem.isStreamActive(AudioManager.STREAM_MUSIC, 0)) {
                    if (DEBUG) {
                        Log.d(TAG, "No active session to adjust, skipping media only volume event");
                    }
                    return;
                }
                try {
                    String packageName = getContext().getOpPackageName();
                    mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream,
                            flags, packageName, TAG);
                } catch (RemoteException e) {
                    Log.e(TAG, "Error adjusting default volume.", e);
                }
            } else {
            Log.d(TAG, "matt- else");
                session.adjustVolume(direction, flags, getContext().getPackageName(),
                        UserHandle.myUserId(), true);
            }
        }






AudioService.java :


 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
            String callingPackage, String caller) {
        adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage,
                caller, Binder.getCallingUid());
    }




  private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
            String callingPackage, String caller, int uid) {
       Log.d(TAG, "matt-adjustSuggestedStreamVolume() stream=" + suggestedStreamType
                + ", flags=" + flags + ", caller=" + caller);
        int streamType;
        boolean isMute = isMuteAdjust(direction);
Log.d(TAG, "matt-adjustSuggestedStreamVolume+isMute=%d",isMute);
        if (mVolumeControlStream != -1) {
            streamType = mVolumeControlStream;
        } else {
            streamType = getActiveStreamType(suggestedStreamType);
        }
        ensureValidStreamType(streamType);
        final int resolvedStream = mStreamVolumeAlias[streamType];


        // Play sounds on STREAM_RING only.
        if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
                resolvedStream != AudioSystem.STREAM_RING) {
            flags &= ~AudioManager.FLAG_PLAY_SOUND;
        }


        // For notifications/ring, show the ui before making any adjustments
        // Don't suppress mute/unmute requests
        if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) {
            direction = 0;
            flags &= ~AudioManager.FLAG_PLAY_SOUND;
            flags &= ~AudioManager.FLAG_VIBRATE;
            if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
        }
       Log.d(TAG, "matt-adjustSuggestedStreamVolume+2");
        adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);
    }












private void adjustStreamVolume(int streamType, int direction, int flags,
            String callingPackage, String caller, int uid) {
        if (mUseFixedVolume) {
            return;
        }
         Log.e(TAG, "matt-adjustStreamVolume() stream=" + streamType + ", dir=" + direction
                + ", flags=" + flags + ", caller=" + caller);


        ensureValidDirection(direction);
        ensureValidStreamType(streamType);


        boolean isMuteAdjust = isMuteAdjust(direction);
Log.e(TAG, "matt-adjustStreamVolume+isMuteAdjust="+isMuteAdjust);


        if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
            return;
        }
  if (isMuteAdjust) {
                boolean state;
                if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
                    state = !streamState.mIsMuted;
                } else {
                    state = direction == AudioManager.ADJUST_MUTE;
                }


Log.e(TAG, "matt-adjustStreamVolume-state="+state);
                if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
                    setSystemAudioMute(state);
                }
                for (int stream = 0; stream < mStreamStates.length; stream++) {
                    if (streamTypeAlias == mStreamVolumeAlias[stream]) {
                        if (!(readCameraSoundForced()
                                    && (mStreamStates[stream].getStreamType()
                                        == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
                            mStreamStates[stream].mute(state);
                        }
                    }
                }
            
          }
}




 public void mute(boolean state) {
            boolean changed = false;
            synchronized (VolumeStreamState.class) {
                if (state != mIsMuted) {
                    changed = true;
                    mIsMuted = state;


                    // Set the new mute volume. This propagates the values to
                    // the audio system, otherwise the volume won't be changed
                    // at the lower level.
                    Log.e(TAG, "matt-mute");
                    sendMsg(mAudioHandler,
                            MSG_SET_ALL_VOLUMES,
                            SENDMSG_QUEUE,
                            0,
                            0,
                            this, 0);
                }
            }
 Log.e(TAG, "matt-mute+1");
            if (changed) {
                // Stream mute changed, fire the intent.
                Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
                intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
                intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state);
                sendBroadcastToAll(intent);
            }
        }
静音
02-20 14:35:08.551  1655  2894 D MediaSessionService: matt-MediaSessionService.java-dispatchAdjustVolume 
02-20 14:35:08.551  1655  2894 D MediaSessionService: matt-dispatchAdjustVolumeLocked-Adjusting session null by 101. flags=4113, suggestedStream=-2147483648
02-20 14:35:08.551  1655  2894 D MediaSessionService: matt- if (session == null
02-20 14:35:08.551  1655  2894 E AudioService: matt-adjustSuggestedStreamVolume() stream=-2147483648, flags=4113, caller=MediaSessionService
02-20 14:35:08.551  1655  2894 E AudioService: matt-adjustSuggestedStreamVolume+isMute=true
02-20 14:35:08.555  1655  2894 E AudioService: matt-adjustSuggestedStreamVolume+2
02-20 14:35:08.555  1655  2894 E AudioService: matt-adjustStreamVolume() stream=2, dir=101, flags=4113, caller=MediaSessionService
02-20 14:35:08.555  1655  2894 E AudioService: matt-adjustStreamVolume+isMuteAdjust=true
02-20 14:35:08.556  1655  2894 E AudioService: matt-adjustStreamVolume-state=true
02-20 14:35:08.556  1655  2894 E AudioService: matt-mute
02-20 14:35:08.556  1655  2894 E AudioService: matt-mute+1
02-20 14:35:08.557  1655  2894 E AudioService: matt-mute
02-20 14:35:08.557  1655  2894 E AudioService: matt-mute+1
02-20 14:35:08.558  1655  2894 E AudioService: matt-mute
02-20 14:35:08.558  1655  2894 E AudioService: matt-mute+1
02-20 14:35:08.558  1655  2894 E AudioService: matt-mute
02-20 14:35:08.558  1655  2894 E AudioService: matt-mute+1




取消静音


02-20 14:35:23.078  1655  2462 D MediaSessionService: matt-MediaSessionService.java-dispatchAdjustVolume 
02-20 14:35:23.078  1655  2462 D MediaSessionService: matt-dispatchAdjustVolumeLocked-Adjusting session null by 101. flags=4113, suggestedStream=-2147483648
02-20 14:35:23.078  1655  2462 D MediaSessionService: matt- if (session == null
02-20 14:35:23.078  1655  2462 E AudioService: matt-adjustSuggestedStreamVolume() stream=-2147483648, flags=4113, caller=MediaSessionService
02-20 14:35:23.078  1655  2462 E AudioService: matt-adjustSuggestedStreamVolume+isMute=true
02-20 14:35:23.083  1655  2462 E AudioService: matt-adjustSuggestedStreamVolume+2
02-20 14:35:23.083  1655  2462 E AudioService: matt-adjustStreamVolume() stream=2, dir=101, flags=4113, caller=MediaSessionService
02-20 14:35:23.083  1655  2462 E AudioService: matt-adjustStreamVolume+isMuteAdjust=true
02-20 14:35:23.083  1655  2462 E AudioService: matt-adjustStreamVolume-state=false
02-20 14:35:23.083  1655  2462 E AudioService: matt-mute
02-20 14:35:23.083  1655  2462 E AudioService: matt-mute+1
02-20 14:35:23.086  1655  2462 E AudioService: matt-mute
02-20 14:35:23.086  1655  2462 E AudioService: matt-mute+1
02-20 14:35:23.086  1655  2462 E AudioService: matt-mute
02-20 14:35:23.086  1655  2462 E AudioService: matt-mute+1
02-20 14:35:23.088  1655  2462 E AudioService: matt-mute
02-20 14:35:23.088  1655  2462 E AudioService: matt-mute+1














































MediaController.java :




public void adjustVolume(int direction, int flags) {
        try {
            mSessionBinder.adjustVolume(direction, flags, mContext.getPackageName());
        } catch (RemoteException e) {
            Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
        }
    }






MediaSessionCompat.java:


  public void adjustVolume(int direction, int flags, String packageName) {
                MediaSessionImplBase.this.adjustVolume(direction, flags);
            }




  private void adjustVolume(int direction, int flags) {
            if (mVolumeType == MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
                if (mVolumeProvider != null) {
Log.d("matt", " MediaSessionCompat.java-adjustVolume-if");
                    mVolumeProvider.onAdjustVolume(direction);
                }
            } else {
            Log.d("matt", " MediaSessionCompat.java-adjustVolume-else");
                mAudioManager.adjustStreamVolume(direction, mLocalStream, flags);
            }
        }








MediaSessionRecord.java:


  public void adjustVolume(int direction, int flags, String packageName) {
            int uid = Binder.getCallingUid();
            final long token = Binder.clearCallingIdentity();
            try {
                MediaSessionRecord.this.adjustVolume(direction, flags, packageName, uid, false);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }






 public void adjustVolume(int direction, int flags, String packageName, int uid,
            boolean useSuggested) {


  int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND;
        if (isPlaybackActive(false) || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
            flags &= ~AudioManager.FLAG_PLAY_SOUND;
        }
        if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
            // Adjust the volume with a handler not to be blocked by other system service.
            int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
            postAdjustLocalVolume(stream, direction, flags, packageName, uid, useSuggested,
                    previousFlagPlaySound);
        } else {
            if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
                // Nothing to do, the volume cannot be changed
                return;
            }
            if (direction == AudioManager.ADJUST_TOGGLE_MUTE
                    || direction == AudioManager.ADJUST_MUTE
                    || direction == AudioManager.ADJUST_UNMUTE) {
                Log.w(TAG, "Muting remote playback is not supported");
                return;
            }
            mSessionCb.adjustVolume(direction);


            int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
            mOptimisticVolume = volumeBefore + direction;
            mOptimisticVolume = Math.max(0, Math.min(mOptimisticVolume, mMaxVolume));
            mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
            mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
            if (volumeBefore != mOptimisticVolume) {
                pushVolumeUpdate();
            }
            mService.notifyRemoteVolumeChanged(flags, this);


            if (DEBUG) {
                Log.d(TAG, "Adjusted optimistic volume to " + mOptimisticVolume + " max is "
                        + mMaxVolume);
            }
        }
    }


public static void main(String[] args) {
        (new Input()).run(args);
    }

private void run(String[] args) {


else if (command.equals("keyevent")) {
                if (length >= 2) {
                    final boolean longpress = "--longpress".equals(args[index + 1]);
                    final int start = longpress ? index + 2 : index + 1;
                    inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);
                    if (length > start) {
                        for (int i = start; i < length; i++) {
                            int keyCode = KeyEvent.keyCodeFromString(args[i]);
                            if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
                                keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[i]);
                            }
 Log.i(TAG, "matt-void run ");
                            sendKeyEvent(inputSource, keyCode, longpress);
                        }
                        return;
                    }
                }
            } 


}




private void sendKeyEvent(int inputSource, int keyCode, boolean longpress) {
        long now = SystemClock.uptimeMillis();
Log.i(TAG, "matt-sendKeyEvent: ");
        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));
        if (longpress) {
            injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 1, 0,
                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_LONG_PRESS,
                    inputSource));
        }
        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,
                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));
    }




InputManagerService.java:


 private void injectKeyEvent(KeyEvent event) {
        Log.i(TAG, "matt-injectKeyEvent: " + event);
        InputManager.getInstance().injectInputEvent(event,
                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
    }






 public boolean injectInputEvent(InputEvent event, int mode) {
        return injectInputEventInternal(event, Display.DEFAULT_DISPLAY, mode);
    }


    private boolean injectInputEventInternal(InputEvent event, int displayId, int mode) {
        if (event == null) {
            throw new IllegalArgumentException("event must not be null");
        }
Slog.e(TAG, "matt-injectInputEventInternal"); 
        if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
                && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
                && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
            throw new IllegalArgumentException("mode is invalid");
        }


        final int pid = Binder.getCallingPid();
        final int uid = Binder.getCallingUid();
        final long ident = Binder.clearCallingIdentity();
        final int result;
        try {
            result = nativeInjectInputEvent(mPtr, event, displayId, pid, uid, mode,
                    INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        switch (result) {
            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
                Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
                throw new SecurityException(
                        "Injecting to another application requires INJECT_EVENTS permission");
            case INPUT_EVENT_INJECTION_SUCCEEDED:
                return true;
            case INPUT_EVENT_INJECTION_TIMED_OUT:
                Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
                return false;
            case INPUT_EVENT_INJECTION_FAILED:
            default:
                Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
                return false;
        }
    }


com_android_server_input_InputManagerService.cpp:
 
 
  static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
        jlong ptr, jobject inputEventObj, jint displayId, jint injectorPid, jint injectorUid,
        jint syncMode, jint timeoutMillis, jint policyFlags) {
    NativeInputManager* im = reinterpret_cast(ptr);


    if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
        KeyEvent keyEvent;
        status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
        if (status) {
            jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
            return INPUT_EVENT_INJECTION_FAILED;
        }


        return (jint) im->getInputManager()->getDispatcher()->injectInputEvent(
                & keyEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis,
                uint32_t(policyFlags));
    } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
        const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
        if (!motionEvent) {
            jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
            return INPUT_EVENT_INJECTION_FAILED;
        }


        return (jint) im->getInputManager()->getDispatcher()->injectInputEvent(
                motionEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis,
                uint32_t(policyFlags));    //跑到了这里
    } else {
        jniThrowRuntimeException(env, "Invalid input event type.");
        return INPUT_EVENT_INJECTION_FAILED;
    }
}




 inputdispatcher.cpp:


int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t displayId,
        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
        uint32_t policyFlags) {


  switch (event->getType()) {
    case AINPUT_EVENT_TYPE_KEY: {
ALOGE("matt-inputdispatcher-injectInputEvent");
        const KeyEvent* keyEvent = static_cast(event);
        int32_t action = keyEvent->getAction();
        if (! validateKeyEvent(action)) {
            return INPUT_EVENT_INJECTION_FAILED;
        }




  if (needWake) {
ALOGE(" matt-mLooper->wake();");
        mLooper->wake();
    }







之后怎么跳到下面的地方真的不知道
PhoneWindow.java:


 public boolean dispatchKeyEvent(KeyEvent event) {




 Log.d(TAG, "matt-dispatchKeyEvent-PhoneWindow.java  ");
            return isDown ? PhoneWindow.this.onKeyDown(mFeatureId, event.getKeyCode(), event)
                    : PhoneWindow.this.onKeyUp(mFeatureId, event.getKeyCode(), event);


}






 protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) {


    switch (keyCode) {
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_DOWN:
            case KeyEvent.KEYCODE_VOLUME_MUTE: {
Log.d(TAG, "matt-before switch (keyCode) ");
                int direction = 0;
                switch (keyCode) {
                    case KeyEvent.KEYCODE_VOLUME_UP:
                        direction = AudioManager.ADJUST_RAISE;
                        break;
                    case KeyEvent.KEYCODE_VOLUME_DOWN:
                        direction = AudioManager.ADJUST_LOWER;
                        break;
                    case KeyEvent.KEYCODE_VOLUME_MUTE:
Log.d(TAG, "matt-case KeyEvent.KEYCODE_VOLUME_MUTE ");
                        direction = AudioManager.ADJUST_TOGGLE_MUTE;
                        break;
                }


              if (mMediaController != null) {
Log.d(TAG, "matt- if (mMediaController != null)  ");
                    mMediaController.adjustVolume(direction, AudioManager.FLAG_SHOW_UI);
                } else {
                    MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy(  //跑到了这里
                            mVolumeControlStreamType, direction,
                            AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE
                                    | AudioManager.FLAG_FROM_KEY);
                }


}






MediaSessionLegacyHelper.java:
     public void sendAdjustVolumeBy(int suggestedStream, int delta, int flags) {
        mSessionManager.dispatchAdjustVolume(suggestedStream, delta, flags);
        if (DEBUG) {
            Log.d(TAG, "dispatched volume adjustment");
        }
    }




MediaSessionManager.java:


public void dispatchAdjustVolume(int suggestedStream, int direction, int flags) {
        try {
            mService.dispatchAdjustVolume(suggestedStream, direction, flags);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to send adjust volume.", e);
        }
    }




MediaSessionService.java:






 public void dispatchAdjustVolume(int suggestedStream, int delta, int flags) {
            final int pid = Binder.getCallingPid();
            final int uid = Binder.getCallingUid();
            final long token = Binder.clearCallingIdentity();
Log.d(TAG, "matt-MediaSessionService.java-dispatchAdjustVolume ");
            try {
                synchronized (mLock) {
                    MediaSessionRecord session = mPriorityStack
                            .getDefaultVolumeSession(mCurrentUserId);
                    dispatchAdjustVolumeLocked(suggestedStream, delta, flags, session);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }






 private void dispatchAdjustVolumeLocked(int suggestedStream, int direction, int flags,
                MediaSessionRecord session) {
           // if (DEBUG) {
                String description = session == null ? null : session.toString();
                Log.d(TAG, "matt-dispatchAdjustVolumeLocked-Adjusting session " + description + " by " + direction + ". flags="
                        + flags + ", suggestedStream=" + suggestedStream);


           // }
            boolean preferSuggestedStream = false;
            if (isValidLocalStreamType(suggestedStream)
                    && AudioSystem.isStreamActive(suggestedStream, 0)) {
                preferSuggestedStream = true;
            }
            if (session == null || preferSuggestedStream) {
Log.d(TAG, "matt- if (session == null");  //最后走了这边
                if ((flags & AudioManager.FLAG_ACTIVE_MEDIA_ONLY) != 0
                        && !AudioSystem.isStreamActive(AudioManager.STREAM_MUSIC, 0)) {
                    if (DEBUG) {
                        Log.d(TAG, "No active session to adjust, skipping media only volume event");
                    }
                    return;
                }
                try {
                    String packageName = getContext().getOpPackageName();
                    mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream,
                            flags, packageName, TAG);
                } catch (RemoteException e) {
                    Log.e(TAG, "Error adjusting default volume.", e);
                }
            } else {
            Log.d(TAG, "matt- else");
                session.adjustVolume(direction, flags, getContext().getPackageName(),
                        UserHandle.myUserId(), true);
            }
        }






AudioService.java :


 public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
            String callingPackage, String caller) {
        adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage,
                caller, Binder.getCallingUid());
    }




  private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
            String callingPackage, String caller, int uid) {
       Log.d(TAG, "matt-adjustSuggestedStreamVolume() stream=" + suggestedStreamType
                + ", flags=" + flags + ", caller=" + caller);
        int streamType;
        boolean isMute = isMuteAdjust(direction);
Log.d(TAG, "matt-adjustSuggestedStreamVolume+isMute=%d",isMute);
        if (mVolumeControlStream != -1) {
            streamType = mVolumeControlStream;
        } else {
            streamType = getActiveStreamType(suggestedStreamType);
        }
        ensureValidStreamType(streamType);
        final int resolvedStream = mStreamVolumeAlias[streamType];


        // Play sounds on STREAM_RING only.
        if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
                resolvedStream != AudioSystem.STREAM_RING) {
            flags &= ~AudioManager.FLAG_PLAY_SOUND;
        }


        // For notifications/ring, show the ui before making any adjustments
        // Don't suppress mute/unmute requests
        if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) {
            direction = 0;
            flags &= ~AudioManager.FLAG_PLAY_SOUND;
            flags &= ~AudioManager.FLAG_VIBRATE;
            if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
        }
       Log.d(TAG, "matt-adjustSuggestedStreamVolume+2");
        adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);
    }












private void adjustStreamVolume(int streamType, int direction, int flags,
            String callingPackage, String caller, int uid) {
        if (mUseFixedVolume) {
            return;
        }
         Log.e(TAG, "matt-adjustStreamVolume() stream=" + streamType + ", dir=" + direction
                + ", flags=" + flags + ", caller=" + caller);


        ensureValidDirection(direction);
        ensureValidStreamType(streamType);


        boolean isMuteAdjust = isMuteAdjust(direction);
Log.e(TAG, "matt-adjustStreamVolume+isMuteAdjust="+isMuteAdjust);


        if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
            return;
        }
  if (isMuteAdjust) {
                boolean state;
                if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
                    state = !streamState.mIsMuted;
                } else {
                    state = direction == AudioManager.ADJUST_MUTE;
                }


Log.e(TAG, "matt-adjustStreamVolume-state="+state);
                if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
                    setSystemAudioMute(state);
                }
                for (int stream = 0; stream < mStreamStates.length; stream++) {
                    if (streamTypeAlias == mStreamVolumeAlias[stream]) {
                        if (!(readCameraSoundForced()
                                    && (mStreamStates[stream].getStreamType()
                                        == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
                            mStreamStates[stream].mute(state);
                        }
                    }
                }
            
          }
}




 public void mute(boolean state) {
            boolean changed = false;
            synchronized (VolumeStreamState.class) {
                if (state != mIsMuted) {
                    changed = true;
                    mIsMuted = state;


                    // Set the new mute volume. This propagates the values to
                    // the audio system, otherwise the volume won't be changed
                    // at the lower level.
                    Log.e(TAG, "matt-mute");
                    sendMsg(mAudioHandler,
                            MSG_SET_ALL_VOLUMES,
                            SENDMSG_QUEUE,
                            0,
                            0,
                            this, 0);
                }
            }
 Log.e(TAG, "matt-mute+1");
            if (changed) {
                // Stream mute changed, fire the intent.
                Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
                intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
                intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state);
                sendBroadcastToAll(intent);
            }
        }
静音
02-20 14:35:08.551  1655  2894 D MediaSessionService: matt-MediaSessionService.java-dispatchAdjustVolume 
02-20 14:35:08.551  1655  2894 D MediaSessionService: matt-dispatchAdjustVolumeLocked-Adjusting session null by 101. flags=4113, suggestedStream=-2147483648
02-20 14:35:08.551  1655  2894 D MediaSessionService: matt- if (session == null
02-20 14:35:08.551  1655  2894 E AudioService: matt-adjustSuggestedStreamVolume() stream=-2147483648, flags=4113, caller=MediaSessionService
02-20 14:35:08.551  1655  2894 E AudioService: matt-adjustSuggestedStreamVolume+isMute=true
02-20 14:35:08.555  1655  2894 E AudioService: matt-adjustSuggestedStreamVolume+2
02-20 14:35:08.555  1655  2894 E AudioService: matt-adjustStreamVolume() stream=2, dir=101, flags=4113, caller=MediaSessionService
02-20 14:35:08.555  1655  2894 E AudioService: matt-adjustStreamVolume+isMuteAdjust=true
02-20 14:35:08.556  1655  2894 E AudioService: matt-adjustStreamVolume-state=true
02-20 14:35:08.556  1655  2894 E AudioService: matt-mute
02-20 14:35:08.556  1655  2894 E AudioService: matt-mute+1
02-20 14:35:08.557  1655  2894 E AudioService: matt-mute
02-20 14:35:08.557  1655  2894 E AudioService: matt-mute+1
02-20 14:35:08.558  1655  2894 E AudioService: matt-mute
02-20 14:35:08.558  1655  2894 E AudioService: matt-mute+1
02-20 14:35:08.558  1655  2894 E AudioService: matt-mute
02-20 14:35:08.558  1655  2894 E AudioService: matt-mute+1




取消静音


02-20 14:35:23.078  1655  2462 D MediaSessionService: matt-MediaSessionService.java-dispatchAdjustVolume 
02-20 14:35:23.078  1655  2462 D MediaSessionService: matt-dispatchAdjustVolumeLocked-Adjusting session null by 101. flags=4113, suggestedStream=-2147483648
02-20 14:35:23.078  1655  2462 D MediaSessionService: matt- if (session == null
02-20 14:35:23.078  1655  2462 E AudioService: matt-adjustSuggestedStreamVolume() stream=-2147483648, flags=4113, caller=MediaSessionService
02-20 14:35:23.078  1655  2462 E AudioService: matt-adjustSuggestedStreamVolume+isMute=true
02-20 14:35:23.083  1655  2462 E AudioService: matt-adjustSuggestedStreamVolume+2
02-20 14:35:23.083  1655  2462 E AudioService: matt-adjustStreamVolume() stream=2, dir=101, flags=4113, caller=MediaSessionService
02-20 14:35:23.083  1655  2462 E AudioService: matt-adjustStreamVolume+isMuteAdjust=true
02-20 14:35:23.083  1655  2462 E AudioService: matt-adjustStreamVolume-state=false
02-20 14:35:23.083  1655  2462 E AudioService: matt-mute
02-20 14:35:23.083  1655  2462 E AudioService: matt-mute+1
02-20 14:35:23.086  1655  2462 E AudioService: matt-mute
02-20 14:35:23.086  1655  2462 E AudioService: matt-mute+1
02-20 14:35:23.086  1655  2462 E AudioService: matt-mute
02-20 14:35:23.086  1655  2462 E AudioService: matt-mute+1
02-20 14:35:23.088  1655  2462 E AudioService: matt-mute
02-20 14:35:23.088  1655  2462 E AudioService: matt-mute+1




















你可能感兴趣的:(android)