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 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 */
     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      */
     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      */
     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      */
     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      */
     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      */
    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 
    118         public SyncRunnable(Runnable target) {
    119             mTarget = target;
    120         }
    121 
    122         @Override
    123         public void run() {
    124             mTarget.run();
    125             synchronized (this) {
    126                 mComplete = true;
    127                 notifyAll();
    128             }
    129         }
    130 
    131         public void waitForComplete() {
    132             synchronized (this) {
    133                 while (!mComplete) {
    134                     try {
    135                         wait();
    136                     } catch (InterruptedException e) {
    137                     }
    138                 }
    139             }
    140         }
    141     }
    142 
    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 
    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 
    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