1901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv/* 2901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * Copyright (C) 2016 The Android Open Source Project 3901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * 4901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * Licensed under the Apache License, Version 2.0 (the "License"); 5901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * you may not use this file except in compliance with the License. 6901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * You may obtain a copy of the License at 7901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * 8901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * http://www.apache.org/licenses/LICENSE-2.0 9901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * 10901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * Unless required by applicable law or agreed to in writing, software 11901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * distributed under the License is distributed on an "AS IS" BASIS, 12901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * See the License for the specific language governing permissions and 14901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * limitations under the License. 15901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv */ 16901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivpackage com.android.car.vehiclemonitor; 17901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 18901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport android.annotation.IntDef; 19901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport android.os.Handler; 20901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport android.os.Looper; 21901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport android.os.Message; 22901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport android.os.RemoteException; 23901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport android.os.ServiceManager; 24901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport android.os.ServiceSpecificException; 25901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 26901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport java.lang.annotation.Retention; 27901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport java.lang.annotation.RetentionPolicy; 28901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivimport java.lang.ref.WeakReference; 29901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 30901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv/** 31901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * System API to access Vehicle monitor. This is only for system services and applications should 32901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * not use this. All APIs will fail with security error if normal app tries this. 33901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv */ 34901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkivpublic class VehicleMonitor { 35901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private static final String TAG = VehicleMonitor.class.getSimpleName(); 36901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 37901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private final IVehicleMonitor mService; 38901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private final VehicleMonitorListener mListener; 39901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private final IVehicleMonitorListenerImpl mVehicleMonitorListener; 40901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private final EventHandler mEventHandler; 41901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 42901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private static final int VMS_CONNECT_MAX_RETRY = 10; 43901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private static final long VMS_RETRY_WAIT_TIME_MS = 1000; 44901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 45901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv /** 46901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * Application priorities used in vehicle monitoring. 47901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv */ 48901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv @Retention(RetentionPolicy.SOURCE) 49901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv @IntDef({ 50901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv ApplicationPriority.NONE, 51901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv ApplicationPriority.FOREGROUND 52901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv }) 53901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public @interface ApplicationPriority { 54901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv int NONE = 0; 55901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv int FOREGROUND = 1; 56901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 57901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 58901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv /** 59901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * Listener for VMS events. 60901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv */ 61901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public interface VehicleMonitorListener { 62901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv void onAppViolation(int pid, int uid, int action, int violation); 63901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 64901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 65901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv /** 66901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * Factory method to create VehicleMonitor 67901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv */ 68901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public static VehicleMonitor createVehicleMonitor( 69901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv VehicleMonitorListener listener, Looper looper) { 70901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv int retryCount = 0; 71901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv IVehicleMonitor service = null; 72901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv while (true) { 73901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv service = IVehicleMonitor.Stub.asInterface( 74901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv ServiceManager.getService(IVehicleMonitor.class.getCanonicalName())); 75901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv if (service != null) { 76901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv break; 77901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 78901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv retryCount++; 79901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv if (retryCount > VMS_CONNECT_MAX_RETRY) { 80901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv break; 81901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 82901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv try { 83901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv Thread.sleep(VMS_RETRY_WAIT_TIME_MS); 84901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } catch (InterruptedException e) { 85901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv //ignore 86901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 87901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 88901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv if (service == null) { 89901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv throw new RuntimeException("Vehicle monitor service not available:" 90901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv + IVehicleMonitor.class.getCanonicalName()); 91901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 92901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv return new VehicleMonitor(service, listener, looper); 93901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 94901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 95901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private VehicleMonitor( 96901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv IVehicleMonitor service, VehicleMonitorListener listener, Looper looper) { 97901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mService = service; 98901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mListener = listener; 99901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mEventHandler = new EventHandler(looper); 100901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mVehicleMonitorListener = new IVehicleMonitorListenerImpl(this); 101901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv try { 102901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mService.setMonitorListener(mVehicleMonitorListener); 103901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } catch (RemoteException e) { 104901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv throw new RuntimeException("Vehicle monitor service not working ", e); 105901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 106901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 107901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 108901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv /** 109901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * Set application priority. 110901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * <p> 111901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv * This will lead into writing application priority into vehicle monitor. 112901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv */ 113901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public void setAppPriority(int pid, int uid, @ApplicationPriority int priority) 114901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv throws ServiceSpecificException { 115901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv try { 116901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mService.setAppPriority(pid, uid, priority); 117901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } catch (RemoteException e) { 118901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv throw new RuntimeException("Vehicle monitor service not working ", e); 119901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 120901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 121901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 122901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private void handleVehicleMonitorAppViolation(AppViolation appViolation) { 123901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mListener.onAppViolation(appViolation.mPid, appViolation.mUid, appViolation.mAction, 124901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv appViolation.mViolation); 125901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 126901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 127901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private class EventHandler extends Handler { 128901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 129901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private static final int MSG_APP_VIOLATION = 0; 130901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 131901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private EventHandler(Looper looper) { 132901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv super(looper); 133901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 134901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 135901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private void notifyAppViolation(int pid, int uid, int action, int violation) { 136901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv AppViolation appViolation = new AppViolation(pid, uid, action, violation); 137901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv Message msg = obtainMessage(MSG_APP_VIOLATION, appViolation); 138901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv sendMessage(msg); 139901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 140901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 141901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv @Override 142901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public void handleMessage(Message msg) { 143901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv switch (msg.what) { 144901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv case MSG_APP_VIOLATION: 145901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv AppViolation appViolation = (AppViolation) msg.obj; 146901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv handleVehicleMonitorAppViolation(appViolation); 147901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv break; 148901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 149901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 150901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 151901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 152901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private static class IVehicleMonitorListenerImpl extends IVehicleMonitorListener.Stub { 153901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 154901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private final WeakReference<VehicleMonitor> mVehicleMonitor; 155901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 156901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private IVehicleMonitorListenerImpl(VehicleMonitor vehicleNewotk) { 157901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mVehicleMonitor = new WeakReference<>(vehicleNewotk); 158901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 159901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 160901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv @Override 161901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public void onAppViolation(int pid, int uid, int action, int violation) { 162901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv VehicleMonitor vehicleMonitor = mVehicleMonitor.get(); 163901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv if (vehicleMonitor != null) { 164901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv vehicleMonitor.mEventHandler.notifyAppViolation(pid, uid, action, violation); 165901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 166901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 167901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 168901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 169901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv private static class AppViolation { 170901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public final int mPid; 171901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public final int mUid; 172901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public final int mAction; 173901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv public final int mViolation; 174901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv 175901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv AppViolation(int pid, int uid, int action, int violation) { 176901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mPid = pid; 177901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mUid = uid; 178901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mAction = action; 179901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv mViolation = violation; 180901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 181901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv } 182901c024b7d764a1e1556e99ffcd3da8522c8a0b8Vitalii Tomkiv} 183