RK3128系列之Android7.1去掉开机铃声并弄成可配置的

文章详细介绍了在RK3128系列设备上,如何在Android7.1系统中移除开机铃声。通过修改`PowerManagerNotifier`类中的`playWirelessChargingStartedSound`函数,添加一个可配置的属性`CHARGING_SOUNDS_ENABLED`,根据该属性值决定是否播放开机声音。此外,还提到了开机声音文件的配置路径和默认值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RK3128系列之Android7.1去掉开机铃声

1.第一步找到播放开机语音的位置

代码:

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.power;

import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.RetailDemoModeServiceInternal;

import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;

import android.app.ActivityManagerNative;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.hardware.input.InputManagerInternal;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
import android.util.EventLog;
import android.util.Slog;
import android.view.WindowManagerPolicy;
import android.view.inputmethod.InputMethodManagerInternal;
import android.os.SystemProperties;

/**
 * Sends broadcasts about important power state changes.
 * <p>
 * This methods of this class may be called by the power manager service while
 * its lock is being held.  Internally it takes care of sending broadcasts to
 * notify other components of the system or applications asynchronously.
 * </p><p>
 * The notifier is designed to collapse unnecessary broadcasts when it is not
 * possible for the system to have observed an intermediate state.
 * </p><p>
 * For example, if the device wakes up, goes to sleep, wakes up again and goes to
 * sleep again before the wake up notification is sent, then the system will
 * be told about only one wake up and sleep.  However, we always notify the
 * fact that at least one transition occurred.  It is especially important to
 * tell the system when we go to sleep so that it can lock the keyguard if needed.
 * </p>
 */
final class Notifier {
    private static final String TAG = "PowerManagerNotifier";

    private static final boolean DEBUG = false;

    private static final int INTERACTIVE_STATE_UNKNOWN = 0;
    private static final int INTERACTIVE_STATE_AWAKE = 1;
    private static final int INTERACTIVE_STATE_ASLEEP = 2;

    private static final int MSG_USER_ACTIVITY = 1;
    private static final int MSG_BROADCAST = 2;
    private static final int MSG_WIRELESS_CHARGING_STARTED = 3;
    private static final int MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED = 4;

    private final Object mLock = new Object();

    private final Context mContext;
    private final IBatteryStats mBatteryStats;
    private final IAppOpsService mAppOps;
    private final SuspendBlocker mSuspendBlocker;
    private final WindowManagerPolicy mPolicy;
    private final ActivityManagerInternal mActivityManagerInternal;
    private final InputManagerInternal mInputManagerInternal;
    private final InputMethodManagerInternal mInputMethodManagerInternal;
    private final RetailDemoModeServiceInternal mRetailDemoModeServiceInternal;

    private final NotifierHandler mHandler;
    private final Intent mScreenOnIntent;
    private final Intent mScreenOffIntent;
    private final Intent mScreenBrightnessBoostIntent;

    // True if the device should suspend when the screen is off due to proximity.
    private final boolean mSuspendWhenScreenOffDueToProximityConfig;

    // The current interactive state.  This is set as soon as an interactive state
    // transition begins so as to capture the reason that it happened.  At some point
    // this state will propagate to the pending state then eventually to the
    // broadcasted state over the course of reporting the transition asynchronously.
    private boolean mInteractive = true;
    private int mInteractiveChangeReason;
    private boolean mInteractiveChanging;

    // The pending interactive state that we will eventually want to broadcast.
    // This is designed so that we can collapse redundant sequences of awake/sleep
    // transition pairs while still guaranteeing that at least one transition is observed
    // whenever this happens.
    private int mPendingInteractiveState;
    private boolean mPendingWakeUpBroadcast;
    private boolean mPendingGoToSleepBroadcast;

    // The currently broadcasted interactive state.  This reflects what other parts of the
    // system have observed.
    private int mBroadcastedInteractiveState;
    private boolean mBroadcastInProgress;
    private long mBroadcastStartTime;

    // True if a user activity message should be sent.
    private boolean mUserActivityPending;

    public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
            IAppOpsService appOps, SuspendBlocker suspendBlocker,
            WindowManagerPolicy policy) {
        mContext = context;
        mBatteryStats = batteryStats;
        mAppOps = appOps;
        mSuspendBlocker = suspendBlocker;
        mPolicy = policy;
        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
        mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
        mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
        mRetailDemoModeServiceInternal = LocalServices.getService(RetailDemoModeServiceInternal.class);

        mHandler = new NotifierHandler(looper);
        mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
        mScreenOnIntent.addFlags(
                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
        mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
        mScreenOffIntent.addFlags(
                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
        mScreenBrightnessBoostIntent =
                new Intent(PowerManager.ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED);
        mScreenBrightnessBoostIntent.addFlags(
                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);

        mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
                com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);

        // Initialize interactive state for battery stats.
        try {
            mBatteryStats.noteInteractive(true);
        } catch (RemoteException ex) { }
    }

    /**
     * Called when a wake lock is acquired.
     */
    public void onWakeLockAcquired(int flags, String tag, String packageName,
            int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
        if (DEBUG) {
            Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
                    + "\", packageName=" + packageName
                    + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
                    + ", workSource=" + workSource);
        }

        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
        if (monitorType >= 0) {
            try {
                final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
                        && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
                if (workSource != null) {
                    mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
                            historyTag, monitorType, unimportantForLogging);
                } else {
                    mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
                            monitorType, unimportantForLogging);
                    // XXX need to deal with disabled operations.
                    mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
                            AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
                }
            } catch (RemoteException ex) {
                // Ignore
            }
        }
    }

    public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource,
            String historyTag) {
        if (DEBUG) {
            Slog.d(TAG, "onLongPartialWakeLockStart: ownerUid=" + ownerUid
                    + ", workSource=" + workSource);
        }

        try {
            if (workSource != null) {
                final int N = workSource.size();
                for (int i=0; i<N; i++) {
                    mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, workSource.get(i));
                }
            } else {
                mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, ownerUid);
            }
        } catch (RemoteException ex) {
            // Ignore
        }
    }

    public void onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource,
            String historyTag) {
        if (DEBUG) {
            Slog.d(TAG, "onLongPartialWakeLockFinish: ownerUid=" + ownerUid
                    + ", workSource=" + workSource);
        }

        try {
            if (workSource != null) {
                final int N = workSource.size();
                for (int i=0; i<N; i++) {
                    mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, workSource.get(i));
                }
            } else {
                mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, ownerUid);
            }
        } catch (RemoteException ex) {
            // Ignore
        }
    }

    /**
     * Called when a wake lock is changing.
     */
    public void onWakeLockChanging(int flags, String tag, String packageName,
            int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
            int newFlags, String newTag, String newPackageName, int newOwnerUid,
            int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {

        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
        final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
        if (workSource != null && newWorkSource != null
                && monitorType >= 0 && newMonitorType >= 0) {
            if (DEBUG) {
                Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
                        + "\", packageName=" + newPackageName
                        + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
                        + ", workSource=" + newWorkSource);
            }

            final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
                    && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
            try {
                mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
                        monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
                        newMonitorType, unimportantForLogging);
            } catch (RemoteException ex) {
                // Ignore
            }
        } else {
            onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag);
            onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
                    newWorkSource, newHistoryTag);
        }
    }

    /**
     * Called when a wake lock is released.
     */
    public void onWakeLockReleased(int flags, String tag, String packageName,
            int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
        if (DEBUG) {
            Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
                    + "\", packageName=" + packageName
                    + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
                    + ", workSource=" + workSource);
        }

        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
        if (monitorType >= 0) {
            try {
                if (workSource != null) {
                    mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
                            historyTag, monitorType);
                } else {
                    mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
                            historyTag, monitorType);
                    mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
                            AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
                }
            } catch (RemoteException ex) {
                // Ignore
            }
        }
    }

    private int getBatteryStatsWakeLockMonitorType(int flags) {
        switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
            case PowerManager.PARTIAL_WAKE_LOCK:
                return BatteryStats.WAKE_TYPE_PARTIAL;

            case PowerManager.SCREEN_DIM_WAKE_LOCK:
            case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
                return BatteryStats.WAKE_TYPE_FULL;

            case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                if (mSuspendWhenScreenOffDueToProximityConfig) {
                    return -1;
                }
                return BatteryStats.WAKE_TYPE_PARTIAL;

            case PowerManager.DRAW_WAKE_LOCK:
                return BatteryStats.WAKE_TYPE_DRAW;

            case PowerManager.DOZE_WAKE_LOCK:
                // Doze wake locks are an internal implementation detail of the
                // communication between dream manager service and power manager
                // service.  They have no additive battery impact.
                return -1;

            default:
                return -1;
        }
    }

    /**
     * Notifies that the device is changing wakefulness.
     * This function may be called even if the previous change hasn't finished in
     * which case it will assume that the state did not fully converge before the
     * next transition began and will recover accordingly.
     */
    public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
        final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
        if (DEBUG) {
            Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
                    + ", reason=" + reason + ", interactive=" + interactive);
        }

        // Tell the activity manager about changes in wakefulness, not just interactivity.
        // It needs more granularity than other components.
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mActivityManagerInternal.onWakefulnessChanged(wakefulness);
            }
        });

        // Handle any early interactive state changes.
        // Finish pending incomplete ones from a previous cycle.
        if (mInteractive != interactive) {
            // Finish up late behaviors if needed.
            if (mInteractiveChanging) {
                handleLateInteractiveChange();
            }

            // Start input as soon as we start waking up or going to sleep.
            mInputManagerInternal.setInteractive(interactive);
            mInputMethodManagerInternal.setInteractive(interactive);

            // Notify battery stats.
            try {
                mBatteryStats.noteInteractive(interactive);
            } catch (RemoteException ex) { }

            // Handle early behaviors.
            mInteractive = interactive;
            mInteractiveChangeReason = reason;
            mInteractiveChanging = true;
            handleEarlyInteractiveChange();
        }
    }

    /**
     * Notifies that the device has finished changing wakefulness.
     */
    public void onWakefulnessChangeFinished() {
        if (DEBUG) {
            Slog.d(TAG, "onWakefulnessChangeFinished");
        }

        if (mInteractiveChanging) {
            mInteractiveChanging = false;
            handleLateInteractiveChange();
        }
    }

    /**
     * Handle early interactive state changes such as getting applications or the lock
     * screen running and ready for the user to see (such as when turning on the screen).
     */
    private void handleEarlyInteractiveChange() {
        synchronized (mLock) {
            if (mInteractive) {
                // Waking up...
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
                        mPolicy.startedWakingUp();
                    }
                });

                // Send interactive broadcast.
                mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
                mPendingWakeUpBroadcast = true;
                updatePendingBroadcastLocked();
            } else {
                // Going to sleep...
                // Tell the policy that we started going to sleep.
                final int why = translateOffReason(mInteractiveChangeReason);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mPolicy.startedGoingToSleep(why);
                    }
                });
            }
        }
    }

    /**
     * Handle late interactive state changes once they are finished so that the system can
     * finish pending transitions (such as turning the screen off) before causing
     * applications to change state visibly.
     */
    private void handleLateInteractiveChange() {
        synchronized (mLock) {
            if (mInteractive) {
                // Finished waking up...
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mPolicy.finishedWakingUp();
                    }
                });
            } else {
                // Finished going to sleep...
                // This is a good time to make transitions that we don't want the user to see,
                // such as bringing the key guard to focus.  There's no guarantee for this
                // however because the user could turn the device on again at any time.
                // Some things may need to be protected by other mechanisms that defer screen on.

                // Cancel pending user activity.
                if (mUserActivityPending) {
                    mUserActivityPending = false;
                    mHandler.removeMessages(MSG_USER_ACTIVITY);
                }

                // Tell the policy we finished going to sleep.
                final int why = translateOffReason(mInteractiveChangeReason);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
                        mPolicy.finishedGoingToSleep(why);
                    }
                });

                // Send non-interactive broadcast.
                mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
                mPendingGoToSleepBroadcast = true;
                updatePendingBroadcastLocked();
            }
        }
    }

    private static int translateOffReason(int reason) {
        switch (reason) {
            case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
                return WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
            case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
                return WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
            default:
                return WindowManagerPolicy.OFF_BECAUSE_OF_USER;
        }
    }

    /**
     * Called when screen brightness boost begins or ends.
     */
    public void onScreenBrightnessBoostChanged() {
        if (DEBUG) {
            Slog.d(TAG, "onScreenBrightnessBoostChanged");
        }

        mSuspendBlocker.acquire();
        Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED);
        msg.setAsynchronous(true);
        mHandler.sendMessage(msg);
    }

    /**
     * Called when there has been user activity.
     */
    public void onUserActivity(int event, int uid) {
        if (DEBUG) {
            Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid);
        }

        try {
            mBatteryStats.noteUserActivity(uid, event);
        } catch (RemoteException ex) {
            // Ignore
        }

        synchronized (mLock) {
            if (!mUserActivityPending) {
                mUserActivityPending = true;
                Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
                msg.setAsynchronous(true);
                mHandler.sendMessage(msg);
            }
        }
    }

    /**
     * Called when the screen has turned on.
     */
    public void onWakeUp(String reason, int reasonUid, String opPackageName, int opUid) {
        if (DEBUG) {
            Slog.d(TAG, "onWakeUp: event=" + reason + ", reasonUid=" + reasonUid
                    + " opPackageName=" + opPackageName + " opUid=" + opUid);
        }

        try {
            mBatteryStats.noteWakeUp(reason, reasonUid);
            if (opPackageName != null) {
                mAppOps.noteOperation(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
            }
        } catch (RemoteException ex) {
            // Ignore
        }

    }

    /**
     * Called when wireless charging has started so as to provide user feedback.
     */
    public void onWirelessChargingStarted() {
        if (DEBUG) {
            Slog.d(TAG, "onWirelessChargingStarted");
        }

        mSuspendBlocker.acquire();
        Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED);
        msg.setAsynchronous(true);
        mHandler.sendMessage(msg);
    }

    private void updatePendingBroadcastLocked() {
        if (!mBroadcastInProgress
                && mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
                && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
                        || mPendingInteractiveState != mBroadcastedInteractiveState)) {
            mBroadcastInProgress = true;
            mSuspendBlocker.acquire();
            Message msg = mHandler.obtainMessage(MSG_BROADCAST);
            msg.setAsynchronous(true);
            mHandler.sendMessage(msg);
        }
    }

    private void finishPendingBroadcastLocked() {
        mBroadcastInProgress = false;
        mSuspendBlocker.release();
    }

    private void sendUserActivity() {
        synchronized (mLock) {
            if (!mUserActivityPending) {
                return;
            }
            mUserActivityPending = false;
        }
        if (mRetailDemoModeServiceInternal != null) {
            mRetailDemoModeServiceInternal.onUserActivity();
        }
        mPolicy.userActivity();
    }

    private void sendNextBroadcast() {
        final int powerState;
        synchronized (mLock) {
            if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
                // Broadcasted power state is unknown.  Send wake up.
                mPendingWakeUpBroadcast = false;
                mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
            } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
                // Broadcasted power state is awake.  Send asleep if needed.
                if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
                        || mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) {
                    mPendingGoToSleepBroadcast = false;
                    mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
                } else {
                    finishPendingBroadcastLocked();
                    return;
                }
            } else {
                // Broadcasted power state is asleep.  Send awake if needed.
                if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
                        || mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) {
                    mPendingWakeUpBroadcast = false;
                    mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
                } else {
                    finishPendingBroadcastLocked();
                    return;
                }
            }

            mBroadcastStartTime = SystemClock.uptimeMillis();
            powerState = mBroadcastedInteractiveState;
        }

        EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);

        if (powerState == INTERACTIVE_STATE_AWAKE) {
            sendWakeUpBroadcast();
        } else {
            sendGoToSleepBroadcast();
        }
    }

    private void sendBrightnessBoostChangedBroadcast() {
        if (DEBUG) {
            Slog.d(TAG, "Sending brightness boost changed broadcast.");
        }

        mContext.sendOrderedBroadcastAsUser(mScreenBrightnessBoostIntent, UserHandle.ALL, null,
                mScreeBrightnessBoostChangedDone, mHandler, 0, null, null);
    }

    private final BroadcastReceiver mScreeBrightnessBoostChangedDone = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            mSuspendBlocker.release();
        }
    };

    private void sendWakeUpBroadcast() {
        if (DEBUG) {
            Slog.d(TAG, "Sending wake up broadcast.");
        }

        if (ActivityManagerNative.isSystemReady()) {
            mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
                    mWakeUpBroadcastDone, mHandler, 0, null, null);
        } else {
            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
            sendNextBroadcast();
        }
    }

    private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
                    SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
            sendNextBroadcast();
        }
    };

    private void sendGoToSleepBroadcast() {
        if (DEBUG) {
            Slog.d(TAG, "Sending go to sleep broadcast.");
        }

        if (ActivityManagerNative.isSystemReady()) {
            mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null,
                    mGoToSleepBroadcastDone, mHandler, 0, null, null);
        } else {
            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1);
            sendNextBroadcast();
        }
    }

    private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
                    SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
            sendNextBroadcast();
        }
    };

    private void playWirelessChargingStartedSound() {
    //系统属性CHARGING_SOUNDS_ENABLED控制是否播放开机铃声
        boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.CHARGING_SOUNDS_ENABLED, ("true".equals(SystemProperties.get("persist.sys.start_sound", "false"))?1:0)) != 0;
        final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
                Settings.Global.WIRELESS_CHARGING_STARTED_SOUND);
        if (enabled && soundPath != null) {
            final Uri soundUri = Uri.parse("file://" + soundPath);
            if (soundUri != null) {
                final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
                if (sfx != null) {
                    sfx.setStreamType(AudioManager.STREAM_SYSTEM);
                    sfx.play();
                }
            }
        }

        mSuspendBlocker.release();
    }

    private final class NotifierHandler extends Handler {
        public NotifierHandler(Looper looper) {
            super(looper, null, true /*async*/);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_USER_ACTIVITY:
                    sendUserActivity();
                    break;

                case MSG_BROADCAST:
                    sendNextBroadcast();
                    break;

                case MSG_WIRELESS_CHARGING_STARTED:
                	//这里就是播放开机铃声的位置
                    playWirelessChargingStartedSound();
                    break;
                case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
                    sendBrightnessBoostChangedBroadcast();
                    break;
            }
        }
    }
}

目录:
\frameworks\base\services\core\java\com\android\server\power\Notifier.java

函数方法playWirelessChargingStartedSound就是播放开机铃声的位置,
只要将其中控制开机语音的属性设置成0就可以了,但是我们现在要做成可配置的,因为在做1系统固件事会遇到不同客户跟不同需求,所以我们要做成可配置的,方便后期生产固件能针对不同需求配置,
所以我加了个属性:

boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.CHARGING_SOUNDS_ENABLED, ("true".equals(SystemProperties.get("persist.sys.start_sound", "false"))?1:0)) != 0;

可以通过加上1如下配置:

PRODUCT_PROPERTY_OVERRIDES += persist.sys.start_sound=true
true:代表有铃声
false:代表没有铃声

下面我们来看看铃声文件是在哪里配置的
通过上面代码可以看出文件目录是通过这个属性来配置的:

String soundPath = Settings.Global.getString(mContext.getContentResolver(),
                Settings.Global.WIRELESS_CHARGING_STARTED_SOUND);

通过全局查找,我们可以找到的是,他是在SettingsProvider系统应用中配置的,
目录1如下:

\frameworks\base\packages\SettingsProvider\src\com\android\providers\settings

代码如下:


            loadStringSetting(stmt, Settings.Global.LOCK_SOUND,
                    R.string.def_lock_sound);
            loadStringSetting(stmt, Settings.Global.UNLOCK_SOUND,
                    R.string.def_unlock_sound);
            loadStringSetting(stmt, Settings.Global.TRUSTED_SOUND,
                    R.string.def_trusted_sound);
            loadIntegerSetting(stmt, Settings.Global.POWER_SOUNDS_ENABLED,
                    R.integer.def_power_sounds_enabled);
            loadStringSetting(stmt, Settings.Global.LOW_BATTERY_SOUND,
                    R.string.def_low_battery_sound);
            loadIntegerSetting(stmt, Settings.Global.DOCK_SOUNDS_ENABLED,
                    R.integer.def_dock_sounds_enabled);
            loadIntegerSetting(stmt, Settings.Global.DOCK_SOUNDS_ENABLED_WHEN_ACCESSIBILITY,
                    R.integer.def_dock_sounds_enabled_when_accessibility);
            loadStringSetting(stmt, Settings.Global.DESK_DOCK_SOUND,
                    R.string.def_desk_dock_sound);
            loadStringSetting(stmt, Settings.Global.DESK_UNDOCK_SOUND,
                    R.string.def_desk_undock_sound);
            loadStringSetting(stmt, Settings.Global.CAR_DOCK_SOUND,
                    R.string.def_car_dock_sound);
            loadStringSetting(stmt, Settings.Global.CAR_UNDOCK_SOUND,
                    R.string.def_car_undock_sound);
             //这里就是了
            loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND,
                    R.string.def_wireless_charging_started_sound);

            loadIntegerSetting(stmt, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED,
                    R.integer.def_dock_audio_media_enabled);

            loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0);
            loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION,
                    PackageHelper.APP_INSTALL_AUTO);

            // Set default cdma emergency tone
            loadSetting(stmt, Settings.Global.EMERGENCY_TONE, 0);

            // Set default cdma call auto retry
            loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0);

            // Set the preferred network mode to target desired value or Default
            // value defined in RILConstants
            int type;
            type = RILConstants.PREFERRED_NETWORK_MODE;
            loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);

通过以上代码可知他是资源文件里面配置的,属性是def_wireless_charging_started_sound
然后找出,看如下代码:

 <integer name="def_lockscreen_sounds_enabled">1</integer>
    <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
    <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
    <string name="def_trusted_sound" translatable="false">/system/media/audio/ui/Trusted.ogg</string>
    <string name="def_wireless_charging_started_sound" translatable="false">/system/media/audio/ui/WirelessChargingStarted.ogg</string>

    <bool name="def_lockscreen_disabled">false</bool>
    <bool name="def_device_provisioned">false</bool>
    <integer name="def_dock_audio_media_enabled">1</integer>

没错,铃声存放的目录是:
/system/media/audio/ui/WirelessChargingStarted.ogg

好了,这里介绍就到此结束了,后面还会继续更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值