1ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung/* 2ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Copyright (C) 2015 The Android Open Source Project 3ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * 4ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Licensed under the Apache License, Version 2.0 (the "License"); 5ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * you may not use this file except in compliance with the License. 6ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * You may obtain a copy of the License at 7ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * 8ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * http://www.apache.org/licenses/LICENSE-2.0 9ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * 10ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Unless required by applicable law or agreed to in writing, software 11ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * distributed under the License is distributed on an "AS IS" BASIS, 12ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * See the License for the specific language governing permissions and 14ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * limitations under the License. 15ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 16ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 17ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungpackage com.android.car; 18ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 194aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Parkimport android.content.Context; 204aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Parkimport android.content.pm.ApplicationInfo; 214aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Parkimport android.content.pm.PackageManager.NameNotFoundException; 224aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Parkimport android.os.Binder; 2343cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Parkimport android.os.Handler; 2443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Parkimport android.os.Looper; 254aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Parkimport android.util.Log; 264aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park 270d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsevimport java.util.List; 280d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev 29ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung/** Utility class */ 3043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Parkpublic final class CarServiceUtils { 31ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 324aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park private static final String PACKAGE_NOT_FOUND = "Package not found:"; 334aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park 3443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park /** do not construct. static only */ 3543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park private CarServiceUtils() {}; 3643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 374aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park /** 384aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park * Check if package name passed belongs to UID for the current binder call. 394aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park * @param context 404aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park * @param packageName 414aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park */ 423da3c6150b395fb0ae0ae83873086a4a34cc8b33Enrico Granata public static void assertPackageName(Context context, String packageName) 434aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park throws IllegalArgumentException, SecurityException { 444aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park if (packageName == null) { 454aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park throw new IllegalArgumentException("Package name null"); 464aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park } 474aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park ApplicationInfo appInfo = null; 484aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park try { 494aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park appInfo = context.getPackageManager().getApplicationInfo(packageName, 504aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park 0); 514aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park } catch (NameNotFoundException e) { 524aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park String msg = PACKAGE_NOT_FOUND + packageName; 534aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park Log.w(CarLog.TAG_SERVICE, msg, e); 544aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park throw new SecurityException(msg, e); 554aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park } 564aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park if (appInfo == null) { 574aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park throw new SecurityException(PACKAGE_NOT_FOUND + packageName); 584aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park } 594aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park int uid = Binder.getCallingUid(); 604aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park if (uid != appInfo.uid) { 614aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park throw new SecurityException("Wrong package name:" + packageName + 624aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park ", The package does not belong to caller's uid:" + uid); 634aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park } 644aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park } 6543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 6643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park /** 6743cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * Execute a runnable on the main thread 6843cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * 6943cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * @param action The code to run on the main thread. 7043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park */ 7143cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park public static void runOnMain(Runnable action) { 7243cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park runOnLooper(Looper.getMainLooper(), action); 7343cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 7443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 7543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park /** 7643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * Execute a runnable in the given looper 7743cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * @param looper Looper to run the action. 7843cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * @param action The code to run. 7943cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park */ 8043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park public static void runOnLooper(Looper looper, Runnable action) { 8143cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park new Handler(looper).post(action); 8243cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 8343cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 8443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park /** 8543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * Execute a call on the application's main thread, blocking until it is 8643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * complete. Useful for doing things that are not thread-safe, such as 8743cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * looking at or modifying the view hierarchy. 8843cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * 8943cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * @param action The code to run on the main thread. 9043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park */ 9143cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park public static void runOnMainSync(Runnable action) { 9243cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park runOnLooperSync(Looper.getMainLooper(), action); 9343cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 9443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 9543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park /** 9643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * Execute a call on the given Looper thread, blocking until it is 9743cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * complete. 9843cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * 9943cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * @param looper Looper to run the action. 10043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park * @param action The code to run on the main thread. 10143cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park */ 10243cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park public static void runOnLooperSync(Looper looper, Runnable action) { 10343cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park if (Looper.myLooper() == looper) { 10443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park // requested thread is the same as the current thread. call directly. 10543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park action.run(); 10643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } else { 10743cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park Handler handler = new Handler(looper); 10843cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park SyncRunnable sr = new SyncRunnable(action); 10943cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park handler.post(sr); 11043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park sr.waitForComplete(); 11143cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 11243cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 11343cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 11443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park private static final class SyncRunnable implements Runnable { 11543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park private final Runnable mTarget; 11643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park private volatile boolean mComplete = false; 11743cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 11843cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park public SyncRunnable(Runnable target) { 11943cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park mTarget = target; 12043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 12143cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 12243cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park @Override 12343cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park public void run() { 12443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park mTarget.run(); 12543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park synchronized (this) { 12643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park mComplete = true; 12743cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park notifyAll(); 12843cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 12943cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 13043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park 13143cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park public void waitForComplete() { 13243cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park synchronized (this) { 13343cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park while (!mComplete) { 13443cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park try { 13543cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park wait(); 13643cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } catch (InterruptedException e) { 13743cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 13843cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 13943cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 14043cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 14143cfff21932b23f0e382aa78ffc1bb053928b1c5Keun-young Park } 14271b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park 14371b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park public static float[] toFloatArray(List<Float> list) { 14471b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park final int size = list.size(); 14571b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park final float[] array = new float[size]; 14671b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park for (int i = 0; i < size; ++i) { 14771b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park array[i] = list.get(i); 14871b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park } 14971b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park return array; 15071b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park } 15171b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park 15271b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park public static int[] toIntArray(List<Integer> list) { 15371b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park final int size = list.size(); 15471b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park final int[] array = new int[size]; 15571b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park for (int i = 0; i < size; ++i) { 15671b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park array[i] = list.get(i); 15771b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park } 15871b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park return array; 15971b2f5cd736f3a9aac8a9356b049d20ea76edb88Keun-young Park } 1600d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev 1610d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev public static byte[] toByteArray(List<Byte> list) { 1620d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev final int size = list.size(); 1630d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev final byte[] array = new byte[size]; 1640d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev for (int i = 0; i < size; ++i) { 1650d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev array[i] = list.get(i); 1660d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev } 1670d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev return array; 1680d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev } 169ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung} 170