blob: b47e22c81bbac3b09776b63a4157038d8176cd01 [file] [log] [blame]
keunyoungca515072015-07-10 12:21:47 -07001/*
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
17package com.android.car;
18
Keun-young Park71b2f5c2016-03-10 18:44:40 -080019import java.util.List;
20
Keun-young Park4aeb4bf2015-12-08 18:31:33 -080021import android.content.Context;
22import android.content.pm.ApplicationInfo;
23import android.content.pm.PackageManager;
24import android.content.pm.PackageManager.NameNotFoundException;
25import android.os.Binder;
Keun-young Park43cfff22016-02-19 12:49:52 -080026import android.os.Handler;
27import android.os.Looper;
Keun-young Park4aeb4bf2015-12-08 18:31:33 -080028import android.util.Log;
29
keunyoungca515072015-07-10 12:21:47 -070030/** Utility class */
Keun-young Park43cfff22016-02-19 12:49:52 -080031public final class CarServiceUtils {
keunyoungca515072015-07-10 12:21:47 -070032
Keun-young Park4aeb4bf2015-12-08 18:31:33 -080033 private static final String PACKAGE_NOT_FOUND = "Package not found:";
34
Keun-young Park43cfff22016-02-19 12:49:52 -080035 /** do not construct. static only */
36 private CarServiceUtils() {};
37
Keun-young Park4aeb4bf2015-12-08 18:31:33 -080038 /**
39 * Check if package name passed belongs to UID for the current binder call.
40 * @param context
41 * @param packageName
42 */
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 }
Keun-young Park43cfff22016-02-19 12:49:52 -080066
67 /**
68 * Execute a runnable on the main thread
69 *
70 * @param action The code to run on the main thread.
71 */
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 */
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 */
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 */
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
119 public SyncRunnable(Runnable target) {
120 mTarget = target;
121 }
122
123 @Override
124 public void run() {
125 mTarget.run();
126 synchronized (this) {
127 mComplete = true;
128 notifyAll();
129 }
130 }
131
132 public void waitForComplete() {
133 synchronized (this) {
134 while (!mComplete) {
135 try {
136 wait();
137 } catch (InterruptedException e) {
138 }
139 }
140 }
141 }
142 }
Keun-young Park71b2f5c2016-03-10 18:44:40 -0800143
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
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 }
keunyoungca515072015-07-10 12:21:47 -0700161}