1 /* 2 * Copyright (C) 2015 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; 18 19 import java.util.List; 20 21 import android.content.Context; 22 import android.content.pm.ApplicationInfo; 23 import android.content.pm.PackageManager; 24 import android.content.pm.PackageManager.NameNotFoundException; 25 import android.os.Binder; 26 import android.os.Handler; 27 import android.os.Looper; 28 import android.util.Log; 29 30 /** Utility class */ 31 public final class CarServiceUtils { 32 33 private static final String PACKAGE_NOT_FOUND = "Package not found:"; 34 35 /** do not construct. static only */ CarServiceUtils()36 private CarServiceUtils() {}; 37 38 /** 39 * Check if package name passed belongs to UID for the current binder call. 40 * @param context 41 * @param packageName 42 */ assertPakcageName(Context context, String packageName)43 public static void assertPakcageName(Context context, String packageName) 44 throws IllegalArgumentException, SecurityException { 45 if (packageName == null) { 46 throw new IllegalArgumentException("Package name null"); 47 } 48 ApplicationInfo appInfo = null; 49 try { 50 appInfo = context.getPackageManager().getApplicationInfo(packageName, 51 0); 52 } catch (NameNotFoundException e) { 53 String msg = PACKAGE_NOT_FOUND + packageName; 54 Log.w(CarLog.TAG_SERVICE, msg, e); 55 throw new SecurityException(msg, e); 56 } 57 if (appInfo == null) { 58 throw new SecurityException(PACKAGE_NOT_FOUND + packageName); 59 } 60 int uid = Binder.getCallingUid(); 61 if (uid != appInfo.uid) { 62 throw new SecurityException("Wrong package name:" + packageName + 63 ", The package does not belong to caller's uid:" + uid); 64 } 65 } 66 67 /** 68 * Execute a runnable on the main thread 69 * 70 * @param action The code to run on the main thread. 71 */ runOnMain(Runnable action)72 public static void runOnMain(Runnable action) { 73 runOnLooper(Looper.getMainLooper(), action); 74 } 75 76 /** 77 * Execute a runnable in the given looper 78 * @param looper Looper to run the action. 79 * @param action The code to run. 80 */ runOnLooper(Looper looper, Runnable action)81 public static void runOnLooper(Looper looper, Runnable action) { 82 new Handler(looper).post(action); 83 } 84 85 /** 86 * Execute a call on the application's main thread, blocking until it is 87 * complete. Useful for doing things that are not thread-safe, such as 88 * looking at or modifying the view hierarchy. 89 * 90 * @param action The code to run on the main thread. 91 */ runOnMainSync(Runnable action)92 public static void runOnMainSync(Runnable action) { 93 runOnLooperSync(Looper.getMainLooper(), action); 94 } 95 96 /** 97 * Execute a call on the given Looper thread, blocking until it is 98 * complete. 99 * 100 * @param looper Looper to run the action. 101 * @param action The code to run on the main thread. 102 */ runOnLooperSync(Looper looper, Runnable action)103 public static void runOnLooperSync(Looper looper, Runnable action) { 104 if (Looper.myLooper() == looper) { 105 // requested thread is the same as the current thread. call directly. 106 action.run(); 107 } else { 108 Handler handler = new Handler(looper); 109 SyncRunnable sr = new SyncRunnable(action); 110 handler.post(sr); 111 sr.waitForComplete(); 112 } 113 } 114 115 private static final class SyncRunnable implements Runnable { 116 private final Runnable mTarget; 117 private volatile boolean mComplete = false; 118 SyncRunnable(Runnable target)119 public SyncRunnable(Runnable target) { 120 mTarget = target; 121 } 122 123 @Override run()124 public void run() { 125 mTarget.run(); 126 synchronized (this) { 127 mComplete = true; 128 notifyAll(); 129 } 130 } 131 waitForComplete()132 public void waitForComplete() { 133 synchronized (this) { 134 while (!mComplete) { 135 try { 136 wait(); 137 } catch (InterruptedException e) { 138 } 139 } 140 } 141 } 142 } 143 toFloatArray(List<Float> list)144 public static float[] toFloatArray(List<Float> list) { 145 final int size = list.size(); 146 final float[] array = new float[size]; 147 for (int i = 0; i < size; ++i) { 148 array[i] = list.get(i); 149 } 150 return array; 151 } 152 toIntArray(List<Integer> list)153 public static int[] toIntArray(List<Integer> list) { 154 final int size = list.size(); 155 final int[] array = new int[size]; 156 for (int i = 0; i < size; ++i) { 157 array[i] = list.get(i); 158 } 159 return array; 160 } 161 } 162