Home | History | Annotate | Download | only in car
      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 */
     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      */
     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      */
     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     }
    143 
    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     }
    161 }
    162