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.google.android.car.kitchensink.os; 18 19 import static android.car.PlatformVersion.VERSION_CODES.TIRAMISU_1; 20 import static android.car.os.ThreadPolicyWithPriority.priorityToString; 21 import static android.car.os.ThreadPolicyWithPriority.schedToString; 22 23 import android.car.Car; 24 import android.car.os.CarPerformanceManager; 25 import android.car.os.ThreadPolicyWithPriority; 26 import android.os.Bundle; 27 import android.os.Handler; 28 import android.os.Process; 29 import android.view.LayoutInflater; 30 import android.view.View; 31 import android.view.ViewGroup; 32 import android.widget.ArrayAdapter; 33 import android.widget.Button; 34 import android.widget.EditText; 35 import android.widget.Spinner; 36 import android.widget.TextView; 37 38 import androidx.fragment.app.Fragment; 39 40 import com.android.internal.os.BackgroundThread; 41 42 import com.google.android.car.kitchensink.KitchenSinkActivity; 43 import com.google.android.car.kitchensink.R; 44 45 public final class CarPerformanceTestFragment extends Fragment { 46 private CarPerformanceManager mCarPerformanceManager; 47 private TextView mTextView; 48 private Spinner mThreadPolicySelect; 49 private EditText mThreadPriorityInput; 50 private static final String NOT_SUPPORTED_MESSAGE = 51 " is not supported on this platform, supported from TM-QPR-1 or up"; 52 53 @Override onCreate(Bundle savedInstanceState)54 public void onCreate(Bundle savedInstanceState) { 55 Runnable r = () -> 56 mCarPerformanceManager = ((KitchenSinkActivity) getActivity()) 57 .getPerformanceManager(); 58 ((KitchenSinkActivity) getActivity()).requestRefreshManager(r, 59 new Handler(getContext().getMainLooper())); 60 super.onCreate(savedInstanceState); 61 } 62 63 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance)64 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance) { 65 View v = inflater.inflate(R.layout.car_performance_test, container, 66 /* attachToRoot= */ false); 67 68 mTextView = v.findViewById(R.id.thread_priority_textview); 69 70 Button b = v.findViewById(R.id.get_thread_priority_btn); 71 b.setOnClickListener(this::getThreadPriority); 72 73 b = v.findViewById(R.id.set_thread_priority_btn); 74 b.setOnClickListener(this::setThreadPriority); 75 76 mThreadPolicySelect = v.findViewById(R.id.policy_input); 77 ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(), 78 R.array.thread_policy_list, android.R.layout.simple_spinner_item); 79 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 80 mThreadPolicySelect.setAdapter(adapter); 81 82 mThreadPriorityInput = v.findViewById(R.id.priority_input); 83 84 int pid = Process.myPid(); 85 ((TextView) v.findViewById(R.id.pid_value)).setText(Integer.toString(pid)); 86 ((TextView) v.findViewById(R.id.uid_value)).setText(Integer.toString(Process.myUid())); 87 ((TextView) v.findViewById(R.id.process_group_value)).setText(Integer.toString( 88 Process.getProcessGroup(pid))); 89 int bgThreadTid = BackgroundThread.get().getThreadId(); 90 ((TextView) v.findViewById(R.id.bg_thread_process_group_value)).setText(Integer.toString( 91 Process.getProcessGroup(bgThreadTid))); 92 93 return v; 94 } 95 getThreadPriority(View v)96 private void getThreadPriority(View v) { 97 if (!Car.getPlatformVersion().isAtLeast(TIRAMISU_1)) { 98 mTextView.setText("CarPerformanceManager.getThreadPriority" 99 + NOT_SUPPORTED_MESSAGE); 100 return; 101 } 102 103 try { 104 ThreadPolicyWithPriority p = mCarPerformanceManager.getThreadPriority(); 105 106 mTextView.setText("Current thread scheduling policy: " + schedToString(p.getPolicy()) 107 + "\nCurrent thread scheduling priority: " + priorityToString(p.getPriority())); 108 } catch (Exception e) { 109 mTextView.setText("Failed to get thread priority, error: " + e); 110 } 111 } 112 setThreadPriority(View v)113 private void setThreadPriority(View v) { 114 if (!Car.getPlatformVersion().isAtLeast(TIRAMISU_1)) { 115 mTextView.setText("CarPerformanceManager.setThreadPriority" 116 + NOT_SUPPORTED_MESSAGE); 117 return; 118 } 119 120 int policyPos = mThreadPolicySelect.getSelectedItemPosition(); 121 int policy; 122 switch (policyPos) { 123 case 1: 124 policy = ThreadPolicyWithPriority.SCHED_FIFO; 125 break; 126 case 2: 127 policy = ThreadPolicyWithPriority.SCHED_RR; 128 break; 129 default: 130 policy = ThreadPolicyWithPriority.SCHED_DEFAULT; 131 break; 132 } 133 134 int priority; 135 try { 136 priority = Integer.parseInt(mThreadPriorityInput.getText().toString()); 137 } catch (Exception e) { 138 mTextView.setText("Thread priority must be an integer"); 139 return; 140 } 141 try { 142 mCarPerformanceManager.setThreadPriority( 143 new ThreadPolicyWithPriority(policy, priority)); 144 } catch (Exception e) { 145 mTextView.setText("Failed to set thread priority, error: " + e); 146 return; 147 } 148 mTextView.setText("Setting thread priority succeeded"); 149 } 150 } 151