android系统 默认提示音控制流程

android系统 默认提示音控制流程,第1张

概述以下是源码分析流程:第一步:frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java  1.   publicvoidonCreate(){       super.onCreate();       Log.v(TAG,"SystemUIApplicationcreated.");       

以下是源码分析流程:
第一步:
frameworks/base/packages/systemUI/src/com/androID/systemUI/systemUIApplication.java
   1.
    public voID onCreate() {
        super.onCreate();
        Log.v(TAG, "systemUIApplication created.");
        // This line is used to setup Dagger's dependency injection and should be kept at the
        // top of this method.
        TimingsTraceLog log = new TimingsTraceLog("systemUIBoottiming",
                Trace.TRACE_TAG_APP);
        log.traceBegin("DependencyInjection");
        mContextAvailableCallback.onContextAvailable(this);
        mRootComponent = systemUIFactory.getInstance().getRootComponent();
        mComponentHelper = mRootComponent.getContextComponentHelper();
        mBootCompleteCache = mRootComponent.provIDeBootCacheImpl();
        log.traceEnd();

        // Set the application theme that is inherited by all services. Note that setting the
        // application theme in the manifest does only work for activitIEs. Keep this in sync with
        // the theme set there.
        settheme(R.style.theme_systemUI);

        if (Process.myUserHandle().equals(UserHandle.SYstem)) {
            IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
            bootCompletedFilter.setPriority(IntentFilter.SYstem_HIGH_PRIORITY);
            registerReceiver(new broadcastReceiver() {
                @OverrIDe
                public voID onReceive(Context context, Intent intent) {
                    if (mBootCompleteCache.isBootComplete()) return;

                    if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received");
                    unregisterReceiver(this);
                    mBootCompleteCache.setBootComplete();
                    if (mServicesstarted) {
                        final int N = mServices.length;
                        for (int i = 0; i < N; i++) {
                            mServices[i].onBootCompleted();
                        }
                    }
                }
            }, bootCompletedFilter);

            IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
            registerReceiver(new broadcastReceiver() {
                @OverrIDe
                public voID onReceive(Context context, Intent intent) {
                    if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
                        if (!mBootCompleteCache.isBootComplete()) return;
                        // Update names of systemUI notification channels
                        NotificationChannels.createall(context);
                    }
                }
            }, localeChangedFilter);
        } else {
            // We don't need to startServices for sub-process that is doing some tasks.
            // (screenshots, sweetsweetdesserts or tuner ..)
            String processname = ActivityThread.currentProcessname();
            ApplicationInfo info = getApplicationInfo();
            if (processname != null && processname.startsWith(info.processname + ":")) {
                return;
            }
            // For a secondary user, boot-completed will never be called because it has already
            // been broadcasted on startup for the primary systemUI process.  Instead, for
            // components which require the systemUI component to be initialized per-user, we
            // start those components Now for the current non-system user.
            startSecondaryUserServicesIfNeeded();   会走这里
        }
    }


    2.
        voID startSecondaryUserServicesIfNeeded() {
        String[] names = systemUIFactory.getInstance().getsystemUIServiceComponentsPerUser(   //这里从config.xml文件里面获取服务名称
                getResources());
        startServicesIfNeeded(/* metricsPrefix= */ "StartSecondaryServices", names);
    }

   3.
   frameworks/base/packages/systemUI/res/values/config.xml
    <string-array name="config_systemUIServiceComponents" translatable="false">
        <item>com.androID.systemUI.util.NotificationChannels</item>
        <item>com.androID.systemUI.keyguard.KeyguardVIEwMediator</item>
        <item>com.androID.systemUI.recents.Recents</item>
        <item>com.androID.systemUI.volume.VolumeUI</item>
        <item>com.androID.systemUI.stackdivIDer.divIDer</item>
        <item>com.androID.systemUI.statusbar.phone.Statusbar</item>
        <item>com.androID.systemUI.usb.StorageNotification</item>
        <item>com.androID.systemUI.power.PowerUI</item>
        <item>com.androID.systemUI.media.ringtonePlayer</item>
        <item>com.androID.systemUI.keyboard.KeyboardUI</item>
        <item>com.androID.systemUI.pip.PipUI</item>
        <item>com.androID.systemUI.shortcut.ShortcutKeydispatcher</item>
        <item>@string/config_systemUIvendorServiceComponent</item>
        <item>com.androID.systemUI.util.leak.GarbageMonitor$Service</item>
        <item>com.androID.systemUI.LatencyTester</item>
        <item>com.androID.systemUI.globalactions.GlobalActionsComponent</item>
        <item>com.androID.systemUI.Screendecorations</item>
        <item>com.androID.systemUI.biometrics.AuthController</item>
        <item>com.androID.systemUI.SlicebroadcastRelayHandler</item>
        <item>com.androID.systemUI.SizeCompatModeActivityController</item>
        <item>com.androID.systemUI.statusbar.notification.InstantAppNotifIEr</item>
        <item>com.androID.systemUI.theme.themeOverlayController</item>
        <item>com.androID.systemUI.accessibility.WindowMagnification</item>
        <item>com.androID.systemUI.accessibility.SystemActions</item>
        <item>com.androID.systemUI.toast.ToastUI</item>
    </string-array>


    4.
    private voID startServicesIfNeeded(String metricsPrefix, String[] services) {
        if (mServicesstarted) {
            return;
        }
        mServices = new systemUI[services.length];

        if (!mBootCompleteCache.isBootComplete()) {
            // check to see if maybe it was already completed long before we began
            // see ActivityManagerService.finishBooting()
            if ("1".equals(SystemPropertIEs.get("sys.boot_completed"))) {
                mBootCompleteCache.setBootComplete();
                if (DEBUG) {
                    Log.v(TAG, "BOOT_COMPLETED was already sent");
                }
            }
        }

        final DumpManager dumpManager = mRootComponent.createDumpManager();

        Log.v(TAG, "Starting systemUI services for user " +
                Process.myUserHandle().getIDentifIEr() + ".");
        TimingsTraceLog log = new TimingsTraceLog("systemUIBoottiming",
                Trace.TRACE_TAG_APP);
        log.traceBegin(metricsPrefix);
        final int N = services.length;
        for (int i = 0; i < N; i++) {
            String clsname = services[i];
            if (DEBUG) Log.d(TAG, "loading: " + clsname);
            log.traceBegin(metricsPrefix + clsname);
            long ti = System.currentTimeMillis();
            try {
                systemUI obj = mComponentHelper.resolvesystemUI(clsname);
                if (obj == null) {
                    Constructor constructor = Class.forname(clsname).getConstructor(Context.class);
                    obj = (systemUI) constructor.newInstance(this);
                }
                mServices[i] = obj;
            } catch (ClassNotFoundException
                    | NoSuchMethodException
                    | illegalaccessexception
                    | InstantiationException
                    | InvocationTargetException ex) {
                throw new RuntimeException(ex);
            }

            if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
            mServices[i].start();   这里会启动ringtonePlayer 服务
            log.traceEnd();

            // Warn if initialization of component takes too long
            ti = System.currentTimeMillis() - ti;
            if (ti > 1000) {
                Log.w(TAG, "Initialization of " + clsname + " took " + ti + " ms");
            }
            if (mBootCompleteCache.isBootComplete()) {
                mServices[i].onBootCompleted();
            }

            dumpManager.registerDumpable(mServices[i].getClass().getname(), mServices[i]);
        }
        mRootComponent.getinitController().executePostinitTasks();
        log.traceEnd();

        mServicesstarted = true;
    }


第二步:
frameworks/base/packages/systemUI/src/com/androID/systemUI/media/ringtonePlayer.java

  public voID start() {
        mAsyncPlayer.setUsesWakeLock(mContext);

        mAudioService = IAudioService.Stub.asInterface(
                ServiceManager.getService(Context.AUdio_SERVICE));
        try {
            mAudioService.setringtonePlayer(mCallback);   mAudioService设置IringtonePlayer的回调
        } catch (remoteexception e) {
            Log.e(TAG, "Problem registering ringtonePlayer: " + e);
        }
    }

 

    @OverrIDe
        public voID playAsync(Uri uri, UserHandle user, boolean looPing, AudioAttributes aa) {
            if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");
            if (Binder.getCallingUID() != Process.SYstem_UID) {
                throw new SecurityException("Async playback only available from system UID.");
            }
            if (UserHandle.ALL.equals(user)) {
                user = UserHandle.SYstem;
            }
       Log.e(TAG, Log.getStackTraceString(new Throwable()));
            mAsyncPlayer.play(getContextForUser(user), uri, looPing, aa);
        }

 

第三步:
frameworks/base/services/core/java/com/androID/server/notification/notificationmanagerService.java
 
          if (mAssistants.isEnabled()) {
                    mAssistants.onNotificationEnqueuedLocked(r);
                    mHandler.postDelayed(new PostNotificationRunnable(r.getKey()),
                            DELAY_FOR_ASSISTANT_TIME);
                } else {
                    mHandler.post(new PostNotificationRunnable(r.getKey()));  这里开始PostNotificationRunnable 线程运行
                }

 

  final boolean isPackageSuspended =
                            isPackagePausedOrSuspended(r.getSbn().getPackagename(), r.getUID());
                    r.setHIDden(isPackageSuspended);
    int buzzBeepBlinkLoggingCode = 0;
                    if (!r.isHIDden()) {
                        buzzBeepBlinkLoggingCode = buzzBeepBlinkLocked(r);
                    }

    

 

 int buzzBeepBlinkLocked(NotificationRecord record) {
        Log.e(TAG,"zhanghui                  buzzBeepBlinkLocked   1.0");
        if (mIsautomotive && !mNotificationEffectsEnabledForautomotive) {
            return 0;
        }
        boolean buzz = false;
        boolean beep = false;
        boolean blink = false;

        final Notification notification = record.getSbn().getNotification();
        final String key = record.getKey();
            Log.e(TAG,"zhanghui                  buzzBeepBlinkLocked   1.0.0");
        // Should this notification make noise, vibe, or use the LED?
        final boolean aboveThreshold =
                mIsautomotive
                        ? record.getimportance() > notificationmanager.importANCE_DEFAulT
                        : record.getimportance() >= notificationmanager.importANCE_DEFAulT;
        // Remember if this notification already owns the notification channels.
        boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
        boolean wasBuzz = key != null && key.equals(mVibrateNotificationKey);
        // These are set insIDe the conditional if the notification is allowed to make noise.
        boolean hasValIDVibrate = false;
        boolean hasValIDSound = false;
        boolean sentAccessibilityEvent = false;
       Log.e(TAG,"zhanghui                  buzzBeepBlinkLocked   1.1");
        // If the notification will appear in the status bar, it should send an accessibility event
        final boolean suppressedByDnd = record.isIntercepted()
                && (record.getSuppressedVisualEffects() & SUPpressed_EFFECT_STATUS_bar) != 0;
        if (!record.isUpdate
                && record.getimportance() > importANCE_MIN
                && !suppressedByDnd) {
            sendAccessibilityEvent(notification, record.getSbn().getPackagename());
            sentAccessibilityEvent = true;
        }
     Log.e(TAG,"zhanghui                  buzzBeepBlinkLocked   1.2 aboveThreshold="+aboveThreshold);
     Log.e(TAG,"zhanghui                  buzzBeepBlinkLocked   1.2  isNotificationForCurrentUser(record)="+ isNotificationForCurrentUser(record));
        if (aboveThreshold && isNotificationForCurrentUser(record)) {
            Log.e(TAG,"zhanghui                  buzzBeepBlinkLocked   1.2 mSystemReady="+mSystemReady);
        if(mAudioManager != null){
        Log.e(TAG,"zhanghui                  buzzBeepBlinkLocked    mAudioManager is true");
       }
            if (mSystemReady && mAudioManager != null) {
                Uri soundUri = record.getSound();
                hasValIDSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
                long[] vibration = record.getVibration();
                // Demote sound to vibration if vibration missing & phone in vibration mode.
                if (vibration == null
                        && hasValIDSound
                        && (mAudioManager.getRingerModeInternal()
                        == AudioManager.RINGER_MODE_VIBRATE)
                        && mAudioManager.getStreamVolume(
                        AudioAttributes.tolegacyStreamType(record.getAudioAttributes())) == 0) {
                    vibration = mFallbackVibrationPattern;
                }
                hasValIDVibrate = vibration != null;
                boolean hasAudibleAlert = hasValIDSound || hasValIDVibrate;
        Log.e(TAG,"zhanghui     hasAudibleAlert="+hasAudibleAlert);
                if (hasAudibleAlert && !shouldMuteNotificationLocked(record)) {  //shouldMuteNotificationLocked这里很关键,高通原生第一次升级默认没有提示音(比如:蓝牙传输接收文件没有提示音)
                    if (!sentAccessibilityEvent) {
                        sendAccessibilityEvent(notification, record.getSbn().getPackagename());
                        sentAccessibilityEvent = true;
                    }
                    if (DBG) Slog.v(TAG, "Interrupting!");
         Log.e(TAG,"zhanghui                  buzzBeepBlinkLocked   1.2 hasValIDSound="+hasValIDSound);
                    if (hasValIDSound) {
                        if (isInCall()) {
                            playInCallNotification();
                            beep = true;
                        } else {
                            beep = playSound(record, soundUri);  跑这里调用
                        }
                        if(beep) {
                            mSoundNotificationKey = key;
                        }
                    }

                    final boolean ringerModeSilent =
                            mAudioManager.getRingerModeInternal()
                                    == AudioManager.RINGER_MODE_SILENT;
                    if (!isInCall() && hasValIDVibrate && !ringerModeSilent) {
                        buzz = playVibration(record, vibration, hasValIDSound);
                        if(buzz) {
                            mVibrateNotificationKey = key;
                        }
                    }
                } else if ((record.getFlags() & Notification.FLAG_INSISTENT) != 0) {
                    hasValIDSound = false;
                }
            }
        }
        // If a notification is updated to remove the actively playing sound or vibrate,
        // cancel that Feedback Now
        if (wasBeep && !hasValIDSound) {
            clearSoundLocked();
        }
        if (wasBuzz && !hasValIDVibrate) {
            clearVibrateLocked();
        }

        // light
        // release the light
        boolean wasShowlights = mlights.remove(key);
        if (canShowlightsLocked(record, aboveThreshold)) {
            mlights.add(key);
            updatelightsLocked();
            if (mUseAttentionlight && mAttentionlight != null) {
                mAttentionlight.pulse();
            }
            blink = true;
        } else if (wasShowlights) {
            updatelightsLocked();
        }
        final int buzzBeepBlink = (buzz ? 1 : 0) | (beep ? 2 : 0) | (blink ? 4 : 0);
        if (buzzBeepBlink > 0) {
            // Ignore summary updates because we don't display most of the information.
            if (record.getSbn().isGroup() && record.getSbn().getNotification().isGroupSummary()) {
                if (DEBUG_INTERRUPTIVEnesS) {
                    Slog.v(TAG, "INTERRUPTIVEnesS: "
                            + record.getKey() + " is not interruptive: summary");
                }
            } else if (record.canBubble()) {
                if (DEBUG_INTERRUPTIVEnesS) {
                    Slog.v(TAG, "INTERRUPTIVEnesS: "
                            + record.getKey() + " is not interruptive: bubble");
                }
            } else {
                record.setInterruptive(true);
                if (DEBUG_INTERRUPTIVEnesS) {
                    Slog.v(TAG, "INTERRUPTIVEnesS: "
                            + record.getKey() + " is interruptive: alerted");
                }
            }
            Metricslogger.action(record.getLogMaker()
                    .setcategory(MetricsEvent.NOTIFICATION_ALERT)
                    .setType(MetricsEvent.TYPE_OPEN)
                    .setSubtype(buzzBeepBlink));
            EventLogTags.writeNotificationAlert(key, buzz ? 1 : 0, beep ? 1 : 0, blink ? 1 : 0);
        }
        record.setAudiblyAlerted(buzz || beep);
        return buzzBeepBlink;
    }

 


 private boolean playSound(final NotificationRecord record, Uri soundUri) {
        boolean looPing = (record.getNotification().flags & FLAG_INSISTENT) != 0;
        // play notifications if there is no user of exclusive audio focus
        // and the stream volume is not 0 (non-zero volume implIEs not silenced by SILENT or
        //   VIBRATE ringer mode)
        if (!mAudioManager.isAudioFocusExclusive()
                && (mAudioManager.getStreamVolume(
                        AudioAttributes.tolegacyStreamType(record.getAudioAttributes())) != 0)) {
            final long IDentity = Binder.clearCallingIDentity();
            try {
                final IringtonePlayer player = mAudioManager.getringtonePlayer();
                if (player != null) {
                    if (true) Slog.v(TAG, "zhanghui  Playing sound " + soundUri
                            + " with attributes " + record.getAudioAttributes());
            Log.e(TAG, Log.getStackTraceString(new Throwable()));
                    player.playAsync(soundUri, record.getSbn().getUser(), looPing,   这里跑到第二步的ringtonePlayer回调函数的playAsync,这里传入的soundUri 就是后面播放的提示音文件缓存
                            record.getAudioAttributes());
                    return true;
                }
            } catch (remoteexception e) {
            } finally {
                Binder.restoreCallingIDentity(IDentity);
            }
        }
        return false;
    }

第四步:
frameworks/base/packages/systemUI/src/com/androID/systemUI/media/ringtonePlayer.java

  public voID start() {
        mAsyncPlayer.setUsesWakeLock(mContext);

        mAudioService = IAudioService.Stub.asInterface(
                ServiceManager.getService(Context.AUdio_SERVICE));
        try {
            mAudioService.setringtonePlayer(mCallback);   mAudioService设置IringtonePlayer的回调
        } catch (remoteexception e) {
            Log.e(TAG, "Problem registering ringtonePlayer: " + e);
        }
    }

 

    @OverrIDe
        public voID playAsync(Uri uri, UserHandle user, boolean looPing, AudioAttributes aa) {
            if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");
            if (Binder.getCallingUID() != Process.SYstem_UID) {
                throw new SecurityException("Async playback only available from system UID.");
            }
            if (UserHandle.ALL.equals(user)) {
                user = UserHandle.SYstem;
            }
       Log.e(TAG, Log.getStackTraceString(new Throwable()));
            mAsyncPlayer.play(getContextForUser(user), uri, looPing, aa);  这里跑到NotificationPlayer类的play()
        }

frameworks/base/packages/systemUI/src/com/androID/systemUI/media/NotificationPlayer.java


 public voID play(Context context, Uri uri, boolean looPing, AudioAttributes attributes) {
        if (DEBUG) { Log.d(mTag, "play uri=" + uri.toString()); }
        Command cmd = new Command();
        cmd.requestTime = SystemClock.uptimeMillis();
        cmd.code = PLAY;
        cmd.context = context;
        cmd.uri = uri;
        cmd.looPing = looPing;
        cmd.attributes = attributes;
        synchronized (mCmdQueue) {
            enqueueLocked(cmd);
            mState = PLAY;
        }
    }

 

        private voID enqueueLocked(Command cmd) {
        mCmdQueue.add(cmd);
        if (mThread == null) {
            acquireWakeLock();
            mThread = new CmdThread();
            mThread.start();
        }
    }


      private final class CmdThread extends java.lang.Thread {
        CmdThread() {
            super("NotificationPlayer-" + mTag);
        }

        public voID run() {
            while (true) {
                Command cmd = null;

                synchronized (mCmdQueue) {
                    if (DEBUG) Log.d(mTag, "RemoveFirst");
                    cmd = mCmdQueue.removeFirst();
                }

                switch (cmd.code) {
                case PLAY:
                    if (DEBUG) Log.d(mTag, "PLAY");
                    startSound(cmd);  这里跑到CreationAndCompletionThread 线程
                    break;
                case Stop:
                    if (DEBUG) Log.d(mTag, "Stop");
                    final MediaPlayer mp;
                    synchronized (mPlayerLock) {
                        mp = mPlayer;
                        mPlayer = null;
                    }
                    if (mp != null) {
                        long delay = SystemClock.uptimeMillis() - cmd.requestTime;
                        if (delay > 1000) {
                            Log.w(mTag, "Notification stop delayed by " + delay + "msecs");
                        }
                        try {
                            mp.stop();
                        } catch (Exception e) { }
                        mp.release();
                        synchronized(mQueueAudioFocusLock) {
                            if (mAudioManagerWithAudioFocus != null) {
                                if (DEBUG) { Log.d(mTag, "in Stop: abandonning AudioFocus"); }
                                mAudioManagerWithAudioFocus.abandonAudioFocus(null);
                                mAudioManagerWithAudioFocus = null;
                            }
                        }
                        synchronized (mCompletionHandlingLock) {
                            if ((mLooper != null) &&
                                    (mLooper.getThread().getState() != Thread.State.TERMINATED))
                            {
                                if (DEBUG) { Log.d(mTag, "in Stop: quitting looper "+ mLooper); }
                                mLooper.quit();
                            }
                        }
                    } else {
                        Log.w(mTag, "Stop command without a player");
                    }
                    break;
                }

 


 private final class CreationAndCompletionThread extends Thread {
        public Command mCmd;
        public CreationAndCompletionThread(Command cmd) {
            super();
            mCmd = cmd;
        }

        public voID run() {
            Looper.prepare();
            // ok to modify mLooper as here we are
            // synchronized on mCompletionHandlingLock due to the Object.wait() in startSound(cmd)
            mLooper = Looper.myLooper();
            if (DEBUG) Log.d(mTag, "in run: new looper " + mLooper);
            MediaPlayer player = null;
            synchronized(this) {
                AudioManager audioManager =
                    (AudioManager) mCmd.context.getSystemService(Context.AUdio_SERVICE);
                try {
                    player = new MediaPlayer();
                    if (mCmd.attributes == null) {
                        mCmd.attributes = new AudioAttributes.Builder()
                                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                                .build();
                    }
                    player.setAudioAttributes(mCmd.attributes);
                    player.setDataSource(mCmd.context, mCmd.uri);  这里调用了MediaPlayer里面的setDataSource
                    player.setLooPing(mCmd.looPing);
                    player.setonCompletionListener(NotificationPlayer.this);
                    player.setonErrorListener(NotificationPlayer.this);
                    player.prepare();
                    if ((mCmd.uri != null) && (mCmd.uri.getEncodedpath() != null)
                            && (mCmd.uri.getEncodedpath().length() > 0)) {
                        if (!audioManager.isMusicActiveRemotely()) {
                            synchronized (mQueueAudioFocusLock) {
                                if (mAudioManagerWithAudioFocus == null) {
                                    if (DEBUG) Log.d(mTag, "requesting AudioFocus");
                                    int focusGain = AudioManager.AUdioFOCUS_GAIN_TRANSIENT_MAY_DUCK;
                                    if (mCmd.looPing) {
                                        focusGain = AudioManager.AUdioFOCUS_GAIN;
                                    }
                                    mNotificationRampTimeMs = audioManager.getFocusRampTimeMs(
                                            focusGain, mCmd.attributes);
                                    audioManager.requestAudioFocus(null, mCmd.attributes,
                                                focusGain, 0);
                                    mAudioManagerWithAudioFocus = audioManager;
                                } else {
                                    if (DEBUG) Log.d(mTag, "AudioFocus was prevIoUsly requested");
                                }
                            }
                        }
                    }
                    // FIXME Having to start a new thread so we can receive completion callbacks
                    //  is wrong, as we kill this thread whenever a new sound is to be played. This
                    //  can lead to AudioFocus being released too early, before the second sound is
                    //  done playing. This class should be modifIEd to use a single thread, on which
                    //  command are issued, and on which it receives the completion callbacks.
                    if (DEBUG)  { Log.d(mTag, "notification will be delayed by "
                            + mNotificationRampTimeMs + "ms"); }
                    try {
                        Thread.sleep(mNotificationRampTimeMs);
                    } catch (InterruptedException e) {
                        Log.e(mTag, "Exception while sleePing to sync notification playback"
                                + " with ducking", e);
                    }
                    player.start();
                    if (DEBUG) { Log.d(mTag, "player.start"); }
                } catch (Exception e) {
                    if (player != null) {
                        player.release();
                        player = null;
                    }
                    Log.w(mTag, "error loading sound for " + mCmd.uri, e);
                    // playing the notification dIDn't work, revert the focus request
                    abandonAudioFocusAfterError();
                }
                final MediaPlayer mp;
                synchronized (mPlayerLock) {
                    mp = mPlayer;
                    mPlayer = player;
                }
                if (mp != null) {
                    if (DEBUG) { Log.d(mTag, "mPlayer.release"); }
                    mp.release();
                }
                this.notify();
            }
            Looper.loop();
        }
    };

frameworks/base/media/java/androID/media/MediaPlayer.java


 private boolean attemptDataSource(ContentResolver resolver, Uri uri) {
        try (AssetfileDescriptor afd = resolver.openAssetfileDescriptor(uri, "r")) {   这里跑到了ContentResolver里面的openAssetfileDescriptor
            setDataSource(afd);
            return true;
        } catch (NullPointerException | SecurityException | IOException ex) {
            return false;
        }
    }


    public voID setDataSource(String path)
            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        setDataSource(path, null, null);
    }

 


  public voID setDataSource(@NonNull Context context, @NonNull Uri uri)
            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        setDataSource(context, uri, null, null);
    }

 


      private voID setDataSource(String path, String[] keys, String[] values,
            List<httpcookie> cookies)
            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        final Uri uri = Uri.parse(path);
        final String scheme = uri.getScheme();

        if ("file".equals(scheme)) {
            path = uri.getPath();
    Log.e(TAG,"zhanghui              path="+path);
        } else if (scheme != null) {
            // handle non-file sources
            nativeSetDataSource(      
                MediahttpService.createhttpServiceBinderIfNecessary(path, cookies),
                path,
                keys,
                values);
            return;
        }

        final file file = new file(path);
        try (fileinputStream is = new fileinputStream(file)) {
    Log.e(TAG,"zhanghui              is.getFD()="+is.getFD());
            setDataSource(is.getFD());
        }
    }


frameworks/base/core/java/androID/content/ContentResolver.java

    public final @Nullable AssetfileDescriptor openAssetfileDescriptor(@NonNull Uri uri,
            @NonNull String mode) throws fileNotFoundException {
        return openAssetfileDescriptor(uri, mode, null);
    }


 public final @Nullable AssetfileDescriptor openAssetfileDescriptor(@NonNull Uri uri,
            @NonNull String mode, @Nullable CancellationSignal cancellationSignal)
                    throws fileNotFoundException {
        Objects.requireNonNull(uri, "uri");
        Objects.requireNonNull(mode, "mode");

        try {
            if (mWrapped != null) return mWrapped.openAssetfile(uri, mode, cancellationSignal);
        } catch (remoteexception e) {
            return null;
        }

        String scheme = uri.getScheme();
        if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
            if (!"r".equals(mode)) {
                throw new fileNotFoundException("Can't write resources: " + uri);
            }
            OpenResourceIDResult r = getResourceID(uri);
            try {
                return r.r.openRawResourceFd(r.ID);
            } catch (Resources.NotFoundException ex) {
                throw new fileNotFoundException("Resource does not exist: " + uri);
            }
        } else if (SCHEME_file.equals(scheme)) {
            ParcelfileDescriptor pfd = ParcelfileDescriptor.open(
                    new file(uri.getPath()), ParcelfileDescriptor.parseMode(mode));
            return new AssetfileDescriptor(pfd, 0, -1);
        } else {
            if ("r".equals(mode)) {
                return openTypedAssetfileDescriptor(uri, "*/*", null, cancellationSignal);
            } else {
                IContentProvIDer unstableProvIDer = acquireUnstableProvIDer(uri);
                if (unstableProvIDer == null) {
                    throw new fileNotFoundException("No content provIDer: " + uri);
                }
                IContentProvIDer stableProvIDer = null;
                AssetfileDescriptor fd = null;

                try {
                    ICancellationSignal remoteCancellationSignal = null;
                    if (cancellationSignal != null) {
                        cancellationSignal.throwIfCanceled();
                        remoteCancellationSignal = unstableProvIDer.createCancellationSignal();
                        cancellationSignal.setRemote(remoteCancellationSignal);
                    }

                    try {
                        fd = unstableProvIDer.openAssetfile(
                                mPackagename, mAttributionTag, uri, mode,
                                remoteCancellationSignal);
                        if (fd == null) {
                            // The provIDer will be released by the finally{} clause
                            return null;
                        }
                    } catch (DeadobjectException e) {
                        // The remote process has dIEd...  but we only hold an unstable
                        // reference though, so we might recover!!!  Let's try!!!!
                        // This is exciting!!1!!1!!!!1
                        unstableProvIDerDIEd(unstableProvIDer);
                        stableProvIDer = acquireProvIDer(uri);
                        if (stableProvIDer == null) {
                            throw new fileNotFoundException("No content provIDer: " + uri);
                        }
                        fd = stableProvIDer.openAssetfile(
                                mPackagename, mAttributionTag, uri, mode, remoteCancellationSignal);
                        if (fd == null) {
                            // The provIDer will be released by the finally{} clause
                            return null;
                        }
                    }

                    if (stableProvIDer == null) {
                        stableProvIDer = acquireProvIDer(uri);
                    }
                    releaseUnstableProvIDer(unstableProvIDer);
                    unstableProvIDer = null;
                    ParcelfileDescriptor pfd = new ParcelfileDescriptorInner(
                            fd.getParcelfileDescriptor(), stableProvIDer);

                    // Success!  Don't release the provIDer when exiting, let
                    // ParcelfileDescriptorInner do that when it is closed.
                    stableProvIDer = null;

                    return new AssetfileDescriptor(pfd, fd.getStartOffset(),
                            fd.getDeclaredLength());

                } catch (remoteexception e) {
                    // Whatever, whatever, we'll go away.
                    throw new fileNotFoundException(
                            "Failed opening content provIDer: " + uri);
                } catch (fileNotFoundException e) {
                    throw e;
                } finally {
                    if (cancellationSignal != null) {
                        cancellationSignal.setRemote(null);
                    }
                    if (stableProvIDer != null) {
                        releaseProvIDer(stableProvIDer);
                    }
                    if (unstableProvIDer != null) {
                        releaseUnstableProvIDer(unstableProvIDer);
                    }
                }
            }
        }
    }

 

总结

以上是内存溢出为你收集整理的android系统 默认提示音控制流程全部内容,希望文章能够帮你解决android系统 默认提示音控制流程所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1019660.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存