Android 11 boot broadcast processing timeout causes third-party application startup delay

platform

         RK3566 + Android 11

question

         During the test, it was found that the booting time of the third-party application was prolonged. After the Launcher was displayed, it still needed to wait for more than 1 minute. After checking the LOG, it was found that the following abnormal LOG ( Timeout of broadcast BroadcastRecord ) :

//第一个收到
09-13 17:45:03.406 D/WifiSleepController(  432): onReceive, action=android.intent.action.BOOT_COMPLETED

//异常LOG位置
09-13 17:46:07.077 W/BroadcastQueue(  432): Timeout of broadcast BroadcastRecord{35f0038 u0 android.intent.action.BOOT_COMPLETED} - receiver=android.os.BinderProxy@e7eb8bf, started 60000ms ago
09-13 17:46:07.077 W/BroadcastQueue(  432): Receiver during timeout of BroadcastRecord{35f0038 u0 android.intent.action.BOOT_COMPLETED} : ResolveInfo{af90b8c com.android.phone/.vvm.VvmSimStateTracker m=0x108000}

started 60000ms ago indicates that the broadcast process that started 1 minute ago timed out. At this time, the broadcast will continue to be sent. At this time, the third-party application will start to receive the startup broadcast and perform corresponding operations, such as self-starting.


Although it is not a critical position, record the LOG output position in the source code

frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java

    final void broadcastTimeoutLocked(boolean fromMsg) {
    
    
        if (fromMsg) {
    
    
            mPendingBroadcastTimeoutMessage = false;
        }

        if (mDispatcher.isEmpty() || mDispatcher.getActiveBroadcastLocked() == null) {
    
    
            return;
        }

        long now = SystemClock.uptimeMillis();
        BroadcastRecord r = mDispatcher.getActiveBroadcastLocked();
        if (fromMsg) {
    
    
            if (!mService.mProcessesReady) {
    
    
                // Only process broadcast timeouts if the system is ready; some early
                // broadcasts do heavy work setting up system facilities
                return;
            }

            // If the broadcast is generally exempt from timeout tracking, we're done
            if (r.timeoutExempt) {
    
    
                if (DEBUG_BROADCAST) {
    
    
                    Slog.i(TAG_BROADCAST, "Broadcast timeout but it's exempt: "
                            + r.intent.getAction());
                }
                return;
            }

            long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
            if (timeoutTime > now) {
    
    
                // We can observe premature timeouts because we do not cancel and reset the
                // broadcast timeout message after each receiver finishes.  Instead, we set up
                // an initial timeout then kick it down the road a little further as needed
                // when it expires.
                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
                        "Premature timeout ["
                        + mQueueName + "] @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
                        + timeoutTime);
                setBroadcastTimeoutLocked(timeoutTime);
                return;
            }
        }

        if (r.state == BroadcastRecord.WAITING_SERVICES) {
    
    
            // In this case the broadcast had already finished, but we had decided to wait
            // for started services to finish as well before going on.  So if we have actually
            // waited long enough time timeout the broadcast, let's give up on the whole thing
            // and just move on to the next.
            Slog.i(TAG, "Waited long enough for: " + (r.curComponent != null
                    ? r.curComponent.flattenToShortString() : "(null)"));
            r.curComponent = null;
            r.state = BroadcastRecord.IDLE;
            processNextBroadcast(false);
            return;
        }

        // If the receiver app is being debugged we quietly ignore unresponsiveness, just
        // tidying up and moving on to the next broadcast without crashing or ANRing this
        // app just because it's stopped at a breakpoint.
        final boolean debugging = (r.curApp != null && r.curApp.isDebugging());

        Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
                + ", started " + (now - r.receiverTime) + "ms ago");

}

track

         First of all, this problem can be seen from the Log. In the process of delivering the broadcast, it is stuck in some other process. The order of consideration is as follows:

  1. Whether time-consuming operations are processed in VvmSimStateTracker.onReceive
  2. Whether the process initialization performs time-consuming operations, the PhoneApp in the process

        1. Whether the time-consuming operation is processed in VvmSimStateTracker.onReceive

Register broadcast: packages/services/Telephony/src/com/android/phone/AndroidManifest.xml

        <receiver
            android:name="com.android.phone.vvm.VvmSimStateTracker"
            android:exported="false"
            androidprv:systemUserOnly="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.telephony.action.CARRIER_CONFIG_CHANGED"/>
                <action android:name="android.intent.action.SIM_STATE_CHANGED"/>
            </intent-filter>
        </receiver>

Broadcast processing: packages/services/Telephony/src/com/android/phone/vvm/VvmSimStateTracker.java

    public void onReceive(Context context, Intent intent) {
    
    

        final String action = intent.getAction();
        if (action == null) {
    
    
            VvmLog.w(TAG, "Null action for intent.");
            return;
        }
        VvmLog.i(TAG, action);
        switch (action) {
    
    
            case Intent.ACTION_BOOT_COMPLETED:
                onBootCompleted(context);
                break;
			//Ignore....
    }
    private void onBootCompleted(Context context) {
    
    
        for (PhoneAccountHandle phoneAccountHandle : sPreBootHandles) {
    
    
            TelephonyManager telephonyManager = getTelephonyManager(context, phoneAccountHandle);
            if (telephonyManager == null) {
    
    
                continue;
            }
            if (telephonyManager.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
    
    
                sListeners.put(phoneAccountHandle, null);
                sendConnected(context, phoneAccountHandle);
            } else {
    
    
                listenToAccount(context, phoneAccountHandle);
            }
        }
        sPreBootHandles.clear();
    }

 
 
         2. Whether the process initialization has performed time-consuming operations, the PhoneApp in the process

Application声明: packages/services/Telephony/src/com/android/phone/AndroidManifest.xml

    <application android:name="PhoneApp"
            android:persistent="true"
            android:label="@string/phoneAppLabel"
            android:icon="@mipmap/ic_launcher_phone"
            android:allowBackup="false"
            android:supportsRtl="true"
            android:usesCleartextTraffic="true"
            android:defaultToDeviceProtectedStorage="true"
            android:directBootAware="true">

Application: packages/services/Telephony/src/com/android/phone/PhoneApp.java

public class PhoneApp extends Application {
    
    
    PhoneGlobals mPhoneGlobals;

    public PhoneApp() {
    
    
    }

    @Override
    public void onCreate() {
    
    
        if (UserHandle.myUserId() == 0) {
    
    
            // We are running as the primary user, so should bring up the
            // global phone state.
            mPhoneGlobals = new PhoneGlobals(this);
            mPhoneGlobals.onCreate();

            TelecomAccountRegistry.getInstance(this).setupOnBoot();
        }
    }
}

in conclusion

After inserting the LOG into the codes of 1 and 2, it is finally determined that the problem lies in the initialization of the Application, that is to say, the process of the Phone is stuck in the onCreate function.

Why is the Phone process stuck?

Key part code:

packages/services/Telephony/src/com/android/phone/PhoneGlobals.java

    public void onCreate() {
    
    
        if (VDBG) Log.v(LOG_TAG, "onCreate()...");

        ContentResolver resolver = getContentResolver();

        // Cache the "voice capable" flag.
        // This flag currently comes from a resource (which is
        // overrideable on a per-product basis):
        sVoiceCapable = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE))
                .isVoiceCapable();
        // ...but this might eventually become a PackageManager "system
        // feature" instead, in which case we'd do something like:
        // sVoiceCapable =
        //   getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS);

        if (mCM == null) {
    
    
            // Initialize AnomalyReporter early so that it can be used
            AnomalyReporter.initialize(this);

            // Inject telephony component factory if configured using other jars.
            XmlResourceParser parser = getResources().getXml(R.xml.telephony_injection);
            TelephonyComponentFactory.getInstance().injectTheComponentFactory(parser);
            // Initialize the telephony framework
            PhoneFactory.makeDefaultPhones(this);
			//ignored...
    }

frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneFactory.java

    public static void makeDefaultPhones(Context context) {
    
    
        makeDefaultPhone(context);
    }

	    @UnsupportedAppUsage
    public static void makeDefaultPhone(Context context) {
    
    
        synchronized (sLockProxyPhones) {
    
    
            if (!sMadeDefaults) {
    
    
                sContext = context;
                // create the telephony device controller.
                TelephonyDevController.create();

                TelephonyMetrics metrics = TelephonyMetrics.getInstance();
                metrics.setContext(context);

                int retryCount = 0;
                for(;;) {
    
    
                    boolean hasException = false;
                    retryCount ++;

                    try {
    
    
                        // use UNIX domain socket to
                        // prevent subsequent initialization
                        new LocalServerSocket("com.android.internal.telephony");
                    } catch (java.io.IOException ex) {
    
    
                        hasException = true;
                    }

                    if ( !hasException ) {
    
    
                        break;
                    } else if (retryCount > SOCKET_OPEN_MAX_RETRY) {
    
    
                        throw new RuntimeException("PhoneFactory probably already running");
                    } else {
    
    
                        try {
    
    
                            Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
                        } catch (InterruptedException er) {
    
    
                        }
                    }
                }

                // register statsd pullers.
                sMetricsCollector = new MetricsCollector(context);

                sPhoneNotifier = new DefaultPhoneNotifier(context);

                int cdmaSubscription = CdmaSubscriptionSourceManager.getDefault(context);
                Rlog.i(LOG_TAG, "Cdma Subscription set to " + cdmaSubscription);

                /* In case of multi SIM mode two instances of Phone, RIL are created,
                   where as in single SIM mode only instance. isMultiSimEnabled() function checks
                   whether it is single SIM or multi SIM mode */
                int numPhones = TelephonyManager.getDefault().getActiveModemCount();

                int[] networkModes = new int[numPhones];
                sPhones = new Phone[numPhones];
                sCommandsInterfaces = new RIL[numPhones];
                sTelephonyNetworkFactories = new TelephonyNetworkFactory[numPhones];

                for (int i = 0; i < numPhones; i++) {
    
    
                    // reads the system properties and makes commandsinterface
                    // Get preferred network type.
                    networkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;

                    Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkModes[i]));
                    sCommandsInterfaces[i] = new RIL(context, networkModes[i],
                            cdmaSubscription, i);
                }

                // Ignored
    }

frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java

    @UnsupportedAppUsage
    public RIL(Context context, int preferredNetworkType,
            int cdmaSubscription, Integer instanceId) {
    
    
        super(context);
        if (RILJ_LOGD) {
    
    
            riljLog("RIL: init preferredNetworkType=" + preferredNetworkType
                    + " cdmaSubscription=" + cdmaSubscription + ")");
        }

        mContext = context;
        mCdmaSubscription  = cdmaSubscription;
        mPreferredNetworkType = preferredNetworkType;
        mPhoneType = RILConstants.NO_PHONE;
        mPhoneId = instanceId == null ? 0 : instanceId;
        if (isRadioBugDetectionEnabled()) {
    
    
            mRadioBugDetector = new RadioBugDetector(context, mPhoneId);
        }

        TelephonyManager tm = (TelephonyManager) context.getSystemService(
                Context.TELEPHONY_SERVICE);
        mIsCellularSupported = tm.isVoiceCapable() || tm.isSmsCapable() || tm.isDataCapable();

        mRadioResponse = new RadioResponse(this);
        mRadioIndication = new RadioIndication(this);
        mOemHookResponse = new OemHookResponse(this);
        mOemHookIndication = new OemHookIndication(this);
        mRilHandler = new RilHandler();
        mRadioProxyDeathRecipient = new RadioProxyDeathRecipient();

        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_WAKELOCK_TAG);
        mWakeLock.setReferenceCounted(false);
        mAckWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_ACK_WAKELOCK_NAME);
        mAckWakeLock.setReferenceCounted(false);
        mWakeLockTimeout = TelephonyProperties.wake_lock_timeout()
                .orElse(DEFAULT_WAKE_LOCK_TIMEOUT_MS);
        mAckWakeLockTimeout = TelephonyProperties.wake_lock_timeout()
                .orElse(DEFAULT_ACK_WAKE_LOCK_TIMEOUT_MS);
        mWakeLockCount = 0;
        mRILDefaultWorkSource = new WorkSource(context.getApplicationInfo().uid,
                context.getPackageName());
        mActiveWakelockWorkSource = new WorkSource();

        TelephonyDevController tdc = TelephonyDevController.getInstance();
        tdc.registerRIL(this);

        // set radio callback; needed to set RadioIndication callback (should be done after
        // wakelock stuff is initialized above as callbacks are received on separate binder threads)
        getRadioProxy(null);
        getOemHookProxy(null);

        if (RILJ_LOGD) {
    
    
            riljLog("Radio HAL version: " + mRadioVersion);
        }
    }
    /** Returns a {@link IRadio} instance or null if the service is not available. */
    @VisibleForTesting
    public synchronized IRadio getRadioProxy(Message result) {
    
    
        if (!SubscriptionManager.isValidPhoneId(mPhoneId)) return null;
        if (!mIsCellularSupported) {
    
    
            if (RILJ_LOGV) riljLog("getRadioProxy: Not calling getService(): wifi-only");
            if (result != null) {
    
    
                AsyncResult.forMessage(result, null,
                        CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
                result.sendToTarget();
            }
            return null;
        }

        if (mRadioProxy != null) {
    
    
            return mRadioProxy;
        }

        try {
    
    
            if (mDisabledRadioServices.contains(mPhoneId)) {
    
    
                riljLoge("getRadioProxy: mRadioProxy for " + HIDL_SERVICE_NAME[mPhoneId]
                        + " is disabled");
            } else {
    
    
                try {
    
    
                    mRadioProxy = android.hardware.radio.V1_5.IRadio.getService(
                            HIDL_SERVICE_NAME[mPhoneId], true);
                    mRadioVersion = RADIO_HAL_VERSION_1_5;
                } catch (NoSuchElementException e) {
    
    
                }

                if (mRadioProxy == null) {
    
    
                    try {
    
    
                        mRadioProxy = android.hardware.radio.V1_4.IRadio.getService(
                                HIDL_SERVICE_NAME[mPhoneId], true);
                        mRadioVersion = RADIO_HAL_VERSION_1_4;
                    } catch (NoSuchElementException e) {
    
    
                    }
                }

                if (mRadioProxy == null) {
    
    
                    try {
    
    
                        mRadioProxy = android.hardware.radio.V1_3.IRadio.getService(
                                HIDL_SERVICE_NAME[mPhoneId], true);
                        mRadioVersion = RADIO_HAL_VERSION_1_3;
                    } catch (NoSuchElementException e) {
    
    
                    }
                }

                if (mRadioProxy == null) {
    
    
                    try {
    
    
                        mRadioProxy = android.hardware.radio.V1_2.IRadio.getService(
                                HIDL_SERVICE_NAME[mPhoneId], true);
                        mRadioVersion = RADIO_HAL_VERSION_1_2;
                    } catch (NoSuchElementException e) {
    
    
                    }
                }

                if (mRadioProxy == null) {
    
    
                    try {
    
    
                        mRadioProxy = android.hardware.radio.V1_1.IRadio.getService(
                                HIDL_SERVICE_NAME[mPhoneId], true);
                        mRadioVersion = RADIO_HAL_VERSION_1_1;
                    } catch (NoSuchElementException e) {
    
    
                    }
                }

                if (mRadioProxy == null) {
    
    
                    try {
    
    
                        mRadioProxy = android.hardware.radio.V1_0.IRadio.getService(
                                HIDL_SERVICE_NAME[mPhoneId], true);
                        mRadioVersion = RADIO_HAL_VERSION_1_0;
                    } catch (NoSuchElementException e) {
    
    
                    }
                }

                if (mRadioProxy != null) {
    
    
                    mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
                            mRadioProxyCookie.incrementAndGet());
                    mRadioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
                } else {
    
    
                    mDisabledRadioServices.add(mPhoneId);
                    riljLoge("getRadioProxy: mRadioProxy for "
                            + HIDL_SERVICE_NAME[mPhoneId] + " is disabled");
                }
            }
        } catch (RemoteException e) {
    
    
            mRadioProxy = null;
            riljLoge("RadioProxy getService/setResponseFunctions: " + e);
        }

        if (mRadioProxy == null) {
    
    
            // getService() is a blocking call, so this should never happen
            riljLoge("getRadioProxy: mRadioProxy == null");
            if (result != null) {
    
    
                AsyncResult.forMessage(result, null,
                        CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
                result.sendToTarget();
            }
        }

        return mRadioProxy;
    }

frameworks/opt/telephony/src/java/com/android/internal/telephony/TelephonyDevController.java

    /**
     * each RIL call this interface to register/unregister the unsolicited hardware
     * configuration callback data it can provide.
     */
    public static void registerRIL(CommandsInterface cmdsIf) {
    
    
        /* get the current configuration from this ril... */
        cmdsIf.getHardwareConfig(sRilHardwareConfig);
        /* ... process it ... */
        if (sRilHardwareConfig != null) {
    
    
            AsyncResult ar = (AsyncResult) sRilHardwareConfig.obj;
            if (ar.exception == null) {
    
    
                handleGetHardwareConfigChanged(ar);
            }
        }
        /* and register for async device configuration change. */
        cmdsIf.registerForHardwareConfigChanged(sTelephonyDevController, EVENT_HARDWARE_CONFIG_CHANGED, null);
    }

    public static void unregisterRIL(CommandsInterface cmdsIf) {
    
    
        cmdsIf.unregisterForHardwareConfigChanged(sTelephonyDevController);
    }

Tracing the code to find where it finally gets stuck is when creating the RIL

PhoneApp PhoneGlobals PhoneFactory RIL TelephonyDevController onCreate makeDefaultPhones new RIL registerRIL getHardwareConfig getRadioProxy PhoneApp PhoneGlobals PhoneFactory RIL TelephonyDevController

At the same time, some LOGs related to RIL can be seen from the Log.

01:48:48.154  1880-1880  chatty       com.android.phone  I  uid=1001(radio) com.android.phone expire 4 lines
01:48:48.160   331-339   RIL RILU     pid-331            E  cannot find ttyname for AT Port
01:48:48.161   331-339   RIL RILC                        D  USB can't find at device
01:48:51.161   331-339   RIL RILU                        D  find_pci_device is 0
01:48:51.170   331-339   RIL RILU                        E  cannot find ttyname for AT Port
01:48:51.171   331-339   RIL RILC                        D  USB can't find at device
01:48:52.168  1880-1880  HidlS...ment com.android.phone  W  Waited one second for [email protected]::IRadio/slot1
01:48:53.172  1880-1880  HidlS...ment                    W  Waited one second for [email protected]::IRadio/slot1
01:48:54.172   331-339   RIL RILU     pid-331            D  find_pci_device is 0

Obviously, this cannot find 4G, so naturally the RIL initialization failed.
If the 4G module is connected, this problem will not occur


After waiting for a long time for initialization, there is also an ANR error from com.android.phone .

2022-09-16 07:18:14.975 426-1802/system_process E/ActivityManager: ANR in com.android.phone
    PID: 873
    Reason: Broadcast of Intent { act=android.intent.action.BOOT_COMPLETED flg=0x89000010 cmp=com.android.phone/.vvm.VvmSimStateTracker (has extras) }
    Load: 0.0 / 0.0 / 0.0
    ----- Output from /proc/pressure/memory -----
    some avg10=0.00 avg60=0.00 avg300=0.00 total=0
    full avg10=0.00 avg60=0.00 avg300=0.00 total=0
    ----- End output from /proc/pressure/memory -----
    
    CPU usage from 64519ms to 0ms ago (2022-09-16 07:17:10.274 to 2022-09-16 07:18:14.793):
      10% 426/system_server: 7.9% user + 2.6% kernel / faults: 15491 minor 133 major
      3.5% 579/com.android.systemui: 2.9% user + 0.5% kernel / faults: 8380 minor 1 major
      1.6% 174/surfaceflinger: 1% user + 0.6% kernel / faults: 550 minor
      1.5% 1124/com.google.android.inputmethod.pinyin: 1.2% user + 0.2% kernel / faults: 5726 minor 39 major
      1.4% 331/adbd: 0.4% user + 1% kernel / faults: 8283 minor
      1.3% 146/rknn_server: 0.1% user + 1.2% kernel
      0.5% 224/[email protected]: 0.2% user + 0.3% kernel / faults: 31 minor
      0.5% 138/logd: 0.1% user + 0.3% kernel / faults: 21 minor
      0.4% 340/installd: 0.3% user + 0.1% kernel / faults: 140 minor
      0.4% 246/zygote64: 0% user + 0.3% kernel / faults: 2679 minor
      0.3% 329/rild: 0% user + 0.3% kernel
      0.3% 7/kworker/u8:0-flush-179:0: 0% user + 0.3% kernel / faults: 1137 minor
      0.2% 50/cfinteractive: 0% user + 0.2% kernel
      0.2% 286/audioserver: 0.1% user + 0.1% kernel / faults: 125 minor
      0.2% 346/mediaserver: 0.1% user + 0.1% kernel / faults: 346 minor
      0.2% 141/hwservicemanager: 0% user + 0.1% kernel / faults: 192 minor
      0.2% 387/media.swcodec: 0.1% user + 0% kernel / faults: 136 minor
      0.2% 870/logcat: 0% user + 0.1% kernel
      0.2% 949/com.android.launcher3: 0.1% user + 0% kernel / faults: 537 minor
      0.2% 1/init: 0% user + 0.1% kernel / faults: 39 minor
      0.1% 81/kworker/0:1H-mmc_complete: 0% user + 0.1% kernel
      0.1% 111/kworker/2:2H-kblockd: 0% user + 0.1% kernel
      0.1% 262/android.hardware.audio.service: 0% user + 0.1% kernel / faults: 37 minor
      0.1% 230/kworker/u8:3-devfreq_wq: 0% user + 0.1% kernel / faults: 770 minor
      0.1% 393/irq/77-dwc3: 0% user + 0.1% kernel
      0.1% 873/com.android.phone: 0% user + 0% kernel / faults: 14 minor
      0.1% 244/statsd: 0% user + 0% kernel / faults: 6 minor
      0.1% 896/com.android.settings: 0.1% user + 0% kernel / faults: 420 minor 1 major
      0.1% 95/kworker/1:1H-kblockd: 0% user + 0.1% kernel
      0.1% 231/kworker/0:3H-mmc_complete: 0% user + 0.1% kernel
      0.1% 917/android.ext.services: 0.1% user + 0% kernel / faults: 630 minor
      0.1% 46/kworker/2:1-events_freezable: 0% user + 0.1% kernel
      0.1% 80/kworker/3:1H-kblockd: 0% user + 0.1% kernel
      0.1% 140/servicemanager: 0% user + 0% kernel
      0.1% 1102/com.android.deskclock: 0% user + 0% kernel / faults: 503 minor
      0% 229/kworker/u8:2: 0% user + 0% kernel / faults: 350 minor
      0% 425/kworker/u9:2-kbase_pm_poweroff_wait: 0% user + 0% kernel
      0% 10/rcu_preempt: 0% user + 0% kernel
      0% 139/lmkd: 0% user + 0% kernel
      0% 216/[email protected]: 0% user + 0% kernel / faults: 191 minor
      0% 481/kworker/u9:3-blk_crypto_wq: 0% user + 0% kernel
      0% 78/ion_system_heap: 0% user + 0% kernel
      0% 105/kworker/1:2H-kblockd: 0% user + 0% kernel
      0% 124/kworker/3:2-events_power_efficient: 0% user + 0% kernel
      0% 190/f2fs_discard-25: 0% user + 0% kernel
      0% 270/[email protected]: 0% user + 0% kernel
      0% 977/com.hsdz.systemcontroler:shellservice: 0% user + 0% kernel / faults: 163 minor
      0% 11/rcu_sched: 0% user + 0% kernel
      0% 14/kworker/0:1-kdmflush: 0% user + 0% kernel
      0% 45/kconsole: 0% user + 0% kernel
      0% 131/kworker/1:2-kdmflush: 0% user + 0% kernel
      0% 148/vold: 0% user + 0% kernel / faults: 87 minor
      0% 172/[email protected]: 0% user + 0% kernel
      0% 280/android.hardware.power-service.rockchip: 0% user + 0% kernel
      0% 342/media.extractor: 0% user + 0% kernel
      0% 822/com.android.se: 0% user + 0% kernel / faults: 10 minor

solve

     You can start from packages/services/Telephony and move the code in PhoneApp to Service to execute. After this change, what impact will it have? More verification is needed. At least for the current test, some 4G functions and the power-on broadcast function all normal.

Guess you like

Origin blog.csdn.net/ansondroider/article/details/126892876