Permission support for diagnostics.

This creates two permissions for access to diagnostic data:
 - DIAGNOSTIC_READ, for read-only access to live and freeze frame data;
 - DIAGNOSTIC_CLEAR, for deleting DTC data from the car.

It also extends the meaning of PERMISSION_VENDOR_EXTENSION to mean being allowed to read vendor-specific diagnostic sensor data.

Test: build
Bug: 35435164
For O-MR1.

Change-Id: I046bf6ae4a7aa2b2570ea5657bff9e1ce86edbce
diff --git a/service/src/com/android/car/CarDiagnosticService.java b/service/src/com/android/car/CarDiagnosticService.java
index cf295aa..5b4b675 100644
--- a/service/src/com/android/car/CarDiagnosticService.java
+++ b/service/src/com/android/car/CarDiagnosticService.java
@@ -18,23 +18,22 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.car.Car;
 import android.car.annotation.FutureFeature;
 import android.car.hardware.CarDiagnosticEvent;
 import android.car.hardware.CarDiagnosticManager;
 import android.car.hardware.ICarDiagnostic;
 import android.car.hardware.ICarDiagnosticEventListener;
 import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.ArrayMap;
 import android.util.Log;
+import com.android.car.internal.CarPermission;
 import com.android.car.Listeners.ClientWithRate;
 import com.android.car.hal.DiagnosticHalService;
 import com.android.internal.annotations.GuardedBy;
@@ -81,9 +80,16 @@
 
     private final Context mContext;
 
+    private final CarPermission mDiagnosticReadPermission;
+
+    private final CarPermission mDiagnosticClearPermission;
+
     public CarDiagnosticService(Context context, DiagnosticHalService diagnosticHal) {
         mContext = context;
         mDiagnosticHal = diagnosticHal;
+        mDiagnosticReadPermission = new CarPermission(mContext, Car.PERMISSION_CAR_DIAGNOSTIC_READ);
+        mDiagnosticClearPermission = new CarPermission(mContext,
+                Car.PERMISSION_CAR_DIAGNOSTIC_CLEAR);
     }
 
     @Override
@@ -217,23 +223,6 @@
         return events;
     }
 
-    private void assertPermission(int frameType) {
-        if (Binder.getCallingUid() != Process.myUid()) {
-            switch (getDiagnosticPermission(frameType)) {
-                case PackageManager.PERMISSION_GRANTED:
-                    break;
-                default:
-                    throw new SecurityException(
-                        "client does not have permission:"
-                            + getPermissionName(frameType)
-                            + " pid:"
-                            + Binder.getCallingPid()
-                            + " uid:"
-                            + Binder.getCallingUid());
-            }
-        }
-    }
-
     @Override
     public boolean registerOrUpdateDiagnosticListener(int frameType, int rate,
                 ICarDiagnosticEventListener listener) {
@@ -243,7 +232,7 @@
         Listeners<DiagnosticClient> diagnosticListeners = null;
         mDiagnosticLock.lock();
         try {
-            assertPermission(frameType);
+            mDiagnosticReadPermission.assertGranted();
             diagnosticClient = findDiagnosticClientLocked(listener);
             Listeners.ClientWithRate<DiagnosticClient> diagnosticClientWithRate = null;
             if (diagnosticClient == null) {
@@ -314,21 +303,6 @@
         return true;
     }
 
-    //TODO(egranata): handle permissions correctly
-    private int getDiagnosticPermission(int frameType) {
-        String permission = getPermissionName(frameType);
-        int result = PackageManager.PERMISSION_GRANTED;
-        if (permission != null) {
-            return mContext.checkCallingOrSelfPermission(permission);
-        }
-        // If no permission is required, return granted.
-        return result;
-    }
-
-    private String getPermissionName(int frameType) {
-        return null;
-    }
-
     private boolean startDiagnostic(int frameType, int rate) {
         Log.i(CarLog.TAG_DIAGNOSTIC, String.format("starting diagnostic %s at rate %d",
                 frameType, rate));
@@ -471,7 +445,7 @@
 
     @Override
     public boolean clearFreezeFrames(long... timestamps) {
-        //TODO(egranata): verify permissions before executing operation
+        mDiagnosticClearPermission.assertGranted();
         if (mDiagnosticHal.getDiagnosticCapabilities().isFreezeFrameClearSupported()) {
             mFreezeFrameDiagnosticRecords.lock();
             mDiagnosticHal.clearFreezeFrames(timestamps);