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