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 com.android.car.os; 18 19 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO; 20 21 import android.car.Car; 22 import android.car.builtin.util.Slogf; 23 import android.car.os.ICarPerformanceService; 24 import android.car.os.ThreadPolicyWithPriority; 25 import android.content.Context; 26 import android.os.Binder; 27 import android.os.RemoteException; 28 import android.util.Log; 29 import android.util.proto.ProtoOutputStream; 30 31 import com.android.car.CarLocalServices; 32 import com.android.car.CarLog; 33 import com.android.car.CarServiceBase; 34 import com.android.car.CarServiceUtils; 35 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 36 import com.android.car.internal.util.IndentingPrintWriter; 37 import com.android.car.watchdog.CarWatchdogService; 38 39 /** 40 * Service to implement CarPerformanceManager API. 41 */ 42 public final class CarPerformanceService extends ICarPerformanceService.Stub 43 implements CarServiceBase { 44 static final String TAG = CarLog.tagFor(CarPerformanceService.class); 45 46 private static final boolean DEBUG = Slogf.isLoggable(TAG, Log.DEBUG); 47 48 private CarWatchdogService mCarWatchdogService; 49 private final Context mContext; 50 CarPerformanceService(Context context)51 public CarPerformanceService(Context context) { 52 mContext = context; 53 } 54 55 @Override init()56 public void init() { 57 mCarWatchdogService = CarLocalServices.getService(CarWatchdogService.class); 58 if (DEBUG) { 59 Slogf.d(TAG, "CarPerformanceService is initialized"); 60 } 61 } 62 63 @Override release()64 public void release() {} 65 66 @Override 67 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) dump(IndentingPrintWriter writer)68 public void dump(IndentingPrintWriter writer) { 69 writer.printf("*%s*\n", getClass().getSimpleName()); 70 writer.increaseIndent(); 71 writer.printf("DEBUG=%s", DEBUG); 72 writer.decreaseIndent(); 73 } 74 75 @Override 76 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) dumpProto(ProtoOutputStream proto)77 public void dumpProto(ProtoOutputStream proto) {} 78 79 /** 80 * Sets the thread priority for a specific thread. 81 * 82 * The thread must belong to the calling process. 83 * 84 * @throws IllegalArgumentException If the given policy/priority is not valid. 85 * @throws IllegalStateException If the provided tid does not belong to the calling process. 86 * @throws RemoteException If binder error happens. 87 * @throws SecurityException If permission check failed. 88 * @throws ServiceSpecificException If the operation failed. 89 * @throws UnsupportedOperationException If the current android release doesn't support the API. 90 */ 91 @Override setThreadPriority(int tid, ThreadPolicyWithPriority threadPolicyWithPriority)92 public void setThreadPriority(int tid, ThreadPolicyWithPriority threadPolicyWithPriority) 93 throws RemoteException { 94 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_MANAGE_THREAD_PRIORITY); 95 96 int pid = Binder.getCallingPid(); 97 int uid = Binder.getCallingUid(); 98 mCarWatchdogService.setThreadPriority(pid, tid, uid, threadPolicyWithPriority.getPolicy(), 99 threadPolicyWithPriority.getPriority()); 100 } 101 102 /** 103 * Gets the thread scheduling policy and priority for the specified thread. 104 * 105 * The thread must belong to the calling process. 106 * 107 * @throws IllegalStateException If the operation failed or the provided tid does not belong to 108 * the calling process. 109 * @throws RemoteException If binder error happens. 110 * @throws SecurityException If permission check failed. 111 * @throws UnsupportedOperationException If the current android release doesn't support the API. 112 */ 113 @Override getThreadPriority(int tid)114 public ThreadPolicyWithPriority getThreadPriority(int tid) throws RemoteException { 115 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_MANAGE_THREAD_PRIORITY); 116 117 int pid = Binder.getCallingPid(); 118 int uid = Binder.getCallingUid(); 119 try { 120 int[] result = mCarWatchdogService.getThreadPriority(pid, tid, uid); 121 return new ThreadPolicyWithPriority(result[0], result[1]); 122 } catch (IllegalArgumentException e) { 123 throw new IllegalStateException( 124 "current scheduling policy doesn't support getting priority, cause: " 125 + e.getCause(), e); 126 } 127 } 128 } 129