Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e8f78b3 authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi
Browse files

Improve exception handling in SoundTrigger

This unified the exception handling of SoundTrigger and
SoundTriggerModule and adds support for some ServiceSepcificExceptions
that may occur.

Change-Id: I018c7b249058758f0f3b5af34ee06a2396ecb6a7
Bug: 147435580
parent 73548810
Loading
Loading
Loading
Loading
+43 −3
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.content.Context;
import android.media.AudioFormat;
import android.media.soundtrigger_middleware.ISoundTriggerMiddlewareService;
import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor;
import android.media.soundtrigger_middleware.Status;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -41,6 +42,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.util.Log;

import java.lang.annotation.Retention;
@@ -1675,6 +1677,45 @@ public class SoundTrigger {
        return packageName;
    }

    /**
     * Translate an exception thrown from interaction with the underlying service to an error code.
     * Throws a runtime exception for unexpected conditions.
     * @param e The caught exception.
     * @return The error code.
     *
     * @hide
     */
    static int handleException(Exception e) {
        Log.w(TAG, "Exception caught", e);
        if (e instanceof RemoteException) {
            return STATUS_DEAD_OBJECT;
        }
        if (e instanceof ServiceSpecificException) {
            switch (((ServiceSpecificException) e).errorCode) {
                case Status.OPERATION_NOT_SUPPORTED:
                    return STATUS_INVALID_OPERATION;
                case Status.TEMPORARY_PERMISSION_DENIED:
                    return STATUS_PERMISSION_DENIED;
                case Status.DEAD_OBJECT:
                    return STATUS_DEAD_OBJECT;
            }
            return STATUS_ERROR;
        }
        if (e instanceof SecurityException) {
            return STATUS_PERMISSION_DENIED;
        }
        if (e instanceof IllegalStateException) {
            return STATUS_INVALID_OPERATION;
        }
        if (e instanceof IllegalArgumentException || e instanceof NullPointerException) {
            return STATUS_BAD_VALUE;
        }
        // This is not one of the conditions represented by our error code, escalate to a
        // RuntimeException.
        Log.e(TAG, "Escalating unexpected exception: ", e);
        throw new RuntimeException(e);
    }

    /**
     * Returns a list of descriptors for all hardware modules loaded.
     * @param modules A ModuleProperties array where the list will be returned.
@@ -1697,9 +1738,8 @@ public class SoundTrigger {
                modules.add(ConversionUtil.aidl2apiModuleDescriptor(desc));
            }
            return STATUS_OK;
        } catch (RemoteException e) {
            Log.e(TAG, "Exception caught", e);
            return STATUS_DEAD_OBJECT;
        } catch (Exception e) {
            return handleException(e);
        }
    }

+7 −24
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public class SoundTriggerModule {
                mService = null;
            }
        } catch (Exception e) {
            handleException(e);
            SoundTrigger.handleException(e);
        }
    }

@@ -115,7 +115,7 @@ public class SoundTriggerModule {
            }
            return SoundTrigger.STATUS_BAD_VALUE;
        } catch (Exception e) {
            return handleException(e);
            return SoundTrigger.handleException(e);
        }
    }

@@ -137,7 +137,7 @@ public class SoundTriggerModule {
            mService.unloadModel(soundModelHandle);
            return SoundTrigger.STATUS_OK;
        } catch (Exception e) {
            return handleException(e);
            return SoundTrigger.handleException(e);
        }
    }

@@ -166,7 +166,7 @@ public class SoundTriggerModule {
                    ConversionUtil.api2aidlRecognitionConfig(config));
            return SoundTrigger.STATUS_OK;
        } catch (Exception e) {
            return handleException(e);
            return SoundTrigger.handleException(e);
        }
    }

@@ -189,7 +189,7 @@ public class SoundTriggerModule {
            mService.stopRecognition(soundModelHandle);
            return SoundTrigger.STATUS_OK;
        } catch (Exception e) {
            return handleException(e);
            return SoundTrigger.handleException(e);
        }
    }

@@ -214,7 +214,7 @@ public class SoundTriggerModule {
            mService.forceRecognitionEvent(soundModelHandle);
            return SoundTrigger.STATUS_OK;
        } catch (Exception e) {
            return handleException(e);
            return SoundTrigger.handleException(e);
        }
    }

@@ -242,7 +242,7 @@ public class SoundTriggerModule {
                    ConversionUtil.api2aidlModelParameter(modelParam), value);
            return SoundTrigger.STATUS_OK;
        } catch (Exception e) {
            return handleException(e);
            return SoundTrigger.handleException(e);
        }
    }

@@ -296,23 +296,6 @@ public class SoundTriggerModule {
        }
    }

    private int handleException(Exception e) {
        Log.e(TAG, "", e);
        if (e instanceof NullPointerException) {
            return SoundTrigger.STATUS_NO_INIT;
        }
        if (e instanceof RemoteException) {
            return SoundTrigger.STATUS_DEAD_OBJECT;
        }
        if (e instanceof IllegalArgumentException) {
            return SoundTrigger.STATUS_BAD_VALUE;
        }
        if (e instanceof IllegalStateException) {
            return SoundTrigger.STATUS_INVALID_OPERATION;
        }
        return SoundTrigger.STATUS_ERROR;
    }

    private class EventHandlerDelegate extends ISoundTriggerCallback.Stub implements
            IBinder.DeathRecipient {
        private final Handler mHandler;