• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.car.os;
18 
19 import android.annotation.CallbackExecutor;
20 import android.annotation.NonNull;
21 import android.annotation.RequiresPermission;
22 import android.annotation.SystemApi;
23 import android.car.Car;
24 import android.car.CarManagerBase;
25 import android.os.IBinder;
26 import android.os.Process;
27 import android.os.RemoteException;
28 import android.os.ServiceSpecificException;
29 
30 import java.util.Objects;
31 import java.util.concurrent.Executor;
32 
33 /**
34  * CarPerformanceManager allows applications to tweak performance settings for their
35  * processes/threads and listen for CPU available change notifications.
36  *
37  * @hide
38  */
39 @SystemApi
40 public final class CarPerformanceManager extends CarManagerBase {
41 
42     private final ICarPerformanceService mService;
43 
44     /**
45      * An exception type thrown when {@link setThreadPriority} failed.
46      *
47      * @hide
48      */
49     @SystemApi
50     public static final class SetSchedulerFailedException extends Exception {
SetSchedulerFailedException(Throwable cause)51         SetSchedulerFailedException(Throwable cause) {
52             super(cause);
53         }
54     }
55 
56     /** @hide */
CarPerformanceManager(Car car, IBinder service)57     public CarPerformanceManager(Car car, IBinder service) {
58         super(car);
59         mService = ICarPerformanceService.Stub.asInterface(service);
60     }
61 
62     /** @hide */
63     @Override
onCarDisconnected()64     public void onCarDisconnected() {
65         // nothing to do
66     }
67 
68     /**
69      * Listener to get CPU availability change notifications.
70      *
71      * <p>
72      * Applications implement the listener method to perform one of the following actions:
73      * <ul>
74      * <li>Execute CPU intensive tasks when the CPU availability percent is above the specified
75      * upper bound percent.
76      * <li>Stop executing CPU intensive tasks when the CPU availability percent is below
77      * the specified lower bound percent.
78      * <li>Handle the CPU availability timeout.
79      * </ul>
80      * </p>
81      *
82      * @hide
83      * @removed API not used since Android U. Must be removed in Android W (release 35).
84      */
85     public interface CpuAvailabilityChangeListener {
86         /**
87          * Called on one of the following events:
88          * 1. When the CPU availability percent has reached or decreased below the lower bound
89          *    percent specified at {@link CpuAvailabilityMonitoringConfig#getLowerBoundPercent()}.
90          * 2. When the CPU availability percent has reached or increased above the upper bound
91          *    percent specified at {@link CpuAvailabilityMonitoringConfig#getUpperBoundPercent()}.
92          * 3. When the CPU availability monitoring has reached the timeout specified at
93          *    {@link CpuAvailabilityMonitoringConfig#getTimeoutInSeconds()}.
94          *
95          * <p>The listener is called at the executor which is specified in
96          * {@link CarPerformanceManager#addCpuAvailabilityChangeListener(Executor,
97          * CpuAvailabilityMonitoringConfig, CpuAvailabilityChangeListener)}.
98          *
99          * @param info CPU availability information.
100          */
onCpuAvailabilityChange(@onNull CpuAvailabilityInfo info)101         void onCpuAvailabilityChange(@NonNull CpuAvailabilityInfo info);
102     }
103 
104     /**
105      * Adds the {@link CpuAvailabilityChangeListener} for the calling package.
106      *
107      * @param config CPU availability monitoring config.
108      * @param listener Listener implementing {@link CpuAvailabilityChangeListener}
109      * interface.
110      *
111      * @throws IllegalStateException if {@code listener} is already added.
112      *
113      * @hide
114      * @removed API not used since Android U. Must be removed in Android W (release 35).
115      */
116     @RequiresPermission(Car.PERMISSION_COLLECT_CAR_CPU_INFO)
addCpuAvailabilityChangeListener( @onNull @allbackExecutor Executor executor, @NonNull CpuAvailabilityMonitoringConfig config, @NonNull CpuAvailabilityChangeListener listener)117     public void addCpuAvailabilityChangeListener(
118             @NonNull @CallbackExecutor Executor executor,
119             @NonNull CpuAvailabilityMonitoringConfig config,
120             @NonNull CpuAvailabilityChangeListener listener) {
121         Objects.requireNonNull(executor, "Executor must be non-null");
122         Objects.requireNonNull(config, "Config must be non-null");
123         Objects.requireNonNull(listener, "Listener must be non-null");
124 
125         // TODO(b/217422127): Implement the API.
126         throw new UnsupportedOperationException("Not yet implemented");
127     }
128 
129     /**
130      * Removes the {@link CpuAvailabilityChangeListener} for the calling package.
131      *
132      * @param listener Listener implementing {@link CpuAvailabilityChangeListener}
133      * interface.
134      *
135      * @hide
136      * @removed API not used since Android U. Must be removed in Android W (release 35).
137      */
138     @RequiresPermission(Car.PERMISSION_COLLECT_CAR_CPU_INFO)
removeCpuAvailabilityChangeListener( @onNull @allbackExecutor Executor executor, @NonNull CpuAvailabilityChangeListener listener)139     public void removeCpuAvailabilityChangeListener(
140             @NonNull @CallbackExecutor Executor executor,
141             @NonNull CpuAvailabilityChangeListener listener) {
142         Objects.requireNonNull(executor, "Executor must be non-null");
143         Objects.requireNonNull(listener, "Listener must be non-null");
144 
145         // TODO(b/217422127): Implement the API.
146         throw new UnsupportedOperationException("Not yet implemented");
147     }
148 
149     /**
150      * Sets the thread scheduling policy with priority for the current thread.
151      *
152      * For {@link ThreadPolicyWithPriority#SCHED_DEFAULT} scheduling algorithm, the standard
153      * round-robin time-sharing algorithm will be used and the priority field will be ignored.
154      * Please use {@link Process#setThreadPriority} to adjust the priority for the default
155      * scheduling.
156      *
157      * @param policyWithPriority A thread scheduling policy with priority.
158      * @throws IllegalArgumentException If the policy is not supported or the priority is not within
159      *         {@link ThreadPolicyWithPriority#PRIORITY_MIN} and
160      *         {@link ThreadPolicyWithPriority#PRIORITY_MAX}.
161      * @throws SetSchedulerFailedException If failed to set the scheduling policy and priority.
162      * @throws SecurityException If permission check failed.
163      *
164      * @hide
165      */
166     @SystemApi
167     @RequiresPermission(Car.PERMISSION_MANAGE_THREAD_PRIORITY)
setThreadPriority(@onNull ThreadPolicyWithPriority policyWithPriority)168     public void setThreadPriority(@NonNull ThreadPolicyWithPriority policyWithPriority)
169             throws SetSchedulerFailedException {
170         int tid = Process.myTid();
171         try {
172             mService.setThreadPriority(tid, policyWithPriority);
173         } catch (ServiceSpecificException e) {
174             throw new SetSchedulerFailedException(e);
175         } catch (RemoteException e) {
176             handleRemoteExceptionFromCarService(e);
177         }
178     }
179 
180     /**
181      * Gets the thread scheduling policy with priority for the current thread.
182      *
183      * For {@link ThreadPolicyWithPriority#SCHED_FIFO} or
184      * {@link ThreadPolicyWithPriority#SCHED_RR}, this function returns the priority for the
185      * scheduling algorithm. For {@link ThreadPolicyWithPriority#SCHED_DEFAULT} which is the
186      * standard round-robin time-sharing algorithm, this function always return 0 for priority. The
187      * priority for the default algorithm can be fetched by {@link Process#getThreadPriority}.
188      *
189      * @throws IllegalStateException If failed to get policy or priority.
190      * @throws SecurityException If permission check failed.
191      *
192      * @hide
193      */
194     @SystemApi
195     @RequiresPermission(Car.PERMISSION_MANAGE_THREAD_PRIORITY)
getThreadPriority()196     public @NonNull ThreadPolicyWithPriority getThreadPriority() {
197         int tid = Process.myTid();
198         try {
199             return mService.getThreadPriority(tid);
200         } catch (RemoteException e) {
201             handleRemoteExceptionFromCarService(e);
202             // Car service has crashed, return a default value since we do not
203             // want to crash the client.
204             return new ThreadPolicyWithPriority(
205                     ThreadPolicyWithPriority.SCHED_DEFAULT, /* priority= */ 0);
206         }
207     }
208 }
209