Thermal JobSchedulerService

Thermal

###手机会觉得热么?在炎热的夏天调用如下服务:

package com.xxx.xxxService

import android.app.job.JobInfo
import android.app.job.JobParameters
import android.app.job.JobScheduler
import android.app.job.JobService
import android.content.ComponentName
import android.content.Context
import android.util.Log

class SampleJobService : JobService() {
    override fun onStartJob(params: JobParameters?): Boolean {
        Log.d(TAG, "onStartJob:=============sucess============== ")
        jobFinished(params, false)
        scheduleJob(applicationContext)
        return false
    }

    override fun onStopJob(params: JobParameters?): Boolean {
        Log.d(TAG, "onStopJob: ")

        return false
    }

    companion object {
        private const val TAG = "SampleJobService"
        private const val SERVICE_JOB_ID = 123086

        fun scheduleJob(context: Context) {
            try {
                Log.d(TAG, "scheduleJob: start")
                val serviceComponent = ComponentName("com.xxx.xxxService",
                    "com.xxx.xxxService.SampleJobService")
                val builder = JobInfo.Builder(SERVICE_JOB_ID, serviceComponent)
                builder.setMinimumLatency((5 * 1000).toLong()) // wait at least
                builder.setOverrideDeadline((10 * 1000).toLong()) // maximum delay
                //setPersisted is false to avoid restriction to start foreground service from background
                builder.setPersisted(false)
                builder.setPriority(JobInfo.PRIORITY_HIGH)
                val jobScheduler = context.getSystemService(JobScheduler::class.java)
                var result = jobScheduler.schedule(builder.build())
                Log.d(TAG, "=============start==============: $result")
                Log.d(TAG, "scheduleJob: job scheduled")
            } catch (t: Exception) {
                Log.e(TAG, "sample Job schedule exception: " + t.message)
            }
        }
    }
}

发现温度低的早上可以正常运行,温度高的中午居然不运行,是天气热了手机也不行干活了:

查看JobSchedulerService看看都干了些什么

一、Thermal 2、问题发生是的log打印地方

        final JobRestriction restriction = checkIfRestricted(job);
        if (restriction != null) {
            if (DEBUG) {
                Slog.v(TAG, "areComponentsInPlaceLocked: " + job.toShortString()
                        + " restricted due to " + restriction.getInternalReason());
            }
            return false;
        }
    /**
     * Check if a job is restricted by any of the declared {@link JobRestriction JobRestrictions}.
     * Note, that the jobs with {@link JobInfo#BIAS_FOREGROUND_SERVICE} bias or higher may not
     * be restricted, thus we won't even perform the check, but simply return null early.
     *
     * @param job to be checked
     * @return the first {@link JobRestriction} restricting the given job that has been found; null
     * - if passes all the restrictions or has {@link JobInfo#BIAS_FOREGROUND_SERVICE} bias
     * or higher.
     */
    @GuardedBy("mLock")
    JobRestriction checkIfRestricted(JobStatus job) {
        if (evaluateJobBiasLocked(job) >= JobInfo.BIAS_FOREGROUND_SERVICE) {
            // Jobs with BIAS_FOREGROUND_SERVICE or higher should not be restricted
            return null;
        }
        for (int i = mJobRestrictions.size() - 1; i >= 0; i--) {
            final JobRestriction restriction = mJobRestrictions.get(i);
            if (restriction.isJobRestricted(job)) { //zsg 这里判断是否限制
                return restriction;
            }
        }
        return null;
    }

二、Thermal 3、mThermalStatus这里要是大于门槛值并且返回true,jobservice就会被限制: ThermalStatusRestriction.java

    @Override
    public boolean isJobRestricted(JobStatus job) {
        Log.i("zsg", "isJobRestricted:mThermalStatus: "+mThermalStatus,new Exception());
        if (mThermalStatus >= UPPER_THRESHOLD) {
            return true;
        }
        final int priority = job.getEffectivePriority();
        if (mThermalStatus >= HIGHER_PRIORITY_THRESHOLD) {
            // For moderate throttling, only let expedited jobs and high priority regular jobs that
            // are already running run.
            return !job.shouldTreatAsExpeditedJob()
                    && !(priority == JobInfo.PRIORITY_HIGH
                    && mService.isCurrentlyRunningLocked(job));
        }
        if (mThermalStatus >= LOW_PRIORITY_THRESHOLD) {
            // For light throttling, throttle all min priority jobs and all low priority jobs that
            // aren't already running.
            return (priority == JobInfo.PRIORITY_LOW && !mService.isCurrentlyRunningLocked(job))
                    || priority == JobInfo.PRIORITY_MIN;
        }
        return false;
    }

三、那么mThermalStatus 哪里来的呢?

    @Override
    public void onSystemServicesReady() {
        final PowerManager powerManager =
                mService.getTestableContext().getSystemService(PowerManager.class);
        // Use MainExecutor
        powerManager.addThermalStatusListener(new OnThermalStatusChangedListener() {
            @Override
            public void onThermalStatusChanged(int status) {
                // This is called on the main thread. Do not do any slow operations in it.
                // mService.onControllerStateChanged() will just post a message, which is okay.

                // There are three buckets:
                //   1. Below the lower threshold (we don't care about changes within this bucket)
                //   2. Between the lower and upper thresholds.
                //     -> We care about transitions across buckets
                //     -> We care about transitions within the middle bucket
                //   3. Upper the upper threshold (we don't care about changes within this bucket)
                final boolean significantChange =
                        // Handle transitions within and into the bucket we care about (thus
                        // causing us to change our restrictions).
                        (status >= LOWER_THRESHOLD && status <= UPPER_THRESHOLD)
                                // Take care of transitions from the 2nd or 3rd bucket to the 1st
                                // bucket (thus exiting any restrictions we started enforcing).
                                || (mThermalStatus >= LOWER_THRESHOLD && status < LOWER_THRESHOLD)
                                // Take care of transitions from the 1st or 2nd bucket to the 3rd
                                // bucket (thus resulting in us beginning to enforce the tightest
                                // restrictions).
                                || (mThermalStatus < UPPER_THRESHOLD && status > UPPER_THRESHOLD);
                mThermalStatus = status;
                if (significantChange) {
                    mService.onControllerStateChanged(null);
                }
            }
        });
    }
  • 那么看看powermanager的addThermalStatusListener :PowerManager.java
    四、Thermal 4、这里给listener传递status值,下面注册的监听mThermalService.registerThermalStatusListener
    /**
     * This function adds a listener for thermal status change.
     *
     * @param executor {@link Executor} to handle listener callback.
     * @param listener listener to be added.
     */
    public void addThermalStatusListener(@NonNull @CallbackExecutor Executor executor,
            @NonNull OnThermalStatusChangedListener listener) {
        Objects.requireNonNull(listener, "listener cannot be null");
        Objects.requireNonNull(executor, "executor cannot be null");
        Preconditions.checkArgument(!mListenerMap.containsKey(listener),
                "Listener already registered: %s", listener);
        IThermalStatusListener internalListener = new IThermalStatusListener.Stub() {
            @Override
            public void onStatusChange(int status) {
                final long token = Binder.clearCallingIdentity();
                try {
                    executor.execute(() -> listener.onThermalStatusChanged(status));
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            }
        };
        try {
            if (mThermalService.registerThermalStatusListener(internalListener)) {
                mListenerMap.put(listener, internalListener);
            } else {
                throw new RuntimeException("Listener failed to set");
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
  • 这个mThermalService就是ThermalManagerService
        @Override
        public boolean registerThermalStatusListener(IThermalStatusListener listener) {
            synchronized (mLock) {
                // Notify its callback after new client registered.
                final long token = Binder.clearCallingIdentity();
                try {
                    if (!mThermalStatusListeners.register(listener)) {
                        return false;
                    }
                    // Notify its callback after new client registered.
                    postStatusListener(listener);
                    return true;
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            }
        }

五、Thermal 5、这里给listener传递的status

    private void postStatusListener(IThermalStatusListener listener) {
        final boolean thermalCallbackQueued = FgThread.getHandler().post(() -> {
            try {
                listener.onStatusChange(mStatus);//zsg mStatus就是最后返回的值 mThermalStatus
            } catch (RemoteException | RuntimeException e) {
                Slog.e(TAG, "Thermal callback failed to call", e);
            }
        });
        if (!thermalCallbackQueued) {
            Slog.e(TAG, "Thermal callback failed to queue");
        }
    }

六、Thermal 6、这里从hal调用上来通知状态改变

    /* HwBinder callback **/
    private void onTemperatureChangedCallback(Temperature temperature) {
        final long token = Binder.clearCallingIdentity();
        try {
            onTemperatureChanged(temperature, true);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }
    private void onTemperatureChanged(Temperature temperature, boolean sendStatus) {
        shutdownIfNeeded(temperature);
        synchronized (mLock) {
            Temperature old = mTemperatureMap.put(temperature.getName(), temperature);
            if (old == null || old.getStatus() != temperature.getStatus()) {
                notifyEventListenersLocked(temperature);
            }
            if (sendStatus) {
                onTemperatureMapChangedLocked();
            }
        }
    }
   private void notifyStatusListenersLocked() {
        final int length = mThermalStatusListeners.beginBroadcast();
        try {
            for (int i = 0; i < length; i++) {
                final IThermalStatusListener listener =
                        mThermalStatusListeners.getBroadcastItem(i);
                postStatusListener(listener);//zsg Thermal 1、这里通知listener
            }
        } finally {
            mThermalStatusListeners.finishBroadcast();
        }
    }

    private void onTemperatureMapChangedLocked() {
        int newStatus = Temperature.THROTTLING_NONE;
        final int count = mTemperatureMap.size();
        for (int i = 0; i < count; i++) {
            Temperature t = mTemperatureMap.valueAt(i);
            if (t.getType() == Temperature.TYPE_SKIN && t.getStatus() >= newStatus) {
                newStatus = t.getStatus();
            }
        }
        // Do not update if override from shell
        if (!mIsStatusOverride) {
            setStatusLocked(newStatus);//zsg 这里设置的value
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux thermal是一个用于管理系统温度的子系统。它可以监测系统的温度,并根据需要调整风扇转速或者降低CPU频率等措施来控制温度。这个子系统可以通过/sys/class/thermal目录下的文件进行配置和控制。在Linux系统中,thermal子系统是非常重要的,它可以保证系统的稳定性和可靠性。 ### 回答2: Linux thermal(温度)是Linux内核中的一个子系统,用于监测和管理硬件设备的温度。在计算机系统中,温度是一个非常重要的参数,因为过高的温度可能会导致硬件故障、性能下降甚至损坏。 Linux thermal子系统通过不同的方式来获取硬件的温度信息。例如,它可以通过传感器来读取处理器、显卡、硬盘等设备的温度数据。这些传感器通常嵌入在硬件设备中,并通过总线接口(如I2C)与计算机系统连接。 一旦获取到硬件设备的温度数据,Linux thermal子系统会根据预先设置的策略来采取相应的措施。例如,它可以通过调整风扇转速来降低设备的温度。它还可以通过降低处理器频率来减少能量消耗和温度。 此外,Linux thermal子系统还提供了用户空间接口,允许用户查询和控制温度相关的信息。用户可以使用命令行工具或编写脚本来监控和调整硬件设备的温度状态。 总之,Linux thermal是Linux内核中的一个重要子系统,用于监控和管理硬件设备的温度。它通过传感器获取温度数据,并根据预先设置的策略来调整硬件设备的工作状态,以保持温度在可接受的范围内。这对于确保计算机系统的性能和可靠性非常重要。 ### 回答3: Linux thermal(Linux 热管理系统)是Linux操作系统中的一个功能,旨在监测和管理计算机硬件的温度,在温度升高时采取适当的措施来保护硬件免受损坏。 Linux thermal通过硬件传感器监测计算机中各个部件(如处理器、图形卡、内存等)的温度。传感器可以是来自硬件设备的内置传感器,也可以是外部插件设备的传感器。通过读取这些传感器的数据,Linux thermal能够实时监测温度的变化。 当温度超过设定的安全阈值时,Linux thermal会采取相应的措施来降低硬件的温度。这些措施可以包括调整风扇的转速,降低电压供应,甚至通过暂停或降低某些任务的运行来减少硬件的功耗。 在服务器和桌面计算机等大型计算设备上,Linux thermal的作用非常重要。过高的温度会导致硬件故障、损坏甚至灾难性的停机。通过及时监测温度并进行热管理,Linux系统可以保护硬件的完整性和可靠性。 除了保护硬件免受损坏外,Linux thermal还可以提高计算机的性能和能效。通过优化温度控制,可以避免出现过度降温的情况,提高硬件的工作效率并减少能源消耗。 总之,Linux thermal是Linux操作系统中用于监测和管理计算机硬件温度的功能,它通过读取传感器数据并采取适当的措施来保护硬件,提高性能和能效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值