diff --git a/.gitignore b/.gitignore index b58132f9b..08c045114 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ compile_commands.json tools/builder __pycache__ +aacs/ diff --git a/Alexa_Embedded_CX_Requirements_v13.0.xlsx b/Alexa_Embedded_CX_Requirements_v13.0.xlsx deleted file mode 100644 index b03a4e05e..000000000 Binary files a/Alexa_Embedded_CX_Requirements_v13.0.xlsx and /dev/null differ diff --git a/NOTICE b/NOTICE index 387260f57..b7ca1a56f 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Alexa Auto SDK -Copyright 2017-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. ************************* ALEXA AUTO SDK COMPONENTS diff --git a/aacs/android/README.md b/aacs/android/README.md deleted file mode 100644 index 1b9b2aa88..000000000 --- a/aacs/android/README.md +++ /dev/null @@ -1,757 +0,0 @@ -# Alexa Auto Client Service (AACS) - -## Overview -Alexa Auto Client Service (AACS) is an Alexa Auto SDK feature packaged in an Android archive library (AAR). By providing a common service framework, AACS simplifies the integration of the Auto SDK with your Android device and supports all the Auto SDK extensions. - -Your application communicates with AACS through an intent, which is a messaging object on an Android device. AACS provides the platform implementation for certain interfaces, which speeds up Alexa integration for in-vehicle infotainment (IVI). Without AACS, typical integration of the Auto SDK in the IVI involves the implementation of abstract interfaces provided by each Auto SDK module to handle platform-specific functionality. To implement all required platform interfaces, the Auto SDK is integrated to an event-based system that converts from direct method APIs to an event-based architecture. - -This document assumes that you understand how the Auto SDK works, as described in the [Auto SDK concepts documentation](https://alexa.github.io/alexa-auto-sdk/docs/explore/concepts). When this document uses the term "application," it refers to the application you develop on the Android platform. Information for your application in this document also applies to your Android service. - -## AACS Architecture -The following diagram shows the high-level architecture of AACS on the Android platform. The shaded boxes in the diagram represent components developed by Amazon that are packaged in AACS. - -![AACS Arch Detailed](./docs/diagrams/AACSArchDetailed.png) -The following list describes the components in the AACS service layer, as illustrated in the diagram, and how they interact with one another and with the Auto SDK: - -1. **AlexaAutoClientService** is a persistent service that can start automatically after device boot-up or be manually started by an application through a `startService()` call. The service performs the following functions: - - * Instantiating the Auto SDK Engine. - * Creating and registering the AASB message handler with the AASB MessageBroker. - * Setting the required Engine configuration. - * Managing the notifications displayed in the system notification area. - -2. **PhoneControlMessagingImpl** and **NavigationMessagingImpl** are messaging implementations that serialize direct API calls into a standardized message format. The `PhoneControlMessagingImpl` or `NavigationMessagingImpl` converts platform interface method parameters into the message payload of the respective messaging implementation. The message is then sent to the service layer by using the AASB `MessageBroker` with a specific message topic and action. The messaging implementation also subscribes to message topics that are sent from the human-machine interface (HMI) application to the Auto SDK. -3. **AudioInputImpl**, **AudioOutputImpl**, **ExternalMediaPlayerImpl**, and **AdditionalPlatformImpl** are the direct implementations of Auto SDK platform interfaces. You can enable or disable the implementations in the AACS AAR through the configuration file. If an implementation is disabled, the platform message handler must be provided by a client application. -4. **AASB MessageBroker** is an abstraction built on top of the Auto SDK core. `MessageBroker` routes messages between the application and the Auto SDK core. When the -application responds to `MessageBroker` with an event, the event is routed back through the platform interface implementation. -5. **AASB MessageHandler** implements the platform-specific logic to send and receive AASB messages. -6. **Mediaplayer** handles the default AudioOutput actions, such as prepare, play, and pause for a TTS channel. -7. **IPCLibrary** defines the protocol for the communication between the HMI application and AACS. -It provides the APIs for sending and receiving AASB Messages over the Android Intent/Binder interface and -supports streaming audio data to and from an external application. It builds into an Android archive (AAR) file, which you can include in other apps that need to communicate with AACS. For more information about the IPC, see this [README](common/ipc/README.md). -8. **LVCInteractionProvider** implements APIs defined by the `ILVCClient` Android Interface Definition Language (AIDL) file to connect with `ILVCService`, which is implemented by the Local Voice Control (LVC) application. This connection also enables the LVC APK to provide the configuration for LVC. -9. The core of the **HMI application** that holds the business logic need not change with -`AlexaAutoClientService`. However, you must modify the application so that it can interface with the APIs defined by AACS. - -### AACS as Foreground Service or System Service -AACS runs as a started service on Android. The [Initialization](#initialization) section describes how it is started; this section describes what you do to run AACS as a foreground service or a system service. - -#### As Foreground Service -Typically, AACS is started as a foreground service, which has higher priority and continues running unless it is under memory constraints. In addition, the service displays notifications to alert the user that it is running. - -AACS is run as a foreground service if your application containg AACS AAR is not a system application. -Then your application can use the `startForegroundService()` function to initialize AACS. If AACS is started properly, a notification is displayed. - -Since Android 8.0 (API level 26), foreground services have had -some changes in how they are initialized. The following code checks the Android version and calls the correct API: -~~~ -Intent intentStartService = new Intent(); -intentStartService.setComponent(new ComponentName(AACSConstants.getAACSPackageName(new WeakReference(context)), -"com.amazon.alexaautoclientservice.AlexaAutoClientService")); -intentStartService.setAction(Action.LAUNCH_SERVICE); - -if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - startForegroundService(intent); -} else { - startService(intent); -} -~~~ - -#### As Persistent System Service -If you have root access on the device and your application containing AACS AAR is a system application, then AACS is run as a system service. -Your application no longer needs to start AACS in the foreground, and no notifications appear to show that the service is running. The following example shows an application starting AACS as a system service: -~~~ -Intent intentStartService = new Intent(); -intentStartService.setComponent(new ComponentName(AACSConstants.getAACSPackageName(new WeakReference(context)), -"com.amazon.alexaautoclientservice.AlexaAutoClientService")); -intentStartService.setAction(Action.LAUNCH_SERVICE); - -startService(intent); -~~~ - -Note: persistentSystemService configuration is deprecated. You no longer need to specify this field to run AACS as a persistent system service. - -### AACS Initialization and Configuration -Initializing AACS means getting AACS ready to communicate with other applications. However, Alexa functionality is not available until AACS receives the configuration. - -#### Initialization -There are two ways to initialize AACS: - -* Start AACS from an application: -AACS includes a permission that determines whether an application can start or stop the service. For an application to start or stop AACS, specify the permission name in the application's `AndroidManifest.xml` file as follows: - - `` - - For an example of starting AACS from an application, see [example for starting AACS as a system service](#as-persistent-system-service). - -* Start AACS upon device boot: If you want AACS to start every time the user turns on the device, set `startOnDeviceBootEnabled` in `aacs.general` of your configuration to `true`. Due to this setting, AACS initiates a `startService()` call on itself when it receives the `BOOT_COMPLETED` intent, which the device broadcasts when it is finished booting. - - >**Important!** The device considers AACS inactive until AACS is run at least once. AACS does not start automatically on device boot unless AACS is considered active. Simply run AACS at least once after installation, and AACS will start each time the device is restarted. - -Whether `startOnDeviceBootEnabled` is set to `true` or `false`, the application can always send a `startService()` or `stopService()` call to start or stop AACS. - -#### Configuration Schema -This section describes the configuration schema, which includes Auto SDK engine configuration, general service behavioral settings, and definitions for how AACS interfaces with applications. For more information about AACS configuration, see [Configuration Reference documentation](service/README.md). - - >**Important!** Some configuration fields may require you to provide filepaths. These filepaths must be absolute paths that are accessible to AACS. AACS will not accept filepaths to public locations (such as SD card) for security reasons. - -The sample configuration JSON file in this section illustrates the AACS configuration structure. Be sure to fill out the following required sections under `deviceInfo` of `aacs.alexa`: - -* `clientId` -* `productId` -* `deviceSerialNumber` - -The following documents provide more information about configuration: - -* [Auto SDK module documentation](https://alexa.github.io/alexa-auto-sdk/docs/explore/features) -* [Complete configuration file](https://github.com/alexa/alexa-auto-sdk/blob/4.0/aacs/android/assets/config.json) -~~~ -{ - "aacs.alexa": { - "deviceInfo": { - "clientId": "", - "productId": "", - "deviceSerialNumber": "", - "manufacturerName": "name", - "description": "description" - }, - "localMediaSource": { - "types": [] - }, - "audio": { - "audioOutputType.music": { - "ducking":{ - "enabled": true - } - } - }, - "requestMediaPlayback": { - "mediaResumeThreshold": 50000 - } - }, - "aacs.vehicle": { - "info": { - "make": "Amazon", - "model": "AACE", - "year": "2020", - "trim": "aac", - "geography": "US", - "version": "1.2.3", - "os": "Sample OS 1.0", - "arch": "Sample Arch 1.0", - "language": "en-US", - "microphone": "SingleArray", - "countries": "US,GB,IE,CA,DE,AT,IN,JP,AU,NZ,FR", - "vehicleIdentifier": "Sample Identifier ABC" - }, - "operatingCountry": "US" - }, - "aacs.cbl": { - "enableUserProfile": false - }, - "aacs.carControl": { - "endpoints":[], - "zones":[] - }, - "aacs.general" : { - "version": "1.0", - "persistentSystemService": false, - "startServiceOnBootEnabled": true, - "intentTargets" : { - "AASB" : { - "type": ["RECEIVER"], - "package": [], - "class": [] - }, - "APL" : { - "type": ["RECEIVER"], - "package": [], - "class": [] - }, - ... (Other topics omitted) - } - }, - "aacs.defaultPlatformHandlers": { - "useDefaultLocationProvider": true, - "useDefaultNetworkInfoProvider": true, - "useDefaultExternalMediaAdapter": true, - "useDefaultPropertyManager": true", - "audioInput": { - "audioType": { - "VOICE": { - "useDefault": true, - "audioSource": "MediaRecorder.AudioSource.MIC", - "handleAudioFocus" : true - }, - "COMMUNICATION": { - "useDefault": true, - "audioSource": "MediaRecorder.AudioSource.MIC" - } - } - }, - "audioOutput": { - "audioType": { - "TTS": { - "useDefault": true - }, - "ALARM": { - "useDefault": true - }, - "MUSIC": { - "useDefault": false - }, - "NOTIFICATION": { - "useDefault": true - }, - "EARCON": { - "useDefault": true - }, - "RINGTONE": { - "useDefault": true - }, - "COMMUNICATION": { - "useDefault": true - } - } - } - } - } -~~~ - -#### Sending a Configuration Message -Sending the configuration relies on the provided [IPC library](common/ipc/README.md). This section describes the configuration's basic syntax. - -The message structure consists of two fields, `configFilepaths` and `configStrings`. `configFilepaths` is a String array containing paths to files which hold full or partial configuration JSON. `configStrings` is a String array containing full or partial configurations in the form of escaped JSON Strings. All partial configurations (from filepath or String) will be reconstructed by AACS to be a single, full configuration. We recommend using the `configStrings` option. See the **Important** note on filepaths in the beginning of the [Configuration](#configuration-schema) section. The following code shows an empty `configMessage`: -~~~ -{ - "configFilepaths: [], - "configStrings": [] -} -~~~ -Using an instance of `AACSSender`, the `sendConfigMessageEmbedded()` or `sendConfigMessageAnySize()` method ensures that the configuration message can be sent to AACS. The following example shows how to construct and send the configuration message: - -~~~ -try { - String config = "..."; // configuration read from file - JSONObject configJson = new JSONObject(config); - JSONArray configStringsArray = new JSONArray(); - configStringsArray.put(configJson.toString()); // add escaped JSON string - JSONObject configMessage = new JSONObject(); - configMessage.put("configFilepaths", new JSONArray()); - configMessage.put("configStrings", configStringsArray); - aacsSender.sendConfigMessageAnySize(configMessage.toString(), target, getApplicationContext()); -} catch (JSONException e) { - ... -} -~~~ - -#### File Sharing and Permissions -Some configurable fields for the Auto SDK require paths to files in your application, which is inaccessible to AACS. To enable the Auto SDK to get the file paths, AACS provides a protocol for applications to grant the Auto SDK URI permissions for these files. AACS then creates a local copy of the file in its internal storage and configures the fields for the Auto SDK, using the file path to the local copy to ensure accessibility. Fields that require file sharing are described in documentation. Currently, only installed extensions have configurable fields that need file sharing. See the AACS README for your extension for more information about file sharing. - -AACS's file sharing protocol uses Android's `FileProvider` class to securely receive the URIs of files in applications. See the [Android documentation](#https://developer.android.com/training/secure-file-sharing/setup-sharing) on how to set up `FileProvider` in your application. Your `FileProvider` is functional after the application includes a `` element in its AndroidManifest and a `filepaths.xml` file for specifying shareable paths. - -After `FileProvider` is set up, AACS expects to receive an intent with action `Intent.ACTION_SEND_MULTIPLE` to include the URIs of files to be shared. Send the intent **after** service initialization but **before** the configuration message is sent. It requires the following structure: - -* **Action:** `Intent.ACTION_SEND_MULTIPLE` - The standard Android intent for sharing multiple pieces of content -* **Type:** The MIME type of a URI -* **Extra:** `AACSConstants.CONFIG_MODULE` or `configModule`- A `String` representing the module to be configured by the shared files -* **ParcelableArrayListExtra:** `Intent.EXTRA_STREAM` - An `ArrayList` containing URIs of files to be shared - -Before sending the intent, be sure to grant the `Intent.FLAG_GRANT_READ_URI_PERMISSION` to AACS for each URI being sent. Also, because the intent holds multiple file URIs for a single configuration module at a time, if there are multiple files for separate modules, send multiple intents, as shown in the following example implementation: - -~~~ -private void shareFilePermissionsOfSameModule(File parent, String[] filenames, String module) { - ArrayList fileUris = new ArrayList<>(); - for (String name : filenames) { - File file = new File(parent, name); - Uri fileUri = FileProvider.getUriForFile( - MainActivity.this, - , - file); - grantUriPermission(AACSConstants.getAACSPackageName(new WeakReference(context)), fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); - fileUris.add(fileUri); - } - - Intent shareFileIntent = new Intent(); - shareFileIntent.setComponent( - new ComponentName(AACSConstants.getAACSPackageName(new WeakReference(context)), AACSConstants.AACS_CLASS_NAME)); - shareFileIntent.setAction(Intent.ACTION_SEND_MULTIPLE); - shareFileIntent.setType(getContentResolver().getType(fileUris.get(0))); - shareFileIntent.putExtra(AACSConstants.CONFIG_MODULE, module); - shareFileIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, fileUris); - startForegroundService(shareFileIntent); -} -~~~ - ->**Note:** `AACSConstants.AACS_PACKAGE_NAME` is deprecated and it shall be removed from the future Alexa Auto SDK versions. Use `AACSConstants.getAACSPackageName(Context)` instead. - -#### Initialization Protocol -After starting the service, send file sharing intents for any files outside of AACS's access that will be needed for configuration. Then, send the configuration message. If there are no files to be shared, the configuration can be sent immediately after AACS is initialized. The configuration is not part of the initial intent to start the service because intents in Android have size limits, which the configuration might exceed. Using the provided IPC library allows for sending configuration of any size. - -Because AACS stores the last configuration received, the only requirement is that the configuration is sent the first time AACS is run -after installation. At any subsequent start, AACS uses the stored configuration. Similarly for shared files, AACS retains local copies of the files, -so file sharing intents do not have to be re-sent in subsequent launches. - -However, updating the stored configuration (without uninstalling the application containing AACS AAR) requires that the -`startService` intent include an `Extras` field called `newConfig`. `newConfig` holds a -boolean value that alerts AACS not to start running with the stored configuration, but wait for a new configuration message. -In addition, whenever the `newConfig` field is set to `true`, AACS clears all local copies of shared files -and expect new file sharing intents, if necessary for the new configuration. - -**Note**: The old configuration is overwritten by the new configuration. - -For your application to start AACS with a new configuration, make sure your intent includes `newConfig`, as shown in the following example: - -~~~ -Intent intentStartService = new Intent(); -intentStartService.setComponent(new ComponentName(AACSConstants.getAACSPackageName(new WeakReference(context)), -"com.amazon.alexaautoclientservice.AlexaAutoClientService")); -intentStartService.setAction(Action.LAUNCH_SERVICE); -intentStartService.putExtra("newConfig", true); -~~~ - -Omitting `newConfig` is the same as setting it to `false`, which causes AACS to use the stored configuration. - -**Important**: Sending a new configuration is allowed only once per service run. After AACS is configured and -running, AACS ignores subsequent attempts to update the configuration, even if the `newConfig` field is `true`. To update an existing configuration, you must -stop the service and restart it with `newConfig` set to `true`. This same rule applies to file sharing intents. - -#### Initialization Sequence Diagram -The following diagram shows an example of initializing AACS from an app used by a driver. -![AASC Init Flow](./docs/diagrams/AACSInitFlow.png) - -## Default Platform Implementation -Default platform implementations refer to implementations of Auto SDK platform interfaces that AACS provides to replace the normal protocol of using AASB messages. By enabling a default platform implementation in AACS, you no longer have to handle messages for a particular platform interface and can rely on AACS to provide the necessary functionality. - -AACS provides a default implementation for these platform interfaces: - -* AudioInput (audioType: VOICE, COMMS) -* AudioOutput (audioType: TTS, ALARM, NOTIFICATIONS, EARCON, RINGTONE) -* LocationProvider -* NetworkInfoProvider -* ExternalMediaAdapter for Media App Command and Control (MACC) -* LocalMediaSource -* PropertyManager - -The platform implementations for these interfaces are disabled by default; the AASB messages for these interfaces are routed to the [client app to be handled](#specifying-the-app-targets-for-handling-messages). - -To enable the default platform implementation in AACS, you must set the `aacs.defaultPlatformHandlers` -configuration flags. In the following example, you use `aacs.defaultPlatformHandlers` in the -configuration file to instruct AACS to handle `LocationProvider` and `NetworkInfoProvider`, `AudioInput` for `VOICE`, and -`AudioOutput` for `TTS`. Specific apps handle the other messages. - -~~~ -"aacs.defaultPlatformHandlers": { - "useDefaultLocationProvider": true, - "useDefaultNetworkInfoProvider": true, - "useDefaultExternalMediaAdapter": true, - "useDefaultPropertyManager": true", - "audioInput": { - "audioType": { - "VOICE": { - "useDefault": true, - "audioSource": "MediaRecorder.AudioSource.MIC", - "handleAudioFocus" : true - }, - } - }, - "audioOutput": { - "audioType": { - "TTS": { - "useDefault": true - }, - "MUSIC": { - "useDefault": false - }, - ... other audio types - } - } - } -~~~ - -### Property Content Provider Implementation (Optional) - -AACS supports the Android `ContentProvider` class, which is a standard Android mechanism for performing CRUD (Create, Read, Update, Delete) operations on stored data. By extending this class, you can use a content provider, instead of AACS messages, to manage Auto SDK properties and retrieve state information. Using a content provider offers the following advantages: - -* AACS can consistently provide the properties across multiple launches. Because properties are persistent, your application does not need to reset the properties after each AACS restart. - -* AACS messages are asynchronous, which might cause timeouts and subsequently incorrect or error states. Using a content provider to retrieve state data makes the retrieval process synchronous, thus guaranteeing that the request for state information reaches its destination and a response is received. - -* ContentProvider is the standard Android mechanism for performing CRUD (Create, Read, Update, Delete) operations on stored data. - -#### Sequence Diagram and Overview - -The following sequence diagram illustrates the workflow for the default property manager implementation in AACS. This implementation provides the interface, based on the Android `ContentProvider`, for OEM apps to get and set Auto SDK properties. - -~~~ -aace.alexa.wakewordSupported -aace.alexa.system.firmwareVersion -aace.alexa.setting.locale -aace.alexa.countrySupported -aace.alexa.timezone -aace.alexa.wakewordEnabled -aace.vehicle.operatingCountry -aace.core.version -aace.network.networkInterface -~~~ - -By using the native Android `ContentProvider` class, you can initiate `query` and `update` operations. query retrieves and returns the current String value of an Auto SDK property. `update` sets an Auto SDK property in the Engine and returns a boolean value based on the success of the operation. Insert and Delete operations are disabled for Auto SDK properties. - -![APCP](./docs/diagrams/APCP.png) - -#### Implementation Examples -1. Add `useDefaultPropertyManager` in the `config.json` file and set it to `true`, as shown in the following example: - - ~~~ - ... - "aacs.defaultPlatformHandlers": { - "useDefaultLocationProvider": true, - --> "useDefaultPropertyManager": true, - "audioInput": { - "audioType": { - ... - ~~~ - -2. Add `READ_USER_DICTIONARY` permission to `AndroidManifest.xml` in your application, as shown in the following example: - ~~~ - - { - getContentResolver().update(uri, cv, propertyName, null); - }); - } - } - ~~~ - -#### Important Considerations for Using ContentProvider - -* AACS Property Content Provider does not support the `insert` and `delete` APIs in Property ContentProvider; - -* You must use AACS with the AmazonLite Wake Word extension if you want to update `aace.alexa.wakewordEnabled` property; - -* `aace.alexa.countrySupported` is a deprecated property and cannot be get/set; - -* `aace.alexa.wakewordSupported` and `aace.core.version` are read-only properties acquired when building Auto SDK and cannot be set. - -* Valid property value for `aace.alexa.wakewordEnabled` is `true` or `false`. All the other Auto SDK properties will be validated by Auto SDK. Auto SDK will provide value validation for `aace.alexa.wakewordEnabled` in the future. - -### Enabling AACS to synchronize Alexa's Time Zone and Locale with Device Settings (Optional) -AACS supports synchronizing Alexa's time zone and locale properties with the ones in device settings. To enable the functionality, refer to this [README](service/README.md#syncsystempropertychange) for proper configuration. Once enabled, AACS will synchronize the time zone and/or locale properties of Alexa with the device settings in the following conditions: - -* When Auto SDK engine is initialized, AACS tries to synchronize both properties with the device settings. The property change would fail and not take effect if the system locale is not supported by Alexa. -* When the authorization state is refreshed, AACS tries to synchronize both properties with the device settings. The property change would fail and not take effect if the system locale is not supported by Alexa. -* When AACS gets `android.intent.action.LOCALE_CHANGED` intent as a result of device locale setting change, Alexa locale property will be updated if the locale is supported by Alexa. -* When AACS gets `android.intent.action.TIMEZONE_CHANGED` intent as a result of device time zone setting change, Alexa time zone property will be updated. - -You can also disable the automatic synchronization for specific properties. This is particularly useful when your application wants to disable/enable the synchronization at runtime. For example, after the user manually selects a locale, you may want to disable the synchronization to allow the user's selection to override the system setting changes. To achieve this use case, your application can send intents with the metadata below to AACS: - -* Action: - * Disable: `com.amazon.aacs.syncSystemPropertyChange.disable` - * Enable: `com.amazon.aacs.syncSystemPropertyChange.enable` -* Category: `com.amazon.aacs.syncSystemPropertyChange` -* Extra: `"property": ` - -If this feature is not enabled, your application can still have the full flexibility in changing the two properties by handling AASB Property Manager messages. - -Additionally, you can configure AACS to update the system time zone if the user changes the Alexa's time zone for the device (e.g. the user can change the property on their Alexa mobile app). To enable the functionality, refer to this [README](service/README.md#updatesystempropertyallowed) for proper configuration. Your application with AACS needs to be a system application with android permission `android.permission.SET_TIME_ZONE` obtained. - -**Note:** Always provide the system permission `android.permission.SET_TIME_ZONE` when AACS AAR is in a system application. Refer to [Privileged Permission Allowlisting](https://source.android.com/devices/tech/config/perms-allowlist) in Android documentation. - -### Using Custom Domain Module with CustomDomainMessageDispatcher Enabled (Optional) -To use Custom Domain module with AACS, you need to explicitly enable it first by adding module enablement configuration. Please refer to [AACS Configuration README](service/README.md#aacs-module-enablement) to enable the Custom Domain module. - -By default, all the Custom Domain intents share the same `com.amazon.aacs.aasb.customDomain` intent category. If CustomDomainMessageDispatcher is enabled, the intent category will be the namespace of the custom interface prefixed with `com.amazon.aacs.customDomain`, which allows AACS to dispatch the Custom Domain AASB messages from the engine to the proper components in your system based on the custom namespace. - -Below is the intent schema of the intents sent from the dispatcher. All the intents are sent with our [IPC library](common/ipc/README.md). You can use `AACSReceiver` to receive and process the AASB Custom Domain messages in the intents. - -* Intent for handling/canceling a custom directive: - - * Action: `com.amazon.aacs.customDomain.`. - * Category: `com.amazon.aacs.customDomain.`. - -* Intent for getting the context for a custom namespace: - - * Action: `com.amazon.aacs.customDomain.GetContext` - * Category: `com.amazon.aacs.customDomain.`. - -You can define intent filters in the Android Manifest of your applications to subscribe to the specific Custom Domain intents. See [Specifying the Intent Targets for Handling Messages Using Android Manifest](#using-android-manifest) to learn more about specifying intent targets. -Please refer to this [README](service/README.md#usedefaultcustomdomainmessagedispatcher) on enabling CustomDomainMessageDispatcher. - ->**Note**: CustomDomainMessageDispatcher does not process any custom directives. Your application is responsible for handling any custom directives, sending custom events, and providing custom contexts following the [Custom Domain AASB Documentation](https://alexa.github.io/alexa-auto-sdk/docs/aasb/custom-domain/CustomDomain/index.html). If the dispatcher is not enabled, your application will be responsible for receiving all the Custom Domain AASB Messages (as intents) at one place. - -## Specifying the Intent Targets for Handling Messages - -The AASB message intent targets can be `ACTIVITY`, `RECEIVER`, or `SERVICE`. There are two ways to specify the intent targets for AASB message intents from AACS. - -### Using Android Manifest -You can define intent filters in your application's Android Manifest. The intent filter must exactly match the intents' categories and actions. In the intent filter for an intent that wraps an AASB message, specify the category as `com.amazon.aacs.aasb.` and action as `com.amazon.aacs.aasb.`. - -The following example shows an intent filter of all the CBL message intents for a broadcast receiver target: -~~~ - - - - - - - - - - -~~~ -To receive the message specified through the Android Manifest, the application must also have `com.amazon.alexaautoclientservice` permission in its Android Manifest. -~~~ - -~~~ - -Follow these important guidelines if the intent target is an activity: - -* You must add `` to the intent filter as explained [here](https://developer.android.com/guide/components/intents-filters). - -* Be aware that if you start applications with AACS (for example, by specifying Activity as the intent targets from AACS), the target Activity will move to the foreground or become in focus, causing distraction or confusion to the user. AACS does not request `SYSTEM_ALERT_WINDOW` permission to directly create windows on top of all other apps. Amazon recommends using VIS (VoiceInteractionService) to launch activities, and using Android Services or Broadcast Receivers to receive intents from AACS. - -### Using AACS Configuration File -You can use the AACS configuration file to specify the app that can handle AASB messages with a specific "topic". This method of specifying intent targets has the highest priority, meaning it can *override* the ones specified through intent filters in manifests. After you use the AACS configuration to specify the app, intents with all the actions belonging to the topic go to the specified targets. -Fill the optional fields in `intentTargets` in the AACS configuration file as needed. See the [Configuration Reference documentation](service/README.md) for information about `intentTargets`. The following sample configuration shows how to populate `intentTargets` for each topic. The field `type` accepts `RECEIVER`, `ACTIVITY`, and `SERVICE`, depending on the type of the target that handles the intents with the topic. The targets can be broadcast receiver, application activity, and service. - -The format for specifying AASB message intent targets for an AASB message topic is as follows: -~~~ -"" : { - "type": [, , ...], - "package": ["", "", ...], - "class": ["", "", ...] -}, -~~~ - -The following example shows two topics, which are `AASB` and `APL`: -~~~ - "aacs.general" : { - "intentTargets" : { - "AASB" : { - "type": ["ACTIVITY"], - "package": ["com.amazon.aacstestapp"], - "class": ["com.amazon.aacstestapp.MainActivity"] - }, - "APL" : { - "type": ["RECEIVER"], - "package": ["com.amazon.aacstestapp"], - "class": [".IntentReceiver"] // short version of class name is also accepted. - }, // In this case, the class must be in the package specified in "package". - // ... other topics - } - } -~~~ - -**NOTE**: If a given "topic" is specified both in the configuration file and the -Android Manifest, the configuration file takes priority and the targets with intent filters are ignored. Amazon recommends intent filters when possible. Use the configuration approach only if you need to override the existing intent filters. - -AACS first searches for targets for an intent with a topic in the configuration file. If nothing is found, the package manager scans the intent filters on the device to locate a match. AACS also caches the scan results based on both topic and action. The cache is cleared every time AACS is restarted. - -## Platform Implementation in Your Application -Your applications can register for specific AASB messages and provide a platform implementation. For example, an application (“Login app") can register for Authorization messages. For information about the Authorization module, see the `Core` module documentation. - -### Initial Authentication Sequence Diagram -The following sequence diagram illustrates how an application (“Login app") exchanges messages with AACS over Android Intents to log in the user for Alexa. - -![AACS CBL Login](./docs/diagrams/AACS_CBLLogin.png) - -### Wake Word Enabled Sequence Diagram -The sequence diagram illustrates the sequence for the user to access Alexa if you use the default implementation of AudioInput in AACS. In this diagram, the driver is logged in and wake word is enabled. The driver initiates the action by uttering the Alexa wake word. -![AACS Wakeword](./docs/diagrams/AACSWakeword.png) - -1. Audio is processed locally by the wake word engine in AACS until the wake word is detected. Upon wake word detection, AACS notifies the application that the dialog state has changed to "listening" and initiates a Recognize event with Alexa. - -2. While in the listening state, audio data is sent to Alexa. When the end of speech is detected, Alexa sends a `StopCapture` directive to AACS, and the dialog state is changed to "thinking." Alexa then responds with additional directives in response to the speech request. - -For information about other messages to provide your implementation in the client APK, please refer to the documentation for each Auto SDK module. - -## Client Utility Library - -AACS also provides an optional library, [AACS Common Utils](common/commonutils/README.md). It contains useful methods to make messaging with AACS easier. You can use it as-is or as a reference to facilitate the integration of the Auto SDK with AACS. For information about the library, see [AACS Common Utils README](common/commonutils/README.md) and in-code documentation in the library. - -## Device Settings Required for AACS -AACS requires microphone and location permissions when the default implementation is used for AudioInput and Location. If AACS runs in a system application, you can grant these permissions so that the application users do not have to set the permissions. Otherwise, be sure to instruct your users to grant the following permissions on the app info page under Settings on their device: - -* Location: Enable `android.permission.ACCESS_FINE_LOCATION` to give AACS access the current location. - -* Microphone: Enable `android.permission.RECORD_AUDIO` to give permission to AACS to record audio. Microphone must be enabled if you configure AudioInput to use the default implementation of AACS. - -## Checking AACS Connection State -Your application or service can check the status of AACS by using `ping`, which returns a response as long as AACS is running. The `AACSPinger` utility class from the IPC library enables you to use `ping`. - -To ping AACS, specify the ping permission name in your application's Android Manifest file as follows: - -~~~ - -~~~ - -The following example shows how to use `AACSPinger`: - -~~~ -AACSPinger aacsPinger = new AACSPinger(getApplicationContext(), - "com.amazon.alexaautoclientservice.ping"); - -Future fut = aacsPinger.pingAACS(); - -AACSPinger.AACSPingResponse response = fut.get(); - -if (response.hasResponse) { - // Ping was responded to by AACS - String state = response.AACSState; - ... -} else { - // Ping timed out without an AACS response -} -~~~ - -If AACS responds to the ping request, the `AACSPingResponse.AACSState` string returned by `AACSPinger.pingAACS()` has one of the following values: - -* `STARTED` -* `WAIT_FOR_LVC_CONFIG` -* `CONFIGURED` -* `ENGINE_INITIALIZED` -* `CONNECTED` -* `STOPPED` - -If AACS does not respond within the default timeout of 1 second, `AACSPingResponse.hasResponse` is `false`. - -## AACS State Notification - -As an alternative to pinger where the application or service can fetch the AACS State, AACS also broadcast the various state transitions. - -Your application needs to register a receiver for the following intent action: - -"com.amazon.aacs.service.statechanged" - -This is defined in AACS Constants as ACTION_STATE_CHANGE - -The following example shows an intent receiver to receive AACS State transition events: - -~~~ - -mAACSStateIntentReceiver = new aacsStateIntentReceiver(); - -IntentFilter filter = new IntentFilter(); -filter.addAction(AACSConstants.ACTION_STATE_CHANGE); - -(context.get()).registerReceiver(mAACSStateIntentReceiver, filter); - -~~~ -## Request list of extras from AACS - -Your application can receive the list of AACS extra modules by sending an intent with the action `AACSConstants.IntentAction.GET_SERVICE_METADATA` and the category `AACSConstants.IntentCategory.GET_SERVICE_METADATA`, which returns a response by receiving an intent `AACSConstants.IntentAction.GET_SERVICE_METADATA_REPLY`. - -To get the extras list from AACS- - -- Specify the permission name in your application's Android Manifest file as follows: - -~~~ xml - -~~~ - -- Register a receiver in you application's Android Manifest file as follows: -Following block shows an example of requesting list of extras: - -~~~ xml - -~~~ - -- Send a request intent to AACS. Following code snippet shows an example - -~~~ java -Intent intent = new Intent(); -intent.setAction(AACSConstants.IntentAction.GET_SERVICE_METADATA); -intent.addCategory(AACSConstants.IntentCategory.GET_SERVICE_METADATA); -intent.putExtra(AACSConstants.REPLY_TO_PACKAGE, getPackageName()); -intent.putExtra(AACSConstants.REPLY_TO_CLASS, .class.getName()); -intent.putExtra(AACSConstants.REPLY_TYPE, "RECEIVER"); -sendBroadcast(intent); -~~~ - -- Your receiver class will receive an intent with the following payload - -~~~ json -{ - "metaData": { - "extrasModuleList": [] - } -} -~~~ - -- You can get the payload from the received intent with action `AACSConstants.IntentAction.GET_SERVICE_METADATA_REPLY`. Following code snippet shows the example: - -~~~ java -String payload = intent.getStringExtra(AACSConstants.PAYLOAD); -~~~ - -## Using Instrumentation -You can use AACS instrumentation to log AASB messages for debugging purposes. For more information about how to use instrumentation, see the [AACS Instrumentation README](./service/core-service/src/debug/java/com/amazon/alexaautoclientservice/README.md). - ->**Note:** You can use instrumentation only if you use the debug option when building the Auto SDK with AACS. diff --git a/aacs/android/app-components/README.md b/aacs/android/app-components/README.md deleted file mode 100644 index cd2b08993..000000000 --- a/aacs/android/app-components/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Alexa Auto app components - -The Alexa Auto app components are modularized Android implementation libraries for Alexa features. \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apis/.gitignore b/aacs/android/app-components/alexa-auto-apis/.gitignore deleted file mode 100644 index 35679994d..000000000 --- a/aacs/android/app-components/alexa-auto-apis/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/build -/.gradle -/.idea diff --git a/aacs/android/app-components/alexa-auto-apis/README.md b/aacs/android/app-components/alexa-auto-apis/README.md deleted file mode 100644 index 8a878d106..000000000 --- a/aacs/android/app-components/alexa-auto-apis/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Alexa Auto API - -This Alexa Auto API package provides: - -* Types that are used across multiple Java packages. A Java package is a collection of related types, which is created to avoid type name collisions. -* Interfaces that allow packages to communicate with each other by using standard Java, as long as the consumer and provider of the interface meet these requirements: - * They are in the same Android Package (APK). - * They are loaded and used in the same process. - -## Component Registry (Service Locator) -To enable a package to locate the implementation of an API, the Alexa Auto API Package defines the component registry interfaces and the mechanism to obtain the component registry (also called the service locator). - -### Consuming Implementations from Other Packages - -The following list explains the component registry interfaces: - -* `AlexaAppRootComponent` is a component registry interface with an application scope. It provides interfaces that are in scope for the lifetime of the app. This interface provides access to `AlexaAppScopedComponents`, among other interfaces. -* `AlexaAppScopedComponents` provides interfaces that are available for a limited scope. For example, when an app is in logged-off state, `AlexaAppLoggedOutScopedComponent` can be queried by using `AlexaAppScopedComponents`. - -Any library or application class can obtain `AlexaAppRootComponent` as long as it has the Android context. The following code example illustrates how an app obtains `AlexaAppRootComponent`: - -``` -class MyActivity extends AppCompatActivity { - - public void onStart() { - AlexaApp app = AlexaApp.from(this); - AlexaAppRootComponent componentRegistry = app.getRootComponent(); - componentRegistry.getXYZ().doSomethingUseful(); - } -} -``` - -### Publishing Implementations for Other Packages -How a package publishes the implementation of an API for another package to use depends on the scope, as explained in the following list: - -* App lifecycle implementation: If an object's lifecycle is bound to the lifecycle of an app, then the main Alexa app APK creates an instance of the object and makes it available through the implementation of `AlexaAppRootComponent`. -* Limited scoped implementations: A package can publish scoped components into the component registry to be discovered by other packages. To publish a scoped component, the package can obtain `AlexaAppScopedComponentsActivator` from `AlexaAppRootComponent`. diff --git a/aacs/android/app-components/alexa-auto-apis/build.gradle b/aacs/android/app-components/alexa-auto-apis/build.gradle deleted file mode 100644 index 59e4e8ab6..000000000 --- a/aacs/android/app-components/alexa-auto-apis/build.gradle +++ /dev/null @@ -1,53 +0,0 @@ -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' - -android { - compileSdkVersion 32 - defaultConfig { - minSdkVersion 27 - targetSdkVersion 27 - versionCode Integer.parseInt(new Date().format("yyyyMMdd")) - versionName "4.2" - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - debug { - testCoverageEnabled true - debuggable true - } - } - - testOptions { - // Unit Test: Make all android methods return true by default - unitTests.returnDefaultValues = true - } - - compileOptions { - targetCompatibility 1.8 - sourceCompatibility 1.8 - } - - libraryVariants.all { variant -> - variant.outputs.all { - def project = "alexa-auto-apis" - def separator = "_" - def buildType = variant.buildType.name - def apkName = project + separator + buildType + ".aar" - outputFileName = new File(apkName) - } - } - -} - -dependencies { - implementation deps.kotlin_stdlib - implementation deps.androidx_appcompat - implementation deps.rxjava3 - implementation deps.androidx_navigation_fragment - - implementation project(':aacscommonutils') -} diff --git a/aacs/android/app-components/alexa-auto-apis/proguard-rules.pro b/aacs/android/app-components/alexa-auto-apis/proguard-rules.pro deleted file mode 100644 index f1b424510..000000000 --- a/aacs/android/app-components/alexa-auto-apis/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/AndroidManifest.xml b/aacs/android/app-components/alexa-auto-apis/src/main/AndroidManifest.xml deleted file mode 100644 index 5ceb2dde2..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/AndroidManifest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/AnimationProvider.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/AnimationProvider.java deleted file mode 100644 index f2329ead9..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/AnimationProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.alexaCustomAssistant; - -import android.content.Context; -import android.view.ViewGroup; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -/** - * An interface to handle custom animation. A component can provide custom animation - * that will be rendered in the layouts of the components that initialize it. - */ -public interface AnimationProvider extends ScopedComponent { - /** - * Initialize animation with the given context and view group. - * @param context Android context. - * @param viewGroup The layout that the animation will be rendered onto. - */ - void initialize(Context context, ViewGroup viewGroup); - - /** - * Un-initialize animation. - */ - void uninitialize(); - - /** - * Provide custom layout from animation provider. - * @return resource id for the custom layout. - */ - int getCustomLayout(); - - /** - * Perform different animations depending on different signals. - * @param signal Information for different animations to be rendered. For example, dialog state. - */ - void doTakeOver(String signal); - - /** - * Check if animation provider should take over the animation rendering. - * @return true if animation provider should take over. Otherwise, return false. - */ - boolean shouldTakeOver(); - - /** - * Prepare animation for PTT action. - */ - void prepareAnimationForPTT(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/AssistantManager.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/AssistantManager.java deleted file mode 100644 index 0283685e4..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/AssistantManager.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.alexaCustomAssistant; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -import org.json.JSONObject; - -/** - * An interface that allows components to have access to assistant related information. - */ -public interface AssistantManager extends ScopedComponent { - /** - * Provide the current state of the assistant manager. - * @return The state of the assistant manager. - */ - String getAssistantsState(); - - /** - * Provide the assistants settings. - * @return The settings of the assistants. - */ - JSONObject getAssistantsSettings(); - - /** - * Provide the default assistant for PTT. - * @return The assistant that is assigned to PTT. - */ - String getDefaultAssistantForPTT(); - - String getCoAssistantPolicy(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/EarconProvider.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/EarconProvider.java deleted file mode 100644 index 259442de7..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/EarconProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.alexaCustomAssistant; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -/** - * An interface to handle custom earcon. A component can provide custom earcon that will be played. - */ -public interface EarconProvider extends ScopedComponent { - /** - * Provide custom start voice earcon - * @return The resource id of the custom start voice earcon. - */ - int getAudioCueStartVoice(); - - /** - * Provide custom end of request earcon - * @return The resource id of the custom end of request earcon. - */ - int getAudioCueEnd(); - - /** - * Check if custom start voice earcon should be used. - * @param signal Information for whether custom start voice earcon should be used. For example, - * the detected wake word. - * @return true if custom start voice earcon should be used. Otherwise, return false. - */ - boolean shouldUseAudioCueStartVoice(String signal); - - /** - * Check if custom end of request earcon should be used. - * @param signal Information for whether custom end of request earcon should be used. - * @return true if custom end of request earcon should be used. Otherwise, return false. - */ - boolean shouldUseAudioCueEnd(String signal); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SettingsProvider.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SettingsProvider.java deleted file mode 100644 index 5e87f93bd..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SettingsProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.alexaCustomAssistant; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -/** - * An interface to handle custom setting related navigation graph and resources. - * A component can provide custom setting navigation graph that will override - * the default setting navigation graph. - */ -public interface SettingsProvider extends ScopedComponent { - /** - * Provide custom navigation graph from alexa settings provider. - * @return resource for the custom navigation graph. - */ - int getCustomSettingNavigationGraph(); - - /** - * Provide start destination for the navigation graph from alexa settings provider. - * @return resource id for the start destination. - */ - int getSettingStartDestination(); - - /** - * Provide setting resource id by key. - * @param key The key to map to a specific setting resource id. - * @return The setting resource id. Return 0 if there is no resource id. - */ - int getSettingResId(String key); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SetupController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SetupController.java deleted file mode 100644 index 25c071fd3..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SetupController.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.alexaCustomAssistant; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -import io.reactivex.rxjava3.core.Observable; - -/** - * An interface that allow components to interact with setup flow related to Alexa Custom Assistant. - */ - -public interface SetupController extends ScopedComponent { - /** - * Get the current flow in progress. - * @return The current flow in progress. - */ - String getCurrentSetupFlow(); - - /** - * Set the current setup flow to both-assistant, Alexa only or Non-Alexa only flow. - * @param currentFlow The current flow in progress. - */ - void setCurrentSetupFlow(String currentFlow); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SetupProvider.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SetupProvider.java deleted file mode 100644 index 3bac689e3..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/alexaCustomAssistant/SetupProvider.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.alexaCustomAssistant; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -/** - * An interface to handle custom setup related navigation graph and resources. - * A component can provide custom setup navigation graph that will override - * the default setup navigation graph. - */ -public interface SetupProvider extends ScopedComponent { - /** - * Provide custom navigation graph from alexa setup workflow provider. - * @return resource for the custom navigation graph. - */ - int getCustomSetupNavigationGraph(); - - /** - * Provide start destination for the navigation graph from alexa setup workflow provider. - * @param key The key to map to a specific setup start destination resource id - * @return resource id for the start destination. Return 0 if there is no resource id. - */ - int getSetupWorkflowStartDestinationByKey(String key); - - /** - * Provide setup resource id by key. - * @param key The key to map to a specific setup resource id. - * @return The resource id. Return 0 if there is no resource id. - */ - int getSetupResId(String key); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/apl/APLTheme.kt b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/apl/APLTheme.kt deleted file mode 100644 index b91a50bdc..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/apl/APLTheme.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.apl - -data class APLTheme ( - val themePayload : String? -) \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/apl/APLVisualController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/apl/APLVisualController.java deleted file mode 100644 index 69bc24bef..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/apl/APLVisualController.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.apl; - -import android.content.Context; -import android.view.View; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -/** - * An interface for APL visual handling logics. - */ -public interface APLVisualController extends ScopedComponent { - /** - * Initialize APL presenter with APL characteristic configs. - * - * @param context Android Activity context - * @param configs APL characteristic configs - */ - void initializeAPLPresenter(Context context, String configs); - - /** - * Set APL layout when view is created. - * - * @param view APL view - */ - void setAPLLayout(View view); - - /** - * Render APL visual card with document. - * - * @param jsonPayload document payload - * @param token APL token - * @param windowId APL window ID - */ - void renderDocument(String jsonPayload, String token, String windowId); - - /** - * Clear APL visual card. - * - * @param token APL token - */ - void clearDocument(String token); - - /** - * Execute APL command. - * - * @param payload execution payload - * @param token APL token - */ - void executeCommands(String payload, String token); - - /** - * Handle APL runtime properties update. - * - * @param aplRuntimeProperties APL runtime properties - */ - void handleAPLRuntimeProperties(String aplRuntimeProperties); - - /** - * Send APL data source update. - * - * @param dataType data type - * @param payload data source payload - * @param token APL token - */ - void handleAPLDataSourceUpdate(String dataType, String payload, String token); - - /** - * Interrupt APL commands sequence. - * - * @param token APL token - */ - void interruptCommandSequence(String token); - - /** - * Interrupt APL execution. - */ - void cancelExecution(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/AlexaApp.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/AlexaApp.java deleted file mode 100644 index b1417eb6d..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/AlexaApp.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.app; - -import android.app.Activity; -import android.app.Application; -import android.content.Context; - -import androidx.fragment.app.Fragment; - -import io.reactivex.rxjava3.annotations.NonNull; - -/** - * Glue interface that provides dependencies to different components - * participating in making of Alexa App. - * This interface must be implemented by Application class of Main - * Alexa App that is packaging all other components. - */ -public interface AlexaApp { - /** - * Provides the AlexaApp Root Component from where other - * components can fetch their dependencies. - * - * @return Root Component. - */ - AlexaAppRootComponent getRootComponent(); - - /** - * Cast Application to AlexaApp - * - * @param application Android Application Object. - * @return AlexaApp object. - */ - static AlexaApp from(@NonNull Application application) { - return (AlexaApp) application; - } - - /** - * Obtain AlexaApp from Context. - * - * @param context Android Context. - * @return AlexaApp object. - */ - static AlexaApp from(@NonNull Context context) { - return (AlexaApp) context.getApplicationContext(); - } - - /** - * Obtain AlexaApp from Activity. - * - * @param activity Android Activity. - * @return AlexaApp object. - */ - static AlexaApp from(@NonNull Activity activity) { - return (AlexaApp) activity.getApplication(); - } - - /** - * Obtain AlexaApp from Fragment. - * - * @param fragment Android Fragment. - * @return AlexaApp object. - */ - static AlexaApp from(@NonNull Fragment fragment) { - return (AlexaApp) fragment.getActivity().getApplication(); - } -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/AlexaAppRootComponent.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/AlexaAppRootComponent.java deleted file mode 100644 index ae037c4ad..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/AlexaAppRootComponent.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.app; - -import androidx.annotation.NonNull; - -import com.amazon.alexa.auto.apis.auth.AuthController; -import com.amazon.alexa.auto.apis.media.PlayerInfoCache; -import com.amazon.alexa.auto.apis.setup.AlexaSetupController; - -import java.util.Optional; - -/** - * Application wide Component Registry interface that is shared among - * all modules of Alexa App. The lifetime of components under this registry - * is bound to the lifetime of Alexa App. - * - * The registry enables library components such as alexa-auto-login, - * alexa-auto-media-player etc. to fetch common App Scope dependencies - * from main app. - * - * All app scoped components are queried using direct methods such as - * {@link AlexaAppRootComponent#getAuthController()}. The components - * with scope different than app scope can be deposited, removed and - * queried using following generic methods: - * {@link AlexaAppRootComponent#activateScope(ScopedComponent)} ()}, - * {@link AlexaAppRootComponent#deactivateScope(Class)} ()} & - * {@link AlexaAppRootComponent#getComponent(Class)}. - */ -public interface AlexaAppRootComponent { - /** - * Provides the setup controller for Alexa. - * - * @return Alexa setup controller. - */ - AlexaSetupController getAlexaSetupController(); - - /** - * Provides the {@link AuthController}. - * - * @return Auth Controller. - */ - AuthController getAuthController(); - - /** - * Provides the {@link PlayerInfoCache}. - * - * @return PlayerInfoCache. - */ - PlayerInfoCache getPlayerInfoCache(); - - /** - * Activate the scoped component and bring it in scope. - * - * @param scopedComponent Scoped component to activate. - */ - void activateScope(@NonNull T scopedComponent); - - /** - * Deactivate the scoped component and take it out of scope. - * - * @param scopedComponentClass Scoped component to de-activate. - */ - void deactivateScope(@NonNull Class scopedComponentClass); - - /** - * Query the scoped component, which was deposited earlier with {@link AlexaAppRootComponent#activateScope}. - * - * @param componentClass Class of the component being queried. - * @return Return component if component scope is active. - */ - Optional getComponent(@NonNull Class componentClass); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/ScopedComponent.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/ScopedComponent.java deleted file mode 100644 index c593d0ea8..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/app/ScopedComponent.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.app; - -/** - * Marker interface implemented by all scoped components. - */ -public interface ScopedComponent {} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthController.java deleted file mode 100644 index bbd3e9bb3..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthController.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.auth; - -import io.reactivex.rxjava3.core.Observable; - -/** - * API interface to let Alexa App know about the current auth state and - * to start authentication related workflow such as new login, profile - * selection etc. - */ -public interface AuthController { - /** - * Set authorization mode, such as CBL login mode, preview mode, etc. - * - * @param authMode Authorization mode. - */ - void setAuthMode(AuthMode authMode); - - /** - * Get authorization mode, such as CBL login mode, preview mode, etc. - * - * @return authMode Authorization mode. - */ - AuthMode getAuthMode(); - - /** - * Tells if the user has authenticated within the current app. - * - * @return true, if user has been authenticated with current app. - */ - boolean isAuthenticated(); - - /** - * Set the auth status when needed. - * - * @param authStatus, auth status. - */ - void setAuthState(AuthStatus authStatus); - - /** - * Provides the observable for New Authentication workflow. - * The authentication workflow will be started only after the client - * subscribes to the returned Observable. - * The workflow can ba cancelled anytime by simply un-subscribing from - * the Observable - * - * @return Observable to monitor the progress of authentication workflow. - */ - Observable newAuthenticationWorkflow(); - - /** - * Fetch observable that can be used to monitor the auth changes. - * - * @return Observable of auth status. - */ - Observable observeAuthChangeOrLogOut(); - - /** - * Logs out the currently logged in user. - */ - void logOut(); - - /** - * User request to cancel login with current auth mode. - */ - void cancelLogin(AuthMode mode); - - /** - * Get user identity when login with CBL. - * - * @return UserIdentity User identity. - */ - UserIdentity getUserIdentity(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthStatus.kt b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthStatus.kt deleted file mode 100644 index e178326a5..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthStatus.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.auth - -data class AuthStatus ( - val loggedIn : Boolean, - val userIdentity: UserIdentity? // Not null when logged in is true. -) - -data class UserIdentity ( - val userName : String -) \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthWorkflow.kt b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthWorkflow.kt deleted file mode 100644 index 81216d50a..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/auth/AuthWorkflow.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.auth - -enum class AuthMode { - CBL_AUTHORIZATION, - AUTH_PROVIDER_AUTHORIZATION -} - -enum class AuthState { - CBL_Auth_Not_Started, - CBL_Auth_Started, - CBL_Auth_CodePair_Received, - CBL_Auth_Token_Saved, - CBL_Auth_User_Identity_Saved, - CBL_Auth_Finished, - CBL_Auth_Start_Failed, - Auth_Provider_Request_Authorization, - Auth_Provider_Authorization_Error, - Auth_Provider_Authorization_Get_Data, - Auth_Provider_Authorization_Expired, - Auth_Provider_Authorized, - Auth_Provider_Not_Authorized, - Auth_Provider_Token_Saved, - Auth_Provider_Authorizing, - Auth_Provider_Auth_Started, - Auth_Provider_Logout, - Alexa_Client_Connected, - Alexa_Client_Disconnected, - Alexa_Client_Auth_Unintialized, - Auth_State_Refreshed -} - -data class CodePair ( - val validationUrl : String, - val validationCode : String -) - -data class AuthWorkflowData ( - val authState : AuthState, - val codePair: CodePair?, - val authMsgId: String? -) \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/communication/BluetoothDevice.kt b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/communication/BluetoothDevice.kt deleted file mode 100644 index 2cadde891..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/communication/BluetoothDevice.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.communication - -data class BluetoothDevice ( - val deviceAddress : String, - val deviceName: String, - val contactsUploadPermission: Boolean -) \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/communication/ContactsController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/communication/ContactsController.java deleted file mode 100644 index e88ba5b64..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/communication/ContactsController.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.communication; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -import io.reactivex.rxjava3.core.Observable; - -/** - * API interface to let Alexa App update/remove contacts, set contacts upload permission - * and observe contacts consent. - */ -public interface ContactsController extends ScopedComponent { - /** - * Upload contacts with device address. - * @param deviceAddress device unique address - */ - void uploadContacts(String deviceAddress); - - /** - * Remove contacts with device address. - * @param deviceAddress device unique address - */ - void removeContacts(String deviceAddress); - - /** - * Set contacts upload permission. - * @param deviceAddress device unique address - * @param permission contacts permission - */ - void setContactsUploadPermission(String deviceAddress, String permission); - - /** - * Set messaging permission. - * @param deviceAddress device unique address - * @param permission messaging permission - */ - void setMessagingPermission(String deviceAddress, String permission); - - /** - * Observe contacts upload consent. - * @return contacts consent observable, returning true if contacts consent is needed. - */ - Observable observeContactsConsent(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/login/LoginUIEventListener.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/login/LoginUIEventListener.java deleted file mode 100644 index 0c22f7e4f..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/login/LoginUIEventListener.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.login; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; -import com.amazon.alexa.auto.apis.auth.AuthMode; - -/** - * Listener interface to notify login UI events such as login finished - * event, that can be used by the app to dismiss login view and launch main - * view of the app. - */ -public interface LoginUIEventListener extends ScopedComponent { - /** - * Invoked by Login View to notify Login Host that Login is finished. - */ - void loginFinished(); - - /** - * Invoked by Login View to notify Login Host that Login is switched. - */ - void loginSwitched(AuthMode mode); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/media/MediaSourceInfo.kt b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/media/MediaSourceInfo.kt deleted file mode 100644 index ce42731c4..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/media/MediaSourceInfo.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.media - -data class MediaSourceInfo ( - var url : String, - var token: String, - var repeating: Boolean -) \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/media/PlayerInfoCache.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/media/PlayerInfoCache.java deleted file mode 100644 index 9d410aa2d..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/media/PlayerInfoCache.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.media; - -import android.content.Intent; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.amazon.alexa.auto.aacs.common.RenderPlayerInfo; - -import java.util.Optional; - -import io.reactivex.rxjava3.core.Observable; - -/** - * Cache (in memory) the most recent AudioPlayer info for the lifetime of AACS to facilitate re-populating a media - * session the right metadata if the session is destroyed and re-created within a single AACS runtime cycle. - * - * Note that it is intentionally not implemented to cache the data across reboots because Auto SDK does not yet support - * initializing AudioPlayer and TemplateRuntime capability agents with data from the last cycle. Restoring the data - * into the MediaSession without doing the same to the capability agents would produce unexpected behavior. - */ -public interface PlayerInfoCache { - /** - * Update the current RenderPlayerInfo. - * @param playerInfo The current RenderPlayerInfo. Empty Optional to reset the player info. - **/ - void setPlayerInfo(@NonNull Optional playerInfo); - - /** - * Get the current RenderPlayerInfo. - * @return An Optional. Empty optional when there is no active player metadata. - **/ - Optional getPlayerInfo(); - - /** - * Observe the current RenderPlayerInfo. - * @return An Observable of the RenderPlayerInfo. The Optional will be empty when there is no - * active player metadata. - **/ - Observable> observePlayerInfo(); - - /** - * Update the info for the current media item. - * @param url The current media info. Null to reset. - **/ - void setMediaSourceInfo(Optional info); - - /** - * Get the current media source info. - * @return An Optional. Empty optional when there is no active media item. - **/ - Optional getMediaSourceInfo(); - - /** - * Observe the current media source info. - * @return An Observable of the media source info. Optional empty when there is no active media item. - **/ - Observable> observeMediaSourceInfo(); - - /** - * Set the current position of the media buffered in the player. - * @param position The current playback position. - **/ - void setPlaybackPosition(long position); - - /** - * Get the last known position of the media buffered in the player. - * @return The last known playback position. - **/ - long getPlaybackPosition(); - - /** - * Clear all data from the cache. - **/ - void clearAllData(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/module/ModuleInterface.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/module/ModuleInterface.java deleted file mode 100644 index 3342de9ba..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/module/ModuleInterface.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.module; - -import android.content.Context; - -/** - * ModuleInterface can be utilized by features that require their specific business - * logic and UI/UX to be hosted within their own modules. - */ - -public interface ModuleInterface { - /** - * Initialize the module. - * @param context Android context. - */ - void initialize(Context context); - - /** - * Un-initialize the module. - * @param context Android context. - */ - void uninitialize(Context context); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/session/SessionActivityController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/session/SessionActivityController.java deleted file mode 100644 index 0412ccf3c..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/session/SessionActivityController.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.session; - -import androidx.fragment.app.Fragment; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -import io.reactivex.rxjava3.core.Observable; - -/** - * Component that handles getting the session activity and vending - * it out to components that want to inflate its voice fragment onto that activity. - */ -public interface SessionActivityController extends ScopedComponent { - /** - * Add voice fragment into voice session activity. - * @param fragment voice fragment - */ - void addFragment(Fragment fragment); - - /** - * Remove any existing voice fragment from voice session activity. - */ - void removeFragment(); - - /** - * Mark the current fragment as consumed but not invalidating/removing it. - */ - void consumeFragment(); - - /** - * Get voice fragment which is added into voice session activity. - * @return voice fragment - */ - Fragment getFragment(); - - /** - * Check if voice fragment has been added. - * @return true if added - */ - boolean isFragmentAdded(); - - /** - * Check if the voice fragment has been consumed. - * @return true if consumed - */ - boolean isFragmentConsumed(); - - /** - * Gets an observable that tells us if a voice fragment is inflated. - * @return an observable that informs us whether a voice fragment is inflated. - */ - Observable getFragmentAddedObservable(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/session/SessionViewController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/session/SessionViewController.java deleted file mode 100644 index 8047cb736..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/session/SessionViewController.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.session; - -import android.view.ViewGroup; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -import java.util.Optional; - -import io.reactivex.rxjava3.core.Observable; - -/** - * Component that handles getting the session view and vending - * it out to components that want to inflate onto that view. - */ -public interface SessionViewController extends ScopedComponent { - /** - * Returns whether there is a current voice interaction session active. - * @return is there is a voice interaction session active. - */ - boolean isSessionActive(); - - /** - * Sets the session view container. This should be set when a voice interaction starts - * and then set to null when the voice interaction is finished. - * @param viewGroup container of VIS session. - */ - void setSessionView(ViewGroup viewGroup); - - /** - * Returns the view container to inflate onto. Note that only one template runtime template - * will be inflated onto this container. AutoSDK handles that contract of only allowing one - * template to be shown. It will make sure to call ClearTemplate if a new template needs to - * be shown. - * @return the view container. - */ - Optional getTemplateRuntimeViewContainer(); - - /** - * Clears any existing template runtime template. - */ - void clearTemplate(); - - /** - * Gets an observable that tells us if a template runtime template is inflated. - * @return an observable that informs us whether a template runtime template is inflated. - */ - Observable getTemplateDisplayedObservable(); - - void setTemplateDisplayed(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/setup/AlexaSetupController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/setup/AlexaSetupController.java deleted file mode 100644 index 0664fc53e..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/setup/AlexaSetupController.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.setup; - -import android.content.Intent; - -import io.reactivex.rxjava3.core.Observable; - -/** - * An interface to share the setup state of Alexa as well as helpers - * to make progress in the setup process. - * - * Please note that Alexa auth state is not included in this interface. - * Use {@link com.amazon.alexa.auto.apis.auth.AuthController} to query - * and monitor the auth state. - */ -public interface AlexaSetupController { - /** - * Tells if Alexa is currently selected Voice Assistant such that - * using "Alexa" wake word will wake up Alexa and listen for user's - * request. - * - * @return true, if Alexa is currently selected voice assistant. - */ - boolean isAlexaCurrentlySelectedVoiceAssistant(); - - /** - * Start observing voice assistant selection toggle. When Alexa is selected - * as voice assistant, the observable will yield true. - * - * @return Observable for Voice Assistant Selection. - */ - Observable observeVoiceAssistantSelection(); - - /** - * Creates the intent that can be used for starting the UI that - * can be used for switching the voice assistant to Alexa. - * - * @return Intent for starting the voice assistant switch UI. - */ - Intent createIntentForLaunchingVoiceAssistantSwitchUI(); - - /** - * Creates the intent that can be used for starting the login UI. - * - * Note: To find the current auth state, obtain - * {@link com.amazon.alexa.auto.apis.auth.AuthController} using - * {@link com.amazon.alexa.auto.apis.app.AlexaApp}. - * - * @return Intent for starting the login UI. - */ - Intent createIntentForLaunchingLoginUI(); - - /** - * Tells if Alexa setup is completed and should exit setup workflow. - * - * @return true, if Alexa setup is completed - */ - boolean isSetupCompleted(); - - /** - * Set Alexa setup complete status. When Alexa setup is completed, - * the complete status will be set to be true then the step workflow will be exited. - * If user logout from the app, the Alexa setup complete status will be set to be false. - * - * @param isSetupCompleted, is Alexa setup completed. - */ - void setSetupCompleteStatus(boolean isSetupCompleted); - - /** - * Observe the readiness of AACS. - * @return AACS readiness observable, returning true if AACS is in the ENGINE_INITIALIZED state. - **/ - Observable observeAACSReadiness(); - - /** - * Set the readiness of AACS. - * @param isReady Boolean indicating whether AACS is in the ENGINE_INITIALIZED state or not. - **/ - void setAACSReadiness(boolean isReady); - - /** - * Observe the Alexa cloud connection status. - * @return Alexa cloud status observable - **/ - Observable observeAlexaCloudConnectionStatus(); - - /** - * Set the Alexa cloud connection status. - * @param isConnected Whether the app has a connection to Alexa cloud. - **/ - void setAlexaCloudConnectionStatus(boolean isConnected); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/setup/AlexaSetupWorkflowController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/setup/AlexaSetupWorkflowController.java deleted file mode 100644 index b2109bd63..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/setup/AlexaSetupWorkflowController.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.setup; - -import android.content.Context; - -import androidx.annotation.Nullable; -import androidx.navigation.NavController; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -/** - * An interface to make progress in Alexa setup. - */ -public interface AlexaSetupWorkflowController extends ScopedComponent { - /** - * Start Alexa setup workflow with Android navigation controller - * If startStepOverride is null, then use default start step from the workflow specification file. - */ - void startSetupWorkflow(Context context, NavController navController, @Nullable String startStepOverride); - - /** - * Stop Alexa setup workflow with Android navigation controller - */ - void stopSetupWorkflow(); -} diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/uxRestrictions/CarUxRestrictionStatus.kt b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/uxRestrictions/CarUxRestrictionStatus.kt deleted file mode 100644 index 0f99e8b2a..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/uxRestrictions/CarUxRestrictionStatus.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.uxRestrictions - -data class CarUxRestrictionStatus ( - val isRequiredUXRestriction : Boolean, - val actionRestriction: CarUxRestriction? -) - -data class CarUxRestriction ( - val uxRestrictionName : String -) \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/uxRestrictions/CarUxRestrictionsController.java b/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/uxRestrictions/CarUxRestrictionsController.java deleted file mode 100644 index bfa96440e..000000000 --- a/aacs/android/app-components/alexa-auto-apis/src/main/java/com/amazon/alexa/auto/apis/uxRestrictions/CarUxRestrictionsController.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.alexa.auto.apis.uxRestrictions; - -import com.amazon.alexa.auto.apis.app.ScopedComponent; - -import io.reactivex.rxjava3.core.Observable; - -/** - * API interface to let Alexa App know about the current car UX restrictions state and - * to observe car UX restriction updates. - */ -public interface CarUxRestrictionsController extends ScopedComponent { - /** - * Get active car UX restriction. - * - * @return CarUxRestriction Car UX restriction. - */ - CarUxRestriction getActiveCarUxRestriction(); - - /** - * Fetch observable that can be used to monitor the car UX restrictions changes. - * - * @return Observable of car UX restriction status. - */ - Observable observeCarUxRestrictionChanged(); - - /** - * Register listener for car UX restrictions changes. - */ - void registerListener(); - - /** - * Unregister listener for car UX restrictions changes. - */ - void unregisterListener(); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/.gitignore b/aacs/android/app-components/alexa-auto-apl-renderer/.gitignore deleted file mode 100644 index 1362fe576..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.DS_Store -.classpath -.project -*.iml - -/build diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/README.md b/aacs/android/app-components/alexa-auto-apl-renderer/README.md deleted file mode 100644 index bf5874d40..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/README.md +++ /dev/null @@ -1,185 +0,0 @@ -# Alexa Auto APL Renderer - -The Alexa Auto APL Renderer library enables the Alexa Auto App to render Amazon Presentation Language (APL) documents on the user's device. The library consists of the following components: - -* `APLReceiver`: This class receives the APL intents. After receiving an APL `RenderDocument` intent, it starts adding `APLFragment` to [VoiceActivity](https://github.com/alexa/alexa-auto-sdk/blob/master/aacs/android/app-components/alexa-auto-voice-ui/src/main/java/com/amazon/alexa/auto/voice/ui/VoiceActivity.java) or sends the `APLDirective` event to `APLFragment`. - -* `APLHandler`: This class initializes `APLPresenter`, set `APLLayout` in `APLPresenter` when the layout is inflated. This class also handles APL intents, such as those for rendering or clearing APL documents. It also executes APL commands and implements an event interface named `IAPLEventSender`, which reports events to Alexa or the capability agent. - -* `APLFragment`: This class inflates the APL layout to render the APL document. The `APLLayout` object in [fragment_apl.xml](https://github.com/alexa/alexa-auto-sdk/blob/master/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/layout/fragment_apl.xml) defines the layout. This class also calls the `APLhandler` methods to handle APL intents. - -## Prerequisites for Using the Alexa Auto APL Renderer Library -The APL Renderer library for the Alexa Auto App depends on the capabilities provided by an Auto SDK module called APL Render module. For example, the APL Render module provides the `APLPresenter` class implementation. The Alexa Auto APL Renderer library initializes this class to provide the orchestration logic in the APL rendering process. - -For information about how to build the APL Render module, see the [APL Render documentation](./modules/apl-render/README.md). - -## Using Alexa Auto APL Renderer Library with Alexa Auto App -To use the Alexa Auto APL Renderer Library with the Alexa Auto App, include the appropriate build dependency, fonts package and configure APL in the Alexa Auto App. - -### Including Build Dependency (AAR) - -The Alexa Auto APL Renderer library requires a prebuilt Android view host, which is available as an AAR on the developer portal. To download the AAR, contact your Solutions Architect (SA) or Partner Manager. - ->**Note:** To include the build dependency, you must place the Android view host AAR in the [modules/apl-render/src/main/libs/](./modules/apl-render/src/main/libs) folder of the APL Render module. - -``` -apl-render -└── src - └── main - └── libs - ├── aplRelease.aar - └── ttsplayerRelease.aar -``` - -### Including Fonts Package - -The Alexa Auto APL Renderer library requires a fonts package, which is available as a zip file on the developer portal. To download the fonts package, contact your Solutions Architect (SA) or Partner Manager. - ->**Note:** The fonts package must be unzipped under the [modules/apl-render/src/main](./modules/apl-render/src/main) folder. For example, `unzip fonts.zip -d modules/apl-render/src/main` within the `alexa-auto-apl-render` app component. - -``` -apl-render -└── src - └── main - └── res - └── font - ├── bookerly.xml - ├── bookerly_lcd_bd.ttf - ├── bookerly_lcd_bd_it.ttf - ├── bookerly_lcd_it.ttf - ├── bookerly_lcd_lt.ttf - ├── bookerly_lcd_lt_it.ttf - └── bookerly_lcd_rg.ttf -``` -### Configuring APL in Alexa Auto App - -The Alexa Auto App uses `aacs_config.json` for configuring the Auto SDK. Follow these steps to enable APL and specify the display format: - -1. Enable APL under the `aacs.apl` configuration node as follows: - - ```json - "aacs.modules": { - "aacs.apl": { - "APL": { - "enabled": true - } - } - } - ``` - -2. Add the `gui` configuration node in `aacs.alexa`, as shown in the following example: - - ```json - { - "aacs.alexa": { - "gui": { - "visualCharacteristics": [ - { - "type": "AlexaInterface", - "interface": "Alexa.InteractionMode", - "version": "1.1", - "configurations": { - "interactionModes": [ - { - "id": "apl-interaction-id", - "uiMode": "AUTO", - "interactionDistance": { - "unit": "INCHES", - "value": 24 - }, - "touch": "SUPPORTED", - "keyboard": "SUPPORTED", - "video": "SUPPORTED", - "dialog": "SUPPORTED" - } - ] - } - }, - { - "type": "AlexaInterface", - "interface": "Alexa.Presentation.APL.Video", - "version": "1.0", - "configurations": { - "video": { - "codecs": [ - "H_264_42", - "H_264_41" - ] - } - } - }, - { - "type": "AlexaInterface", - "interface": "Alexa.Display.Window", - "version": "1.0", - "configurations": { - "templates": [ - { - "id": "apl-window-id", - "type": "STANDARD", - "configuration": { - "sizes": [ - { - "type": "DISCRETE", - "id": "window-size-id", - "value": { - "unit": "PIXEL", - "value": { - "width": 900, - "height": 1200 - } - } - } - ], - "interactionModes": [ - "apl-interaction-id" - ] - } - } - ] - } - } - ] - } - } - } - ``` - -For descriptions of the visual characteristic parameters, see the [Alexa Smart Screen SDK documentation](https://github.com/alexa/alexa-smart-screen-sdk/blob/master/modules/GUI/config/SmartScreenSDKConfig.md#visual-characteristics-parameters). - -#### APL Viewport - -The APL viewport refers to the UI screen area where APL will be rendered. The width and height pixel values defined in the `Alexa.Display.Window` configuration define the dimensions APL viewport. That configuration is also uploaded to the cloud so that Alexa skills have knowledge of the APL viewport dimensions. Make sure that the configuration is as accurate as possible in order to provide the best APL experience. - -The table below lists the supported APL viewport sizes. Your configuation must define values that fall within the -range of values listed on the table. - -|Profile |type |shape |mode |minWidth (dp)|maxWidth (dp)|minHeight (dp)|maxHeight (dp)| -|----------------|--------|-------------------|-----|-------------|-------------|--------------|--------------| -|Auto Extra Small|standard| overlay/rectangle |auto | 400 | 599 | 480 | 1279| -|Auto Small |standard| overlay/rectangle |auto | 600 | 959 | 480 | 1279| -|Auto Medium |standard| overlay/rectangle |auto | 960 | 1279 | 480 | 1279| - ->**Note:** APL viewports are defined using dependent pixels (`dp`) but the `Alexa.Display.Window` dimensions must be specified in pixels (`px`). To convert from `dp` to `px` use the formula `px = (dpi/160) * dp`. For example, to define an Auto Medium APL viewport with dimensions 1200 (width `dp`) x 960 (height `dp`) on a device with 240 screen dpi, the values would map to `width (px) = (240/160) * 1200 = 1800` and `height (px) = (240/160) * 960 = 1440`. - -### Using Alexa Auto App - -After the gradle build command finishes building the Alexa Auto App, you can test the sample app by asking, "Alexa, tell me a joke." An APL document is rendered on the device. - -The Auto SDK 4.0 enables the ability to report the vehicle driving state to provide safer visual experiences while the vehicles is moving. To enable the driving state support, add `-PenabledUXRestrictions` to the build command. When you say "Alexa, show coffee shops near me" and view the details for a point of interest, the data displayed in the APL detail card will contain more information while the driving state is `parked`. Additionally, the Auto SDK 4.0 supports the ability to report the light conditions around the vehicle to support day/night mode and provide a custom theme id to alter the look and feel of the APL experience. - ->**Note:** The alexa-auto-ux-restrictions requires Android API level 29. Provide your own implementation for the `CarUxRestrictionsController` interface if your device uses API level less than 29. By default, the driving state will always be set to `moving` if the `CarUxRestrictionsController` is not implemented. - -## Known Issues -* When interrupting music playback with APL utterance, APL card will be dismissed when music playback resumes, this issue could not be seen if music ducking support is enabled in Alexa Auto App. To do this, add audio ducking node in `aacs.alexa`, as shown in the following example: - ``` - "aacs.alexa": { - "audio": { - "audioOutputType.music": { - "ducking":{ - "enabled": true - } - } - } - } - ``` diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/build.gradle b/aacs/android/app-components/alexa-auto-apl-renderer/build.gradle deleted file mode 100644 index b6bdef5a0..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/build.gradle +++ /dev/null @@ -1,88 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion 32 - defaultConfig { - minSdkVersion 27 - targetSdkVersion 27 - versionCode Integer.parseInt(new Date().format("yyyyMMdd")) - versionName "4.2" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - debug { - testCoverageEnabled true - debuggable true - } - } - - testOptions { - // Unit Test: Make all android methods return true by default - unitTests.returnDefaultValues = true - unitTests.includeAndroidResources = true - } - - compileOptions { - targetCompatibility 1.8 - sourceCompatibility 1.8 - } - - libraryVariants.all { variant -> - variant.outputs.all { - def project = "alexa-auto-apl-renderer" - def separator = "_" - def buildType = variant.buildType.name - def apkName = project + separator + buildType + ".aar" - outputFileName = file(apkName).name - } - } -} - -dependencies { - implementation(name:'aplRelease', ext:'aar') - implementation(name:'ttsplayerRelease', ext:'aar') - - implementation project(':alexa-auto-apl-renderer:apl-render') - implementation project(':aacscommonutils') - implementation project(':aacsipc') - implementation project(':aacsconstants') - implementation project(':alexa-auto-apis') - implementation project(":alexa-auto-apps-common-util") - implementation project(":alexa-auto-navigation") - implementation project(':alexa-auto-voice-interaction') - - implementation deps.androidx_appcompat - implementation deps.eventbus - - testImplementation deps.junit - testImplementation deps.mockito - testImplementation deps.mockito_inline - testImplementation deps.androidx_test_core - testImplementation deps.androidx_arch_core_testing - testImplementation deps.roboelectric - - implementation deps.android_appcompat - implementation deps.android_design - implementation deps.android_constraint - implementation deps.android_cardview - implementation deps.android_recyclerview - implementation deps.okhttp - - api deps.google_guava - - // Glide - implementation deps.glide - annotationProcessor deps.glide_compiler - - // RX - implementation deps.rxjava3 - - // Dagger - implementation 'com.google.dagger:dagger-android:2.33' - implementation 'com.google.dagger:dagger-android-support:2.33' - annotationProcessor 'com.google.dagger:dagger-android-processor:2.33' - annotationProcessor 'com.google.dagger:dagger-compiler:2.33' -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/gradle.properties b/aacs/android/app-components/alexa-auto-apl-renderer/gradle.properties deleted file mode 100755 index 017b79adb..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/gradle.properties +++ /dev/null @@ -1,15 +0,0 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -android.enableJetifier=true -android.useAndroidX=true \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/.gitignore b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/.gitignore deleted file mode 100644 index d92c92768..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -src/main/libs/* -build/ -local.properties diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/README.md b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/README.md deleted file mode 100644 index e8bfd1646..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/README.md +++ /dev/null @@ -1,290 +0,0 @@ -# APL Render Module - -The APL Render module is an Android library that enables Alexa Presentation Language (APL) rendering capabilities in an Android application. For detailed information about APL, see the [APL documentation](https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/understand-apl.html). - - -## Table of Contents -- [Overview](#overview) -- [Understanding Android View Host](#understanding-android-view-host) -- [APL Render Module Functionality](#apl-render-module-functionality) -- [How to use the APL Render Module](#how-to-use-the-apl-render-module) - - [Defining the APL Layout](#defining-the-apl-layout) - - [Initializing the APL Runtime](#initializing-the-apl-runtime) - - [Implementing the Event Interface](#implementing-the-event-interface) - - [Instantiating APLPresenter](#instantiating-aplpresenter) -- [Rendering an APL Document](#rendering-an-apl-document) -- [Overriding Android View Host Options](#overriding-android-view-host-options) - - [Using APLOptions.Builder](#using-aploptionsbuilder) -- [APL Runtime Properties](#apl-runtime-properties) - - [Driving State](#driving-state) - - [Theme](#theme) -- [APL Extensions](#apl-extensions) - - [Backstack](#backstack) - - [Local Information Data](#local-information-data) - - [ILocalInfoDataConsumer](#ilocalinfodataconsumer) - - [ILocalInfoDataReporter](#ilocalinfodatareporter) -- [Building the APL Render Library](#building-the-apl-render-library) - -## Overview -Rendering an APL document on a device requires the implementation of various components and the logic that makes the components work together. To handle APL-related directives and events, the device must support APL interfaces. It needs integration of the [APL Core Library](https://github.com/alexa/apl-core-library) to manage the document parsing and rendering workflow. - -In addition, you must build a view host for the device to render the APL document on the screen, as well as provide components to download layouts, images, and other resources. If the APL document generates multimedia content, such as a video or audio file, you need a media player to play back the content. Lastly, APL rendering needs the orchestration logic to manage the lifecycle of a rendered document, which includes user events, audio focus management, time out management, visual context, command execution, and much more. The Alexa Auto SDK, with the APL Render module and a prebuilt Android view host, simplifies the process of APL rendering because it provides the aforementioned components and logic for you. - -## Understanding Android View Host - -The Android view host is the component responsible for rendering APL on the screen. Amazon provides a prebuilt Android view host as an Android Archive Library (AAR) on the developer portal. To download the AAR, contact your Solutions Architect (SA) or Partner Manager. - ->**Note:** To use the Android Render module, you must place the Android view host AAR in the [src/main/libs/](./src/main/libs) folder of the APL Render module. - -## APL Render Module Functionality - -The APL Render module provides all the functionality needed for enabling APL rendering capabilities in an Android application. The APL Render module provides the following capabilities: - -* APL runtime initialization -* HTTP Resource downloader -* Android view host integration -* Android audio focus management -* Activity tracking for timeout management -* Audio and media players -* Interfaces to easily override functionality - -## How to use the APL Render Module - -To use the APL Render module without customization, follow these steps: - -1. Define the APL layout. -2. Initialize the APL runtime. -3. Implement the event interface. -4. Instantiate `APLPresenter`. - -### Defining the APL Layout - -The application must define the layout of the screen on which the APL document is rendered. the width and height of the `APLLayout` must fall in range with one of the three supported [automotive viewport profiles](https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-alexa-viewport-profiles-package.html): auto extra small, auto small, and auto medium. Define an `com.amazon.apl.android.APLLayout` object, as shown in the following example, where the object is defined under `res/layout`: - -```java - - - - - - -``` - -The `app:aplTheme` field corresponds to the default [APL theme](https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-viewport-property.html#theme) to be used if one is not specified in the APL document. Typical values are `light` or `dark`. - -The `app:mode` field specifies the operating mode, which is a [viewport property](https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-viewport-property.html#viewport_mode_property). For information about the viewport object, see the [viewport documentation](https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-viewport-property.html). The value for this field should be `auto` for an Automotive device. - -### Initializing the APL Runtime - -The application must invoke the `APLPresenter.initialize()` static method before inflating the `APLLayout` UI component. The following code shows how to use the `onCreate` method of `Activity` to initialize the APL runtime: - -```java -import com.amazon.apl.android.render.APLPresenter; - -//--------------------------------------------------------------------- -// Initialize the APL Runtime. This must be called during -// Activity.onCreate() or prior to APLLayout inflation. -//--------------------------------------------------------------------- -onCreate() { - Context context = getApplicationContext(); - APLPresenter.initialize(context); -} -``` - -### Implementing the Event Interface - -The application must implement the `com.amazon.apl.android.render.interfaces.IAPLEventSender` interface. The `IAPLEventSender` interface provides the APIs to allow the APL Render module to report events to Alexa or the capability agent. You can integrate the event interface into the APL handler that implements the Auto SDK `APL` AASB message interface. The following code shows how to do the integration: - -```java -import com.amazon.aace.apl.APL; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; - -public class APLHandler extends APL implements IAPLEventSender { - - //--------------------------------------------------------------------- - // Override IAPLEventSender methods. - // APLHandler will register with APL Render library as the event sender. - //--------------------------------------------------------------------- - @Override - public void sendRenderDocumentResult(String token, boolean result, String error) { - renderDocumentResult(token, result, error); // APL::renderDocumentResult - } - - @Override - public void sendExecuteCommandsResult(String token, boolean result, String error) { - executeCommandsResult(token, result, error); // APL::executeCommandsResult - } - - ... -} - -``` - -### Instantiating APLPresenter - -The application must instantiate the `APLPresenter` object, which provides the orchestration logic in the APL rendering process. - ->**Note:** Create `APLPresenter` *after* the APL platform interface handler is registered with the Auto SDK Engine. - -The following code shows how to instantiate the `APLPresenter` object: - -```java -import com.amazon.apl.android.render.APLPresenter; - -public class APLHandler extends APL implements IAPLEventSender { - - private APLPresenter mPresenter; - - public void buildAPLPresenter(JSONArray visualCharacteristics, String defaultWindowId) { - //--------------------------------------------------------------------- - // Retrieve the APLLayout view with id 'apl' defined in apl_view.xml. - // This assumes that 'activity' is the application's Activity. - //--------------------------------------------------------------------- - aplLayout = activity.findViewById(R.id.apl); - //--------------------------------------------------------------------- - // Application needs to handle the correlation of window ids from the - // visual characteristics configuration to the APLLayout instance. - //--------------------------------------------------------------------- - HashMap aplLayouts = new HashMap(); - aplLayouts.put(defaultWindowId, mAplLayout); - //--------------------------------------------------------------------- - // Create APLPresenter to handle APL rendering. - //--------------------------------------------------------------------- - mPresenter = new APLPresenter(aplLayouts, visualCharacteristics, defaultWindowId, this); - } -``` - -The following list describes the parameters to `APLPresenter`: - -* The first parameter is a map of the `APLLayout` objects. Each `APLLayout` is identified by a window ID, which specifies the window where the APL document is rendered. Typically, there is one `APLLayout` defined for the window where all the APL documents are rendered, but you can build skills that support rendering in multiple windows. - -* The second parameter is a JSON array` pointing to the visual characteristics defined by the device. For more information about visual characteristics, see the Auto SDK APL module documentation and the [Smart Screen SDK documentation](https://github.com/alexa/alexa-smart-screen-sdk/blob/master/modules/GUI/config/SmartScreenSDKConfig.md#visual-characteristics-parameters). - -* The third parameter is the default window ID, specifying the window where APL documents are rendered if Alexa does not provide a window ID. - -* The last parameter is the object that implements the `IAPLEventSender` interface. - -## Rendering an APL Document - -To render an APL document, call the `onRenderDocument` API on the `APLPresenter`. The `APLHandler` can delegate the `APL` APIs to the `APLPresenter`, as shown in the following code: - -```java -public class APLHandler extends APL implements IAPLEventSender { - - ... - - //--------------------------------------------------------------------- - // Override Auto SDK APL interfaces - //--------------------------------------------------------------------- - @Override - public void renderDocument(String payload, String token, String windowId) { - mAplPresenter.onRenderDocument(payload, token, windowId); // APLRender implements these interfaces - } - - @Override - public void executeCommands(String payload, String token) { - mPresenter.onExecuteCommands(payload, token); - } - - ... -} -``` - -## Overriding Android View Host Options - -Rendering an APL document requires the APL Render module to set up an `APLOptions` object, which is passed to the view host. The `APLOptions` object is configured with providers, callbacks, and listeners, as described in the following list: - -* Providers are objects implemented outside the view host.They provide objects used during the rendering process. For example, the data retriever provider downloads APL resources, such as layouts from content delivery networks (CDNs). The media player provider plays media, such as videos. - -* Callbacks are interfaces used by the view host to report events, such as: - - * user events (e.g., button clicks) - * document lifecycle events (e.g., completion of document rendering) - -* Listeners are interfaces for reporting the APL rendered document state or screen lock events. - -The APL Render module sets up all the providers, callbacks, and listeners. If the application needs to override any of them, it uses the `APLOptions.Builder` object. - -### Using APLOptions.Builder - -To override `APLOptions`, extend the `APLPresenter` object, as shown in the following code: - -```java -class MyAPLPresenter extends APLPresenter { - - //--------------------------------------------------------------------- - // IAPLOptionsBuilderProvider override - //--------------------------------------------------------------------- - @Override - APLOptions.Builder getAPLOptionsBuilder() { - APLOptions.Builder builder = super.getAPLOptionsBuilder(); - // Listen in on APL finish callback - builder.onAplFinishCallback(() -> { - // Do something here - super.onAplFinish(); - }); - return builder; - } -} -``` -## APL Runtime Properties - -The [`IAPLContentListener`](https://github.com/alexa/alexa-auto-sdk/blob/master/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLContentListener.java) exposes an interface to control some APL runtime properties that affect how APL documents are rendered. The `onAPLRuntimeProperties` API takes in a JSON string that contains one or more properties to update. - -### Driving State - -The `drivingState` property supports the values `moving` and `parked`. An APL experience may differ depending on the driving state in order to provide a safer driving experience. - -### Theme - -The `theme` property allows the APL experience to render in different color schemes. There are six supported values: light, light-gray1, light-gray2, dark, dark-black, dark-gray. The light themes can be during for day driving, while the dark themes can be used for night driving. -## APL Extensions -### Backstack - -This library supports the [Backstack](https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-ext-backstack.html) extension. The application must ensure that the `APLPresenter` is not destroyed and recreated when a new APL document with the same token id is received. Otherwise, the Backstack will be reinstantiated and the previous stack of documents will be lost. - -### Local Information Data - -This library contains a custom APL extension that is used by the `APLPresenter` to expose point of interest data to the application. This data can be used to drop corresponding pins on the head unit's integrated map. Two way communication is also provided so that the application or AP runtime can notify each other when a specific data point is active or selected. - -There are two interfaces that the application can use to interact with Local information data: [ILocalInfoDataConsumer](https://github.com/alexa/alexa-auto-sdk/tree/4.0/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/ILocalInfoDataConsumer.java) and [ILocalInfoDataReporter](https://github.com/alexa/alexa-auto-sdk/tree/4.0/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/ILocalInfoDataReporter.java). - -#### ILocalInfoDataConsumer - -The `IPresenter` (`https://github.com/alexa/alexa-auto-sdk/blob/master/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IPresenter.java`) interface exposes a method to set the data consumer, which must be set by the application: - -``` - /** - * Saves a reference to the local info data consumer. - * - * @param consumer The object that consume local info data events. - */ - void setLocalInfoDataConsumer(ILocalInfoDataConsumer consumer); -``` - -The application will be notified through the consumer method `aplDataAvailable` with a JSON string object represention all the points of interest. The application will be notified when a specific data point is selected on the APL document using the consume method `aplDataItemSelectedById`. - -#### ILocalInfoDataReporter - -The `APLPresenter` implements the `ILocalInfoDataReporter` interface to allow the application to notify the APL runtime when a data point is selected outside of the APL runtime. To do this notification simply call `platformDataItemSelectedById` on the `APLPresenter` instance. - -## Building the APL Render Library -**Note:** Before proceeding to build the APL Render library, download the Android APL resource from the developer portal according to instructions from your Solutions Architect or Partner Manager. - -This library can be built using the included gradle wrapper as follows -``` -./gradlew assembleRelease -``` \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/build.gradle b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/build.gradle deleted file mode 100644 index cb99dd131..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/build.gradle +++ /dev/null @@ -1,77 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion 28 - - defaultConfig { - minSdkVersion 22 - targetSdkVersion 28 - versionCode Integer.parseInt(new Date().format("yyyyMMdd")) - versionName "4.2" - buildConfigField 'int', 'VERSION_CODE', "1" - buildConfigField 'String', 'VERSION_NAME', "\"4.2\"" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - - // Enable desugaring (dependency contains Java 8 bytecode) - compileOptions { - sourceCompatibility 1.8 - targetCompatibility 1.8 - } - - lintOptions { - abortOnError false - } -} - -buildscript { - repositories { - google() - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -dependencies { - compileOnly files('src/main/libs/aplRelease.aar') - compileOnly files('src/main/libs/ttsplayerRelease.aar') - - implementation 'androidx.media:media:1.3.0' - implementation 'androidx.appcompat:appcompat:1.0.0' - implementation 'com.google.android.material:material:1.0.0' - implementation 'androidx.annotation:annotation:1.0.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'androidx.cardview:cardview:1.0.0' - implementation 'androidx.recyclerview:recyclerview:1.0.0' - implementation 'com.google.android.exoplayer:exoplayer-core:2.13.3' - implementation 'com.google.android.exoplayer:exoplayer-dash:2.13.3' - implementation 'com.google.android.exoplayer:exoplayer-smoothstreaming:2.13.3' - implementation 'com.google.android.exoplayer:exoplayer-hls:2.13.3' - implementation 'com.google.android.gms:play-services-maps:16.0.0' - implementation 'com.github.bumptech.glide:glide:4.11.0' - implementation 'androidx.fragment:fragment:1.2.4' - implementation 'com.squareup.okhttp3:okhttp:3.9.1' - implementation 'com.google.dagger:dagger:2.33' - implementation 'com.google.guava:guava:27.0.1-android' - - compileOnly 'org.projectlombok:lombok:1.18.18' - - annotationProcessor 'com.google.dagger:dagger-compiler:2.33' - annotationProcessor 'org.projectlombok:lombok:1.18.18' - -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/gradle.properties b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/gradle.properties deleted file mode 100644 index 938b16188..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -android.useAndroidX=true -android.enableJetifier=true - diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/lombok.config b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/lombok.config deleted file mode 100644 index 41718e05e..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/lombok.config +++ /dev/null @@ -1,5 +0,0 @@ -lombok.anyConstructor.suppressConstructorProperties = true -lombok.nonNull.exceptionType = IllegalArgumentException -lombok.addGeneratedAnnotation = false -lombok.accessors.prefix += m -lombok.getter.noIsPrefix = true \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/proguard-rules.pro b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/proguard-rules.pro deleted file mode 100644 index f1b424510..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/settings.gradle b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/settings.gradle deleted file mode 100644 index 015e7058a..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':apl-render' diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/AndroidManifest.xml b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/AndroidManifest.xml deleted file mode 100644 index 100b61f10..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/APLPresenter.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/APLPresenter.java deleted file mode 100644 index 19522e9c9..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/APLPresenter.java +++ /dev/null @@ -1,870 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render; - -import android.content.Context; -import android.util.Log; -import android.view.KeyEvent; -import android.view.MotionEvent; - -import androidx.annotation.NonNull; -import androidx.core.util.Preconditions; - -import com.amazon.apl.android.APLController; -import com.amazon.apl.android.APLLayout; -import com.amazon.apl.android.APLOptions; -import com.amazon.apl.android.Action; -import com.amazon.apl.android.Content; -import com.amazon.apl.android.IAPLViewPresenter; -import com.amazon.apl.android.RootConfig; -import com.amazon.apl.android.RootContext; -import com.amazon.apl.android.RuntimeConfig; -import com.amazon.apl.android.bitmap.GlideCachingBitmapPool; -import com.amazon.apl.android.bitmap.IBitmapCache; -import com.amazon.apl.android.bitmap.IBitmapPool; -import com.amazon.apl.android.bitmap.LruBitmapCache; -import com.amazon.apl.android.configuration.ConfigurationChange; -import com.amazon.apl.android.dependencies.IDataSourceErrorCallback; -import com.amazon.apl.android.dependencies.IDataSourceFetchCallback; -import com.amazon.apl.android.dependencies.ISendEventCallback; -import com.amazon.apl.android.dependencies.IVisualContextListener; -import com.amazon.apl.android.render.content.APLHttpContentRetriever; -import com.amazon.apl.android.render.dagger.component.ActivityComponent; -import com.amazon.apl.android.render.dagger.component.ApplicationComponent; -import com.amazon.apl.android.render.dagger.component.DaggerActivityComponent; -import com.amazon.apl.android.render.dagger.module.ActivityModule; -import com.amazon.apl.android.render.extension.ExtensionManager; -import com.amazon.apl.android.render.extension.back.BackExtension; -import com.amazon.apl.android.render.extension.back.BackStack; -import com.amazon.apl.android.render.extension.back.BackStackDocument; -import com.amazon.apl.android.render.extension.localinfo.LocalInfoExtension; -import com.amazon.apl.android.render.font.AutoEmbeddedFontResolver; -import com.amazon.apl.android.render.interfaces.IAPLContentListener; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; -import com.amazon.apl.android.render.interfaces.IAPLTokenProvider; -import com.amazon.apl.android.render.interfaces.IDismissible; -import com.amazon.apl.android.render.interfaces.ILocalInfoDataConsumer; -import com.amazon.apl.android.render.interfaces.ILocalInfoDataReporter; -import com.amazon.apl.android.render.interfaces.IPresenter; -import com.amazon.apl.android.render.payload.ExecuteCommandPayload; -import com.amazon.apl.android.render.payload.RenderDocumentPayload; -import com.amazon.apl.android.render.payload.RenderedDocumentStatePayload; -import com.amazon.apl.android.render.payload.UserEventPayload; -import com.amazon.apl.android.render.utils.RenderDocumentUtils; -import com.amazon.apl.android.scaling.Scaling; -import com.amazon.apl.enums.ViewportMode; -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * This class facilitates the integration of Alexa Presentation Language (APL). - * The application is required to initialize the APL runtime by passing the Android - * context to @see initialize(context) prior to the inflation of @see APLLayout components. - * The visual configuration is used to provide window state context. - */ -public class APLPresenter implements IPresenter, ISendEventCallback, IDataSourceFetchCallback, IDataSourceErrorCallback, - IVisualContextListener, IAPLTokenProvider, ILocalInfoDataReporter { - private static final String TAG = APLPresenter.class.getSimpleName(); - - private IAPLEventSender mAplEventSender; - private Map mAplLayouts; - private Action mAction; - private APLController mAplController; - private String mToken; - private APLOptions mAplOptions; - private ActivityComponent mActivityComponent; - private ApplicationComponent mApplicationComponent; - private RenderDocumentPayload mRenderDocumentPayload; - private RenderedDocumentStatePayload mLatestRenderedDocumentState; - private String mDefaultWindowId; - private JSONArray mVisualCharacteristics; - private Hashtable mRuntimeProperties; - private ExtensionManager mExtensionManager; - private LocalInfoExtension mLocalInfoExtension; - private BackExtension mBackHandler; - private BackStack mBackStack; - private ILocalInfoDataConsumer mLocalInfoDataConsumer; - private IDismissible mDismissibleCallback; - - private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); - private static Context mContext; - private RootConfig mRootConfig; - - /** - * Initialize the APL runtime. Must be done during Activity onCreate or - * prior to inflation of APLLayout view. - * - * @param context - */ - public static void initialize(Context context) { - mContext = context; - - BitmapPool glideBitmapPool = Glide.get(mContext).getBitmapPool(); - IBitmapPool pool = new GlideCachingBitmapPool(glideBitmapPool); - IBitmapCache cache = new LruBitmapCache((int) glideBitmapPool.getMaxSize()); - RuntimeConfig runtimeConfig = RuntimeConfig.builder() - .bitmapPool(pool) - .bitmapCache(cache) - .fontResolver(new AutoEmbeddedFontResolver(context)) - .preloadingFontsEnabled(true) - .build(); - - APLController.initializeAPL(context, runtimeConfig); - } - - /** - * @deprecated - * - * Constructs the APLPresenter object. - * - * @param aplLayouts A map of windows ids to the corresponding APL layouts. - * @param visualCharacteristics The array of defined visual characteristics for the device. - * @param defaultWindowId The Id of the window where APL will be rendered if one is not specified in the render - * document request. - * @param aplEventSender The object used to send events back to the cloud. - */ - public APLPresenter(@NonNull final Map aplLayouts, @NonNull JSONArray visualCharacteristics, - @NonNull String defaultWindowId, @NonNull final IAPLEventSender aplEventSender) - throws IllegalStateException { - // Initialize must be called prior to instantiation of this class. - if (mContext == null) { - throw new IllegalStateException("Context is null. Make sure initialize() is called with non null context."); - } - - Preconditions.checkNotNull(aplLayouts); - Preconditions.checkNotNull(visualCharacteristics); - Preconditions.checkNotNull(defaultWindowId); - Preconditions.checkState(!defaultWindowId.isEmpty()); - Preconditions.checkNotNull(aplEventSender); - - mAplLayouts = aplLayouts; - mVisualCharacteristics = visualCharacteristics; - mAplEventSender = aplEventSender; - mDefaultWindowId = defaultWindowId; - APLSingleton.getInstance().init(mContext, mAplEventSender, this); - mApplicationComponent = APLSingleton.getInstance().getApplicationComponent(); - mActivityComponent = initActivityComponent(mContext); - mBackStack = new BackStack(); - - // Default property values - mRuntimeProperties = new Hashtable<>(); - mRuntimeProperties.put("drivingState", "moving"); - mRuntimeProperties.put("theme", "dark"); - mRuntimeProperties.put("video", "disabled"); - - // Initial window state - sendDeviceWindowState(); - - // Listen for touch events - setupTouchListener(); - } - - /** - * Constructs the APLPresenter object. - * - * @param visualCharacteristics The array of defined visual characteristics for the device. - * @param defaultWindowId The Id of the window where APL will be rendered if one is not specified in the render - * document request. - * @param aplEventSender The object used to send events back to the cloud. - */ - public APLPresenter(@NonNull JSONArray visualCharacteristics, @NonNull String defaultWindowId, - @NonNull final IAPLEventSender aplEventSender) throws IllegalStateException { - // Initialize must be called prior to instantiation of this class. - if (mContext == null) { - throw new IllegalStateException("Context is null. Make sure initialize() is called with non null context."); - } - - Preconditions.checkNotNull(visualCharacteristics); - Preconditions.checkNotNull(defaultWindowId); - Preconditions.checkState(!defaultWindowId.isEmpty()); - Preconditions.checkNotNull(aplEventSender); - - mVisualCharacteristics = visualCharacteristics; - mAplEventSender = aplEventSender; - mDefaultWindowId = defaultWindowId; - APLSingleton.getInstance().init(mContext, mAplEventSender, this); - mApplicationComponent = APLSingleton.getInstance().getApplicationComponent(); - mActivityComponent = initActivityComponent(mContext); - mBackStack = new BackStack(); - - // Default property values - mRuntimeProperties = new Hashtable<>(); - mRuntimeProperties.put("drivingState", "moving"); - mRuntimeProperties.put("theme", "dark"); - mRuntimeProperties.put("video", "disabled"); - - // Initial window state - sendDeviceWindowState(); - } - - public void setAPLLayout(@NonNull final Map aplLayouts) { - Preconditions.checkNotNull(aplLayouts); - mAplLayouts = aplLayouts; - - setupTouchListener(); - } - - private synchronized void updateRuntimeProperties() { - Log.v(TAG, "updateRuntimeProperties" + mRuntimeProperties.toString()); - if (mAplController != null) { - APLLayout aplLayout = getAplLayout(); - if (aplLayout != null) { - aplLayout.post(() -> { - Map autoEnvironmentValues = new HashMap<>(); - autoEnvironmentValues.put("drivingState", mRuntimeProperties.get("drivingState")); - ConfigurationChange configurationChange = - aplLayout.createConfigurationChange() - .theme(mRuntimeProperties.get("theme")) - .disallowVideo(mRuntimeProperties.get("video").equalsIgnoreCase("disabled")) - .environmentValue("automobile", autoEnvironmentValues) - .build(); - try { - aplLayout.handleConfigurationChange(configurationChange); - Log.v(TAG, "onConfigChange succeeded"); - } catch (Exception e) { - Log.e(TAG, "Document cannot be rendered in this configuration", e); - } - }); - } - } - } - - //------------------------------------------------------------------------- - // IAPLContentListener - //------------------------------------------------------------------------- - - /** - * Application will notify of APL content through this listener. Content includes - * render document payload, execute commands, data source updates, etc. - * - * @return IAPLContentListener The object that listens for APL content. - */ - public IAPLContentListener getAPLContentListener() { - return this; - } - - /** - * Handle updates from the vehicle that affect how the APL document - * should be rendered. - * - * @param properties JSON string containing one or more properties. - */ - @Override - public void onAPLRuntimeProperties(String properties) { - try { - JSONObject propertiesObject = new JSONObject(properties); - if (propertiesObject.has("drivingState")) { - mRuntimeProperties.put("drivingState", propertiesObject.getString("drivingState").toLowerCase()); - } - - if (propertiesObject.has("theme")) { - mRuntimeProperties.put("theme", propertiesObject.getString("theme").toLowerCase()); - } - - if (propertiesObject.has("video")) { - mRuntimeProperties.put("video", propertiesObject.getString("video").toLowerCase()); - } - - updateRuntimeProperties(); - } catch (JSONException e) { - Log.e(TAG, "propertiesJSONError"); - } - } - - @Override - public void onRenderDocument(String jsonPayload, String token, String windowId) { - try { - mToken = token; - // Extract document and data - mRenderDocumentPayload = RenderDocumentUtils.convertToRenderDocument(jsonPayload); - mRootConfig = mActivityComponent.getRootConfig(); - - Log.i(TAG, "APL render document token: " + mToken + " windowId: " + mRenderDocumentPayload.getWindowId()); - - // Set up content retriever and render callback - APLHttpContentRetriever contentRetriever = - new APLHttpContentRetriever(mApplicationComponent.getOkHttpClientWrapper(), - mApplicationComponent.getNetworkExecutor(), mRenderDocumentPayload); - contentRetriever.addCompleteCallback(content -> doRender(content)); - - // Inflate the document - try { - Content.create(mRenderDocumentPayload.getDocument(), contentRetriever); - } catch (Content.ContentException exception) { - Log.e(TAG, exception.getMessage()); - } - } catch (Exception e) { - Log.e(TAG, e.getMessage()); - renderResponse(token, false, e.getMessage()); - } - } - - @Override - public void onClearDocument(String token) { - Log.i(TAG, "clearDocument and visual context " + token + " mToken: " + mToken); - getAplLayout().post(() -> { - // Clean up current view - destroyAplView(); - // Clear back stack since skill session is done - mBackStack.clear(); - // Notify that clear document is done - mExecutor.submit(() -> { - Log.i(TAG, "Clearing card: token: " + token); - mLatestRenderedDocumentState = null; - mRenderDocumentPayload = null; - mToken = null; - sendDeviceWindowState(); - mAplEventSender.sendClearCard(); - }); - }); - } - - @Override - public void onExecuteCommands(String payload, String token) { - mToken = token; - getAplLayout().post(() -> { - try { - // Log payload and token - Log.v(TAG, "onExecuteCommands: payload: " + payload); - ExecuteCommandPayload commandPayload = ExecuteCommandPayload.convertToExecuteCommand(payload); - String commandsString = commandPayload.getCommands(); - if (!commandsString.isEmpty()) { - mAplController.executeCommands(commandsString, action -> { - if (action != null) { - action.then(() -> { - Log.i(TAG, - "onExecuteCommands: result: true command: token:" + token - + " command: " + commandsString); - mAplEventSender.sendExecuteCommandsResult(token, true, ""); - // Inactive after command completion - mAplEventSender.sendActivityEventRequest( - token, IAPLEventSender.ActivityEvent.DEACTIVATED); - }); - action.addTerminateCallback(() -> { - Log.e(TAG, "onExecuteCommands: result: false token: " + token + " command terminated"); - mAplEventSender.sendExecuteCommandsResult(token, false, "Missing commands"); - // Inactive after command termination - mAplEventSender.sendActivityEventRequest( - token, IAPLEventSender.ActivityEvent.DEACTIVATED); - }); - // Active while commands run - mAplEventSender.sendActivityEventRequest(token, IAPLEventSender.ActivityEvent.ACTIVATED); - } - }); - } else { - mExecutor.submit(() -> { - Log.e(TAG, "onExecuteCommands: result: false token: " + token); - mAplEventSender.sendExecuteCommandsResult(token, false, "Missing commands"); - }); - } - } catch (Exception e) { - Log.e(TAG, "onExecuteCommands: token: result: false token: " + token + " error: " + e.getMessage()); - mExecutor.submit(() -> { mAplEventSender.sendExecuteCommandsResult(token, false, e.getMessage()); }); - } - }); - } - - @Override - public void onDataSourceUpdate(String sourceType, String payload, String token) { - Log.i(TAG, "dataSourceUpdate called: " + sourceType + " payload: " + payload + " token: " + token); - // Update data in APL Controller - if (!mAplController.updateDataSource(sourceType, payload)) { - Log.e(TAG, "handleDataSourceFetchRequest: updateDataSource was unsuccessful"); - } - } - - @Override - public void onInterruptCommandSequence(String token) { - getAplLayout().post(() -> { - try { - Log.i(TAG, "Interrupting command sequence"); - mAplController.cancelExecution(); - } catch (Exception e) { - Log.e(TAG, "Interrupting command sequence did not succeed: " + e.getMessage()); - } - }); - } - - //------------------------------------------------------------------------- - // IAPLOptionsBuilderProvider - //------------------------------------------------------------------------- - - @NonNull - @Override - public APLOptions.Builder getAPLOptionsBuilder() { - return mActivityComponent.getAPLOptionsBuilder() - .sendEventCallback(this) - .dataSourceFetchCallback(this) - .dataSourceErrorCallback(this) - .onAplFinishCallback(this) - .extensionEventCallback(mExtensionManager) - .visualContextListener(this); - } - - //------------------------------------------------------------------------- - // IAPLEventSender - //------------------------------------------------------------------------- - - @Override - public IAPLEventSender getAplEventSender() { - return mAplEventSender; - } - - //------------------------------------------------------------------------- - // IAPLTokenProvider - //------------------------------------------------------------------------- - - @Override - public String getToken() { - return mToken; - } - - //------------------------------------------------------------------------- - // IVisualContextListener - Android Viewhost - //------------------------------------------------------------------------- - - @Override - public void onVisualContextUpdate(JSONObject visualContext) { - Log.v(TAG, "Visual context update: " + visualContext); - - if (mRenderDocumentPayload != null) { - JSONArray compsVisibleOnScreen = new JSONArray(); - compsVisibleOnScreen.put(visualContext); - RenderedDocumentStatePayload payload = - RenderedDocumentStatePayload.builder() - .presentationToken(mRenderDocumentPayload.getPresentationToken()) - .presentationSession(mRenderDocumentPayload.getPresentationSession()) - .versionName(BuildConfig.VERSION_NAME) - .componentsVisibleOnScreenArray(compsVisibleOnScreen) - .build(); - mLatestRenderedDocumentState = payload; - mAplEventSender.sendContext(mLatestRenderedDocumentState.toString()); - } - } - - //------------------------------------------------------------------------- - // IPresenter - //------------------------------------------------------------------------- - - @Override - public void onTouchEvent(MotionEvent event) { - Log.v(TAG, "onTouchEvent: " + event); - String token = getToken(); - if (token != null) { - mAplEventSender.sendActivityEventRequest(token, IAPLEventSender.ActivityEvent.ONE_TIME); - } - } - - @Override - public boolean onKeyEvent(KeyEvent event) { - Log.v(TAG, "onKeyEvent: " + event); - String token = getToken(); - if (token != null) { - mAplEventSender.sendActivityEventRequest(token, IAPLEventSender.ActivityEvent.ONE_TIME); - } - return false; - } - - @Override - public APLLayout getAplLayout() { - String windowId = mRenderDocumentPayload != null && !mRenderDocumentPayload.getWindowId().isEmpty() - ? mRenderDocumentPayload.getWindowId() - : mDefaultWindowId; - return mAplLayouts.get(windowId); - } - - @Override - public void setLocalInfoDataConsumer(ILocalInfoDataConsumer consumer) { - mLocalInfoDataConsumer = consumer; - } - - @Override - public void setDismissibleCallback(IDismissible dismissibleCallback) { - mDismissibleCallback = dismissibleCallback; - } - - @Override - public void cancelExecution() { - if (mAplController != null) { - Log.i(TAG, "cancelExecution"); - mAplController.cancelExecution(); - } - } - - /** - * The following overrides are for methods defined by interfaces in the - * Android viewhost. - */ - - //------------------------------------------------------------------------- - // IOnAplFinishCallback - Android Viewhost - //------------------------------------------------------------------------- - - @Override - public void onAplFinish() { - Log.v(TAG, "APL Rendering finished"); - if (mDismissibleCallback != null) { - mDismissibleCallback.onDismiss(); - } - } - - //------------------------------------------------------------------------- - // ISendEventCallback - Android Viewhost - //------------------------------------------------------------------------- - - @Override - public void onSendEvent(Object[] args, Map components, Map sources) { - try { - JSONArray jsonArgs = new JSONArray((args)); - JSONObject jsonComponents = new JSONObject(components); - JSONObject jsonSources = new JSONObject(sources); - - String userEvent = new UserEventPayload(getToken(), jsonArgs, jsonComponents, jsonSources).toString(); - Log.v(TAG, "UserEvent: " + userEvent); - mAplEventSender.sendUserEventRequest(userEvent); - } catch (Exception e) { - Log.e(TAG, e.getMessage()); - } - } - - //------------------------------------------------------------------------- - // IDataSourceErrorCallback - Android Viewhost - //------------------------------------------------------------------------- - - @Override - public void onDataSourceError(Object errors) { - JSONObject payload = new JSONObject(); - try { - final JSONArray errorsJson = new JSONArray(errors); - payload.put("errors", errorsJson); - payload.put("presentationToken", getToken()); - - Log.v(TAG, "onDataSourceError: " + payload.toString()); - // Notify that an error occurred - mAplEventSender.sendRuntimeErrorEventRequest(payload.toString()); - } catch (JSONException e) { - Log.e(TAG, "Exception occurred while preparing RuntimeError Event payload", e); - } - } - - //------------------------------------------------------------------------- - // IDataSourceFetchCallback - Android Viewhost - //------------------------------------------------------------------------- - - @Override - public void onDataSourceFetchRequest(String dataSourceType, Map eventPayload) { - if (dataSourceType == null) { - Log.e(TAG, "onDataSourceFetchRequest: dataSource type is null"); - return; - } - - if (eventPayload == null) { - Log.e(TAG, "onDataSourceFetchRequest: eventPayload type is null"); - return; - } - - // Construct data source fetch request payload - JSONObject payload; - payload = new JSONObject(eventPayload); - try { - payload.put("presentationToken", getToken()); - Log.i(TAG, "onDataSourceFetchRequest: " + dataSourceType + " payload: " + payload.toString()); - // Notify that event should be sent - mAplEventSender.sendDataSourceFetchEventRequest(dataSourceType, payload.toString()); - - } catch (JSONException e) { - Log.e(TAG, "onDataSourceFetchRequest: unable to add presentation token", e); - } - } - - //------------------------------------------------------------------------- - // IDocumentLifecycleListener - Android Viewhost - //------------------------------------------------------------------------- - - @Override - public void onDocumentRender(@NonNull RootContext rootContext) { - Log.v(TAG, "onDocumentRender: "); - renderResponse(getToken(), true, ""); - } - - @Override - public void onDocumentFinish() { - Log.v(TAG, "onDocumentFinish: "); - } - - //------------------------------------------------------------------------- - // ILocalInfoDataReporter - //------------------------------------------------------------------------- - - @Override - public void platformDataItemSelectedById(String poiId) { - if (mLocalInfoExtension != null) { - Log.v(TAG, "poiSelected " + poiId); - mLocalInfoExtension.poiSelected(mAplController, poiId); - mAplEventSender.sendActivityEventRequest(mToken, IAPLEventSender.ActivityEvent.ONE_TIME); - } - } - - //------------------------------------------------------------------------- - // Helper private methods - //------------------------------------------------------------------------- - - /** - * Returns the APL options that will be used in rendering document. - * - * @return APLOptions The options used for rendering. - */ - private synchronized APLOptions getAPLOptions() { - if (mAplOptions == null) { - mAplOptions = getAPLOptionsBuilder().build(); - } - return mAplOptions; - } - - /** - * Initialize the activity component object that provides APL options and configuration. - * - * @param context - * @return ActivityComponent The activity component object. - */ - private ActivityComponent initActivityComponent(Context context) { - return DaggerActivityComponent.builder() - .activityModule(new ActivityModule(context)) - .applicationComponent(mApplicationComponent) - .build(); - } - - /** - * Listen for touch events on the APL layout so that - * we can report activity events to prevent document from - * timing out when there is user interaction. - */ - private void setupTouchListener() { - for (APLLayout aplLayout : mAplLayouts.values()) { - aplLayout.setOnTouchListener((view, event) -> { - if (event.getAction() == MotionEvent.ACTION_UP) { - onTouchEvent(event); - aplLayout.performClick(); - } - - // Let the parent consume the event - return false; - }); - } - } - - /** - * Render the document. - * - * @param content the inflated contents - */ - private void doRender(Content content) { - // Finish the old document - destroyAplView(); - applyScaling(); - - mExtensionManager = new ExtensionManager(mRootConfig); - Set extensionRequests = content.getExtensionRequests(); - - mBackHandler = new BackExtension(mBackStack, this::goBack, this); - mBackHandler.setResponsibleForBackButton(true); - mExtensionManager.addBuiltInExtension(mBackHandler); - - Map extensionSettings = content.getExtensionSettings(mBackHandler.getUri()); - if (extensionSettings != null) { - Object backstackSettings = extensionSettings.get(BackExtension.SETTINGS_PROPERTY_BACKSTACK_ID); - if (backstackSettings != null) { - mBackHandler.setDocumentId(backstackSettings.toString()); - } - } - - if (extensionRequests.contains(LocalInfoExtension.URI)) { - mLocalInfoExtension = new LocalInfoExtension(mRootConfig); - mLocalInfoExtension.setDataConsumer(mLocalInfoDataConsumer); - mExtensionManager.addBuiltInExtension(mLocalInfoExtension); - } - - // Register extension and render when done - mExtensionManager.registerRequestedExtensions(extensionRequests, () -> performLayout(content)); - } - - private void performLayout(Content content) { - // Make sure mAplLayout is inflated and initialized - APLLayout aplLayout = getAplLayout(); - APLOptions options = getAPLOptions(); - - try { - aplLayout.post(() -> { - IAPLViewPresenter presenter = aplLayout.getPresenter(); - aplLayout.getPresenter().addDocumentLifecycleListener(this); - try { - mAplController = APLController.renderDocument(content, options, mRootConfig, presenter); - sendDeviceWindowState(); - updateRuntimeProperties(); - } catch (Exception e) { - Log.e(TAG, "Cannot render ", e); - renderResponse(getToken(), false, e.getMessage()); - } - }); - - } catch (Exception e) { - Log.e(TAG, "Render failed", e); - } - } - - private void renderResponse(String token, boolean result, String message) { - mExecutor.submit(() -> { - Log.i(TAG, "Render document result: " + result + " token: " + token + " message: " + message); - mAplEventSender.sendRenderDocumentResult(token, result, message); - }); - } - - /** - * Clean up rendering session. - */ - private synchronized void destroyAplView() { - if (mAplController == null) { - return; - } else { - if (mBackHandler != null) { - BackStackDocument document = - new BackStackDocument(mBackHandler.getDocumentId(), mAplController.getDocumentState()); - mBackHandler.addDocument(document); - } - } - - mLocalInfoExtension = null; - mExtensionManager = null; - mAplController.finishDocument(); - mAplController = null; - mAction = null; - } - - /** - * Set the scaling based on the supported view ports. - */ - private void applyScaling() { - List fallbackModes = Collections.singletonList(ViewportMode.kViewportModeAuto); - List viewportSpecifications = mRenderDocumentPayload.getViewportSpecifications(); - Log.v(TAG, "viewportSpecification: " + viewportSpecifications.toString()); - Scaling scaling = viewportSpecifications.isEmpty() ? new Scaling() - : new Scaling(10.0, viewportSpecifications, fallbackModes); - - // Apply the scaling - getAplLayout().setScaling(scaling); - } - - /** - * Builds the initial device window state that will be reported after - * platform interface registration. - * { - * "defaultWindowId": "string", - * "instances" : [ - * { - * "id": "string", - * "templateId": "string", - * "token" : "", - * "configuration": { - * "interactionMode": "string", - * "sizeConfigurationId": "string" - * } - * } - * ] - * } - * - */ - private void sendDeviceWindowState() { - JSONObject deviceWindowState = new JSONObject(); - JSONArray windowInstances = new JSONArray(); - String windowId = mRenderDocumentPayload != null && !mRenderDocumentPayload.getWindowId().isEmpty() - ? mRenderDocumentPayload.getWindowId() - : mDefaultWindowId; - String token = getToken(); - - try { - if (mVisualCharacteristics.length() > 0) { - for (int i = 0; i < mVisualCharacteristics.length(); i++) { - JSONObject currentElement = mVisualCharacteristics.getJSONObject(i); - if (currentElement.getString("interface").equals("Alexa.Display.Window")) { - JSONArray templates = currentElement.getJSONObject("configurations").getJSONArray("templates"); - for (int j = 0; j < templates.length(); j++) { - JSONObject template = templates.getJSONObject(j); - JSONObject windowInstance = new JSONObject(); - JSONObject windowConfiguration = new JSONObject(); - JSONObject configuration = template.getJSONObject("configuration"); - String templateId = template.getString("id"); - - windowInstance.put("id", templateId); - windowInstance.put("templateId", templateId); - windowInstance.put("token", ""); - - // Token must on the rendering window - if (windowId.equals(templateId)) { - windowInstance.put("token", token); - } - - windowConfiguration.put( - "interactionMode", configuration.getJSONArray("interactionModes").getString(0)); - windowConfiguration.put("sizeConfigurationId", - configuration.getJSONArray("sizes").getJSONObject(0).getString("id")); - windowInstance.put("configuration", windowConfiguration); - - windowInstances.put(windowInstance); - } - } - } - - deviceWindowState.put("defaultWindowId", mDefaultWindowId); - deviceWindowState.put("instances", windowInstances); - - Log.v(TAG, "deviceWindowState: " + deviceWindowState.toString()); - mAplEventSender.sendWindowState(deviceWindowState.toString()); - } - } catch (JSONException e) { - Log.e(TAG, "Unable to build window state", e); - } - } - - //------------------------------------------------------------------------- - // BackStack Support - //------------------------------------------------------------------------- - - public void goBack(@NonNull BackStackDocument backStackDocument) { - getAplLayout().post(() -> { - mAplController.finishDocument(); - backStackDocument.getDocumentState().setOptions(getAPLOptions()); - try { - mAplController = APLController.restoreDocument( - backStackDocument.getDocumentState(), getAplLayout().getPresenter()); - } catch (APLController.APLException e) { - Log.e(TAG, "Document failed to restore."); - } - }); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/APLSingleton.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/APLSingleton.java deleted file mode 100644 index 5fb44db1a..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/APLSingleton.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.NonNull; - -import com.amazon.apl.android.render.dagger.component.ApplicationComponent; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; -import com.amazon.apl.android.render.interfaces.IAPLTokenProvider; -import com.amazon.apl.android.render.network.NetworkExecutor; - -import java.util.concurrent.ExecutorService; - -/** - * This class initializes application components and network - * executor. - */ -public class APLSingleton { - // class loader init, represents the earliest possible process time. - // - // Since Java loads the fields in declaration order, place this at the top. - private static final long INIT_TIME = System.currentTimeMillis(); - - private static final String TAG = APLSingleton.class.getSimpleName(); - - private static final APLSingleton INSTANCE = new APLSingleton(); - - private ApplicationComponent mApplicationComponent; - - private ExecutorService mExecutorService; - - public static APLSingleton getInstance() { - return INSTANCE; - } - - private APLSingleton() {} - - public void init(final Context context, @NonNull IAPLEventSender aplEventSender, - @NonNull IAPLTokenProvider aplTokenProvider) { - Log.i(TAG, "Initializing"); - mApplicationComponent = ApplicationComponent.Initializer.init(context, aplEventSender, aplTokenProvider); - mExecutorService = mApplicationComponent.getExecutorService(); - - startNetworkStack(); - } - - private void startNetworkStack() { - final NetworkExecutor networkExecutor = mApplicationComponent.getNetworkExecutor(); - - networkExecutor.execute(() -> mApplicationComponent.getOkHttpClientWrapper().init()); - } - - public ApplicationComponent getApplicationComponent() { - return mApplicationComponent; - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/audio/AudioFocusController.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/audio/AudioFocusController.java deleted file mode 100644 index 763e69737..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/audio/AudioFocusController.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.apl.android.render.audio; - -import static androidx.media.AudioManagerCompat.AUDIOFOCUS_GAIN; - -import android.media.AudioAttributes; -import android.media.AudioFocusRequest; -import android.media.AudioManager; -import android.util.Log; - -import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; -import androidx.core.util.Preconditions; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Manages the Audio Focus for Media Playback. - *

- * Making changes related to Audio Focus. Please test your changes with following: - * https://developer.amazon.com/docs/fire-tv/testing-audio-focus.html - */ -public class AudioFocusController implements AudioManager.OnAudioFocusChangeListener, AutoCloseable { - @VisibleForTesting - static final float VOLUME_MULTIPLIER_DUCK = 0.2f; - @VisibleForTesting - static final float VOLUME_MULTIPLIER_NORMAL = 1.0f; - private static final String TAG = AudioFocusController.class.getSimpleName(); - private static final int AUDIO_FOCUS_STATE_NONE = 0; - private static final int AUDIO_FOCUS_STATE_WAITING_FOR_ACQUISITION = 1; - private static final int AUDIO_FOCUS_STATE_ACQUIRED = 2; - private static final int AUDIO_FOCUS_STATE_DUCKED = 3; - private static final int AUDIO_FOCUS_STATE_LOST_TRANSIENT = 4; - // Dependencies. - @NonNull - private final AudioManager mAudioManager; - // Internal Dependencies. - @NonNull - private final AudioFocusRequest mFocusRequest; - // Late Dependencies. - private PlaybackController mPlaybackController; - // State. - @AudioFocusState - private int mCurrentState; - - /** - * Construct an instance of {@link AudioFocusController}. - * - * @param audioManager {@link AudioManager} Android Audio Manager from which - * audio focus would be requested. - */ - public AudioFocusController(@NonNull AudioManager audioManager, @NonNull PlaybackController playbackController) { - mPlaybackController = playbackController; - mAudioManager = audioManager; - mFocusRequest = makeAudioFocusRequest(); - mCurrentState = AUDIO_FOCUS_STATE_NONE; - } - - /** - * Sets the {@link PlaybackController} required by this object. - * - * @param controller Playback Controller. - */ - public void setPlaybackController(@NonNull PlaybackController controller) { - mPlaybackController = controller; - } - - /** - * Convert Focus Change integer to String for logging. - * - * @param focusChange Focus change integer value. - * @return String corresponding to input focus change. - */ - private static String focusChangeToString(int focusChange) { - switch (focusChange) { - case AudioManager.AUDIOFOCUS_GAIN: - return "AUDIOFOCUS_GAIN"; - case AudioManager.AUDIOFOCUS_LOSS: - return "AUDIOFOCUS_LOSS"; - case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: - return "AUDIOFOCUS_LOSS_TRANSIENT"; - case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: - return "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK"; - case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT: - return "AUDIOFOCUS_GAIN_TRANSIENT"; - case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: - return "AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE"; - case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: - return "AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK"; - case AudioManager.AUDIOFOCUS_NONE: - return "AUDIOFOCUS_NONE"; - default: - return "unknown" + focusChange; - } - } - - /** - * Convert Focus State integer to String for logging. - * - * @param focusState Focus State integer value. - * @return String corresponding to input focus state. - */ - private static String focusStateToString(int focusState) { - switch (focusState) { - case AUDIO_FOCUS_STATE_NONE: - return "AUDIO_FOCUS_STATE_NONE"; - case AUDIO_FOCUS_STATE_ACQUIRED: - return "AUDIO_FOCUS_STATE_ACQUIRED"; - case AUDIO_FOCUS_STATE_WAITING_FOR_ACQUISITION: - return "AUDIO_FOCUS_STATE_WAITING_FOR_ACQUISITION"; - case AUDIO_FOCUS_STATE_DUCKED: - return "AUDIO_FOCUS_STATE_DUCKED"; - case AUDIO_FOCUS_STATE_LOST_TRANSIENT: - return "AUDIO_FOCUS_STATE_LOST_TRANSIENT"; - default: - return "unrecognized:" + focusState; - } - } - - @Override - public void onAudioFocusChange(int focusChange) { - Log.d(TAG, - "Focus Changed. Current audio focus state: " + focusStateToString(mCurrentState) - + " Focus change: " + focusChangeToString(focusChange)); - - switch (focusChange) { - case AudioManager.AUDIOFOCUS_GAIN: - Preconditions.checkArgument(mCurrentState != AUDIO_FOCUS_STATE_NONE); - switch (mCurrentState) { - case AUDIO_FOCUS_STATE_DUCKED: - mPlaybackController.adjustPlaybackVolume(VOLUME_MULTIPLIER_NORMAL); - break; - case AUDIO_FOCUS_STATE_WAITING_FOR_ACQUISITION: - mPlaybackController.startPlaybackNow(); - break; - case AUDIO_FOCUS_STATE_LOST_TRANSIENT: - // Coming out of focus loss transient state. - mPlaybackController.requestResumingPlayback(); - break; - case AUDIO_FOCUS_STATE_ACQUIRED: - break; // Nothing to do, we already have a focus. - case AUDIO_FOCUS_STATE_NONE: - break; // Precondition before switch would not let us be here. - } - mCurrentState = AUDIO_FOCUS_STATE_ACQUIRED; - break; - case AudioManager.AUDIOFOCUS_LOSS: - mCurrentState = AUDIO_FOCUS_STATE_NONE; - mPlaybackController.requestStopPlayback(); - break; - case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: - mCurrentState = AUDIO_FOCUS_STATE_LOST_TRANSIENT; - mPlaybackController.requestPausePlayback(); - break; - case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: - mCurrentState = AUDIO_FOCUS_STATE_DUCKED; - mPlaybackController.adjustPlaybackVolume(VOLUME_MULTIPLIER_DUCK); - break; - case AudioManager.AUDIOFOCUS_NONE: - mPlaybackController.requestStopPlayback(); - mCurrentState = AUDIO_FOCUS_STATE_NONE; - break; - } - } - - @Override - public void close() throws Exception { - Log.i(TAG, "Disposing the Audio Focus Controller"); - abandonAudioFocus(); - } - - /** - * Start the playback after acquiring the audio focus. - *

- * The playback may not begin immediately if acquisition of focus - * is delivered asynchronously. - */ - public void startPlaybackAfterAcquiringFocus() { - Log.d(TAG, - "Start Playback (after acquiring focus). Current audio focus state: " - + focusStateToString(mCurrentState)); - - switch (mCurrentState) { - case AUDIO_FOCUS_STATE_ACQUIRED: - case AUDIO_FOCUS_STATE_DUCKED: - // Focus already acquired. Continue with playback. - mPlaybackController.startPlaybackNow(); - break; - case AUDIO_FOCUS_STATE_WAITING_FOR_ACQUISITION: - Log.d(TAG, "Waiting for audio focus from prior request"); - break; - case AUDIO_FOCUS_STATE_LOST_TRANSIENT: - case AUDIO_FOCUS_STATE_NONE: { - int focusResponse = requestAudioFocus(); - Log.d(TAG, "Audio focus response: " + focusResponse); - - switch (focusResponse) { - case AudioManager.AUDIOFOCUS_REQUEST_GRANTED: - mCurrentState = AUDIO_FOCUS_STATE_ACQUIRED; - mPlaybackController.startPlaybackNow(); - break; - case AudioManager.AUDIOFOCUS_REQUEST_DELAYED: - mCurrentState = AUDIO_FOCUS_STATE_WAITING_FOR_ACQUISITION; - break; - case AudioManager.AUDIOFOCUS_REQUEST_FAILED: - default: - mCurrentState = AUDIO_FOCUS_STATE_NONE; - mPlaybackController.failedToAcquireFocus(); - break; - } - break; - } - } - } - - /** - * Abandon the audio focus if we have acquired one. - */ - public void relinquishAudioFocusIfCurrentlyAcquired() { - Log.d(TAG, "Relinquishing Audio Focus. Current state: " + focusStateToString(mCurrentState)); - if (mCurrentState == AUDIO_FOCUS_STATE_WAITING_FOR_ACQUISITION || mCurrentState == AUDIO_FOCUS_STATE_DUCKED - || mCurrentState == AUDIO_FOCUS_STATE_ACQUIRED) { - abandonAudioFocus(); - mCurrentState = AUDIO_FOCUS_STATE_NONE; - } - } - - /** - * Request Audio Focus for Media Playback. - * - * @return Response returned by {@link AudioManager##requestAudioFocus()} - */ - private int requestAudioFocus() { - Log.d(TAG, "Requesting Audio Focus"); - return mAudioManager.requestAudioFocus(mFocusRequest); - } - - /** - * Abandon Audio Focus for Media Playback. - * - * @return Response returned by {@link AudioManager##abandonAudioFocusRequest()} - */ - private int abandonAudioFocus() { - Log.d(TAG, "Abandoning Audio Focus"); - return mAudioManager.abandonAudioFocusRequest(mFocusRequest); - } - - /** - * Make Audio Focus request required by {@link AudioManager}. - * - * @return An instance of {@link AudioFocusRequest}. - */ - private AudioFocusRequest makeAudioFocusRequest() { - AudioAttributes audioAttributes = new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_MEDIA) - // Todo: Set content type to speech for audibles - .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) - .build(); - - return new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN) - .setAudioAttributes(audioAttributes) - .setWillPauseWhenDucked(false) - .setOnAudioFocusChangeListener(this) - .build(); - } - - /** - * Interface implemented by Player for playback control. - */ - public interface PlaybackController { - /** - * Start the playback now. This method is called when intent to - * Play the media is established and only thing missing had been - * the acquisition of audio focus. - */ - void startPlaybackNow(); - - /** - * Request that media playback can be resumed, if it was terminated - * on account of loosing audio focus transiently. - */ - void requestResumingPlayback(); - - /** - * Request that media playback should be paused because audio focus - * has been lost transiently. - */ - void requestPausePlayback(); - - /** - * Request that media playback be stopped because audio focus has been - * lost permanently. - */ - void requestStopPlayback(); - - /** - * Adjust the media playback volume because either media players audio - * focus has been ordered to duck, or if it is recovering from duck state - * to normal state. - * - * @param volumeMultiplier Volume multiplier between 0 to 1. - */ - void adjustPlaybackVolume(float volumeMultiplier); - - /** - * Called when Audio focus could not be acquired for the playback. - */ - void failedToAcquireFocus(); - } - - @Documented - @Retention(RetentionPolicy.SOURCE) - @IntDef({AUDIO_FOCUS_STATE_NONE, AUDIO_FOCUS_STATE_WAITING_FOR_ACQUISITION, AUDIO_FOCUS_STATE_ACQUIRED, - AUDIO_FOCUS_STATE_DUCKED, AUDIO_FOCUS_STATE_LOST_TRANSIENT}) - private @interface AudioFocusState {} -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/content/APLHttpContentRetriever.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/content/APLHttpContentRetriever.java deleted file mode 100644 index d57b63ced..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/content/APLHttpContentRetriever.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.apl.android.render.content; - -import android.os.Handler; -import android.os.Looper; -import android.text.TextUtils; -import android.util.Log; - -import androidx.annotation.NonNull; - -import com.amazon.apl.android.Content; -import com.amazon.apl.android.render.network.OkHttpClientWrapper; -import com.amazon.apl.android.render.payload.RenderDocumentPayload; -import com.amazon.apl.android.thread.SequentialExecutor; - -import org.json.JSONObject; - -import java.io.IOException; - -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.Response; - -/** - * This class is used during the APL rendering process to download - * resources such as packages, layouts, media, etc. - */ -public class APLHttpContentRetriever extends Content.Callback { - private static final String TAG = APLHttpContentRetriever.class.getSimpleName(); - - public static final String CLOUDFRONT_LOCATION_PREFIX = "https://d2na8397m465mh.cloudfront.net/packages/"; - private static final String CLOUDFRONT_LOCATION_SUFFIX = "/document.json"; - - // Name of the mainTemplate parameter to which entire datasources payload is bound to. - private static final String PARAM_PAYLOAD = "payload"; - - private final OkHttpClientWrapper mOkHttpClient; - private final SequentialExecutor mNetworkExecutor; - private final RenderDocumentPayload mPayload; - private CompleteCallback mCallback; - - public APLHttpContentRetriever(@NonNull OkHttpClientWrapper okHttpClient, - @NonNull SequentialExecutor networkExecutor, @NonNull RenderDocumentPayload payload) { - mNetworkExecutor = networkExecutor; - mOkHttpClient = okHttpClient; - mPayload = payload; - } - - public interface CompleteCallback { void onComplete(Content content); } - - public void addCompleteCallback(APLHttpContentRetriever.CompleteCallback callback) { - mCallback = callback; - } - - private static String getDefaultPackageUrl(final String packageName, final String version) { - return CLOUDFRONT_LOCATION_PREFIX + packageName + "/" + version + CLOUDFRONT_LOCATION_SUFFIX; - } - - @Override - public void onPackageRequest(final Content content, final Content.ImportRequest request) { - final String url = TextUtils.isEmpty(request.getSource()) - ? getDefaultPackageUrl(request.getPackageName(), request.getVersion()) - : request.getSource(); - if (TextUtils.isEmpty(url)) { - Log.e(TAG, "Empty url, cannot fetch package"); - return; - } - - mNetworkExecutor.execute(new LoadContentRequest(mOkHttpClient, url, content, request)); - } - - @Override - public void onDataRequest(final Content content, final String dataId) { - onDataSourceContentRequest(content, dataId, mPayload); - } - - @Override - public void onComplete(Content content) { - Handler handler = new Handler(Looper.getMainLooper()); - handler.post(() -> { - if (mCallback != null) { - mCallback.onComplete(content); - } - }); - } - - @Override - public void onError(final Content content) { - Log.e(TAG, "On APL error"); - mOkHttpClient.cancelAll(); - } - - static final class LoadContentRequest implements Runnable { - private final static int CONTENT_LENGTH_UNKNOWN_SIZE = -1; - private final String mUrl; - private final OkHttpClientWrapper mOkHttpClient; - private final Content mContent; - private final Content.ImportRequest mRequest; - - LoadContentRequest(@NonNull final OkHttpClientWrapper okHttpClient, @NonNull final String url, - @NonNull final Content content, @NonNull final Content.ImportRequest request) { - mUrl = url; - mOkHttpClient = okHttpClient; - mContent = content; - mRequest = request; - } - - @Override - public void run() { - mOkHttpClient.newCall(mUrl).enqueue(new Callback() { - @Override - public void onFailure(@lombok.NonNull final Call call, @lombok.NonNull final IOException e) { - Log.e(TAG, "OkHttp failure. " + e.getMessage()); - } - - @Override - public void onResponse(@lombok.NonNull final Call call, @lombok.NonNull final Response response) { - if (response.isSuccessful()) { - assert response.body() != null; - - try { - final boolean isCacheHit = response.cacheResponse() != null; - final boolean isNetworkHit = response.networkResponse() != null; - - Log.i(TAG, "onResponse: cacheHit: " + isCacheHit + " networkHit: " + isNetworkHit); - - // If content length is -1, then this means that the response size is unknown - // and is streamed to get the content. In this case we are reporting response - // size as -1 and the whole set of imports size is ignored inside ImportTracker. - final long contentLength = response.body().contentLength(); - mContent.addPackage(mRequest, response.body().string()); - } catch (IOException e) { - Log.e(TAG, "OkHttp response error. " + e.getMessage()); - } catch (Content.ContentException ex) { - Log.e(TAG, "Add package content failed.", ex); - } finally { - response.close(); - } - } else { - Log.e(TAG, "OkHttp response failure, code: " + response.code()); - } - } - }); - } - } - - void onDataSourceContentRequest(final Content content, final String dataId, final RenderDocumentPayload payload) { - Log.v(TAG, String.format("onDataRequest: dataId: %s", dataId)); - final JSONObject dataSourcesPayload = payload.getDataSources(); - if (dataSourcesPayload == null) { - Log.e(TAG, "onDataRequest: no datasources set in RenderDocument payload"); - content.addData(dataId, "{}"); - return; - } - if (dataId.equals(PARAM_PAYLOAD)) { // Entire data source payload is being requested - content.addData(dataId, dataSourcesPayload.toString()); - } else if (dataSourcesPayload.has(dataId)) { // requesting specific key within datasource payload - content.addData(dataId, dataSourcesPayload.optString(dataId)); - } else { - Log.w(TAG, - String.format( - "onDataRequest: no object with key '%s' in datasources, defaulting to payload", dataId)); - content.addData(dataId, dataSourcesPayload.toString()); - } - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ActivityContext.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ActivityContext.java deleted file mode 100644 index 81f6a57d2..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ActivityContext.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger; - -import javax.inject.Qualifier; - -/** - * Used to declare activity context. - */ -@Qualifier -public @interface ActivityContext {} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ActivityScope.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ActivityScope.java deleted file mode 100644 index a70c91b93..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ActivityScope.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import javax.inject.Scope; - -/** - * Used to define activity level scope, i.e. only one instance of a class will be provided per - * activity. - */ -@Scope -@Retention(RetentionPolicy.CLASS) -public @interface ActivityScope {} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ApplicationContext.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ApplicationContext.java deleted file mode 100644 index e541b3566..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ApplicationContext.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.apl.android.render.dagger; - -import javax.inject.Qualifier; - -/** - * Used to declare application context. - */ -@Qualifier -public @interface ApplicationContext {} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ApplicationScope.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ApplicationScope.java deleted file mode 100644 index 4492af77f..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/ApplicationScope.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import javax.inject.Scope; - -/** - * Used to define application level scope, i.e. only one instance of a class will be provided per - * application. - */ -@Scope -@Retention(RetentionPolicy.CLASS) -public @interface ApplicationScope {} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/component/ActivityComponent.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/component/ActivityComponent.java deleted file mode 100644 index 0663bb0a4..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/component/ActivityComponent.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger.component; - -import android.content.Context; - -import com.amazon.apl.android.APLOptions; -import com.amazon.apl.android.RootConfig; -import com.amazon.apl.android.render.dagger.ActivityContext; -import com.amazon.apl.android.render.dagger.ActivityScope; -import com.amazon.apl.android.render.dagger.module.APLOptionsModule; -import com.amazon.apl.android.render.dagger.module.ActivityModule; - -import dagger.Component; - -/** - * This provides all the activity level dependencies. - */ -@ActivityScope -@Component(modules = {ActivityModule.class, APLOptionsModule.class}, dependencies = ApplicationComponent.class) -public interface ActivityComponent { - /** - * @return the context. - */ - @ActivityContext - Context getContext(); - - /** - * @return The {@link APLOptions.Builder}. - */ - APLOptions.Builder getAPLOptionsBuilder(); - - /** - * @return The {@link RootConfig}. - */ - RootConfig getRootConfig(); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/component/ApplicationComponent.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/component/ApplicationComponent.java deleted file mode 100644 index 84ce71364..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/component/ApplicationComponent.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger.component; - -import android.content.Context; - -import com.amazon.apl.android.render.dagger.ApplicationContext; -import com.amazon.apl.android.render.dagger.ApplicationScope; -import com.amazon.apl.android.render.dagger.module.ApplicationModule; -import com.amazon.apl.android.render.dagger.module.MediaPlayerModule; -import com.amazon.apl.android.render.dagger.module.NetworkModule; -import com.amazon.apl.android.render.dagger.module.TtsModule; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; -import com.amazon.apl.android.render.interfaces.IAPLTokenProvider; -import com.amazon.apl.android.render.media.APLMediaPlayerProvider; -import com.amazon.apl.android.render.network.NetworkExecutor; -import com.amazon.apl.android.render.network.OkHttpClientWrapper; -import com.amazon.apl.android.render.tts.APLTtsPlayerProvider; - -import java.util.concurrent.ExecutorService; - -import dagger.Component; - -/** - * This provides all the application level dependencies. - */ -@ApplicationScope -@Component(modules = {MediaPlayerModule.class, NetworkModule.class, TtsModule.class}) -public interface ApplicationComponent { - final class Initializer { - public static ApplicationComponent init( - Context context, IAPLEventSender aplEventSender, IAPLTokenProvider aplTokenProvider) { - return DaggerApplicationComponent.builder() - .applicationModule(new ApplicationModule(context, aplEventSender, aplTokenProvider)) - .build(); - } - } - - /** - * @return The application context. - */ - @ApplicationContext - Context getContext(); - - /** - * @return The {@link OkHttpClientWrapper}. - */ - OkHttpClientWrapper getOkHttpClientWrapper(); - - /** - * @return The {@link APLTtsPlayerProvider} - */ - APLTtsPlayerProvider getTtsPlayerProvider(); - - /** - * @return The {@link NetworkExecutor}. - */ - NetworkExecutor getNetworkExecutor(); - - /** - * @return the application level executor service. - */ - ExecutorService getExecutorService(); - - /** - * @return The {@link APLMediaPlayerProvider} - */ - APLMediaPlayerProvider getMediaPlayerProvider(); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/APLOptionsModule.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/APLOptionsModule.java deleted file mode 100644 index 902f05b2c..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/APLOptionsModule.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger.module; - -import android.content.Context; - -import com.amazon.apl.android.APLOptions; -import com.amazon.apl.android.RootConfig; -import com.amazon.apl.android.audio.RuntimeAudioPlayerFactory; -import com.amazon.apl.android.dependencies.IOpenUrlCallback; -import com.amazon.apl.android.dependencies.impl.OpenUrlCallback; -import com.amazon.apl.android.media.RuntimeMediaPlayerFactory; -import com.amazon.apl.android.render.BuildConfig; -import com.amazon.apl.android.render.dagger.ActivityContext; -import com.amazon.apl.android.render.dagger.ActivityScope; -import com.amazon.apl.android.render.media.APLMediaPlayerProvider; -import com.amazon.apl.android.render.tts.APLTtsPlayerProvider; - -import java.util.HashMap; -import java.util.Map; - -import dagger.Module; -import dagger.Provides; - -/** - * Provides {@link com.amazon.apl.android.APLOptions.Builder} - */ -@Module(includes = {}) -public class APLOptionsModule { - /** - * @return an instance of {@link APLOptions}. - */ - @Provides - APLOptions.Builder provideAPLOptions(final IOpenUrlCallback openUrlCallback) { - return APLOptions.builder().openUrlCallback(openUrlCallback); - } - - /** - * @return an instance of {@link IOpenUrlCallback}. - */ - @Provides - @ActivityScope - public IOpenUrlCallback provideOpenUrl(@ActivityContext final Context context) { - return new OpenUrlCallback(context); - } - - /** - * @param context the activity context - * @return an instance of {@link RootConfig} - */ - @Provides - public RootConfig provideRootConfig(@ActivityContext final Context context, final APLTtsPlayerProvider ttsProvider, - final APLMediaPlayerProvider mediaProvider) { - Map autoEnvironmentValues = new HashMap<>(); - autoEnvironmentValues.put("drivingState", "moving"); - return RootConfig.create(context) - .agent(BuildConfig.VERSION_NAME, "1.9") - .registerDataSource("dynamicIndexList") - .registerDataSource("dynamicTokenList") - .setEnvironmentValue("automobile", autoEnvironmentValues) - .audioPlayerFactory(new RuntimeAudioPlayerFactory(ttsProvider)) - .mediaPlayerFactory(new RuntimeMediaPlayerFactory(mediaProvider)) - .allowOpenUrl(false); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/ActivityModule.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/ActivityModule.java deleted file mode 100644 index a1c7f7f6b..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/ActivityModule.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger.module; - -import android.content.Context; - -import com.amazon.apl.android.providers.IImageLoaderProvider; -import com.amazon.apl.android.providers.impl.GlideImageLoaderProvider; -import com.amazon.apl.android.render.dagger.ActivityContext; -import com.amazon.apl.android.render.dagger.ActivityScope; - -import java.lang.ref.WeakReference; - -import dagger.Module; -import dagger.Provides; -import lombok.NonNull; - -/** - * Provides the activity context. - */ -@Module -public class ActivityModule { - /** - * Activity context. - */ - private final WeakReference mContext; - - /** - * Instantiates this module with the activity context. - * - * @param context The context. - */ - public ActivityModule(@ActivityContext final Context context) { - // Ensure application context - mContext = new WeakReference<>(context); - } - - /** - * @return The activity {@link Context} - */ - @Provides - @ActivityScope - @ActivityContext - Context provideContext() { - return mContext.get(); - } - - @Provides - @ActivityScope - IImageLoaderProvider provideImageLoader() { - return new GlideImageLoaderProvider(); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/ApplicationModule.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/ApplicationModule.java deleted file mode 100644 index a6b0ed944..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/ApplicationModule.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger.module; - -import android.content.Context; - -import com.amazon.apl.android.render.dagger.ApplicationContext; -import com.amazon.apl.android.render.dagger.ApplicationScope; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; -import com.amazon.apl.android.render.interfaces.IAPLTokenProvider; -import com.amazon.apl.android.thread.Threading; - -import java.lang.ref.WeakReference; -import java.util.concurrent.ExecutorService; - -import dagger.Module; -import dagger.Provides; - -/** - * Provides the application context. - */ -@Module -public class ApplicationModule { - /** - * Application context. - */ - private final WeakReference mContext; - - /** - * Object used to send events back to the cloud. - */ - private final IAPLEventSender mAplEventSender; - - /** - * Retrieves the token of the rendered APL document. - */ - private final IAPLTokenProvider mAplTokenProvider; - - /** - * Instantiates this module with the application context. - * - * @param context The activity context. - * @param aplEventSender The object used to send events back to cloud. - * @param aplTokenProvider The object that provides the current presentation token. - */ - public ApplicationModule(@ApplicationContext final Context context, IAPLEventSender aplEventSender, - IAPLTokenProvider aplTokenProvider) { - // Ensure application context - mContext = new WeakReference<>(context); - mAplEventSender = aplEventSender; - mAplTokenProvider = aplTokenProvider; - } - - /** - * @return The application {@link Context} - */ - @Provides - @ApplicationScope - @ApplicationContext - Context provideContext() { - return mContext.get(); - } - - /** - * @return The executor service {@link ExecutorService} - */ - @Provides - @ApplicationScope - ExecutorService provideExecutorService() { - return Threading.THREAD_POOL_EXECUTOR; - } - - /** - * @return The APL event sender {@link IAPLEventSender} - */ - @Provides - @ApplicationScope - IAPLEventSender provideAplEventSender() { - return mAplEventSender; - } - - /** - * @return The presentation token provider {@link IAPLTokenProvider} - */ - @Provides - @ApplicationScope - IAPLTokenProvider provideAplTokenProvider() { - return mAplTokenProvider; - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/MediaPlayerModule.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/MediaPlayerModule.java deleted file mode 100644 index 0ce55027e..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/MediaPlayerModule.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger.module; - -import androidx.annotation.NonNull; - -import com.amazon.apl.android.render.dagger.ApplicationScope; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; -import com.amazon.apl.android.render.interfaces.IAPLTokenProvider; -import com.amazon.apl.android.render.media.APLMediaPlayerProvider; - -import dagger.Module; -import dagger.Provides; - -/** - * Provides an instance of {@link com.amazon.apl.android.render.media.APLMediaPlayerProvider}. - */ -@Module(includes = {ApplicationModule.class}) -public class MediaPlayerModule { - /** - * @return the {@link com.amazon.apl.android.render.media.APLMediaPlayerProvider}. - */ - @Provides - @ApplicationScope - public APLMediaPlayerProvider provideMediaPlayerProvider( - @NonNull final IAPLEventSender aplEventSender, @NonNull final IAPLTokenProvider aplTokenProvider) { - return new APLMediaPlayerProvider(aplEventSender, aplTokenProvider); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/NetworkModule.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/NetworkModule.java deleted file mode 100644 index 6f64e64f2..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/NetworkModule.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger.module; - -import android.content.Context; - -import com.amazon.apl.android.render.dagger.ApplicationContext; -import com.amazon.apl.android.render.dagger.ApplicationScope; -import com.amazon.apl.android.render.network.NetworkExecutor; -import com.amazon.apl.android.render.network.OkHttpClientWrapper; - -import dagger.Lazy; -import dagger.Module; -import dagger.Provides; -import okhttp3.Cache; -import okhttp3.OkHttpClient; - -/** - * Provides an instance of {@link OkHttpClient} and the application cache. - */ -@Module(includes = {ApplicationModule.class}) -public class NetworkModule { - private static final long CACHE_SIZE = 4L * 1024L * 1024L; // cache size 4MiB on disk - - /** - * Provides an instance of {@link OkHttpClient}. - * - * @param cache The cache to be used by the OkHttpClient. - * @return An instance of {@link OkHttpClient}. - */ - @Provides - @ApplicationScope - OkHttpClient provideOkHttpClient(final Cache cache) { - return new OkHttpClient.Builder().cache(cache).build(); - } - - /** - * Provides a wrapper around {@link OkHttpClient} to handle cache control and refreshes. - * - * @param okHttpClient the OkHttp client - * @return An instance of {@link OkHttpClientWrapper} - */ - @Provides - @ApplicationScope - OkHttpClientWrapper provideOkHttpClientWrapper(Lazy okHttpClient) { - return new OkHttpClientWrapper(okHttpClient); - } - - /** - * Provides an instance of the application {@link Cache}. - * - * @param context The application {@link Context}. - * @return An instance of the application {@link Cache}. - */ - @Provides - @ApplicationScope - Cache provideCache(@ApplicationContext final Context context) { - return new Cache(context.getCacheDir(), CACHE_SIZE); - } - - @Provides - @ApplicationScope - NetworkExecutor provideNetworkExecutor() { - return new NetworkExecutor(); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/TtsModule.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/TtsModule.java deleted file mode 100644 index 9a4e0ba37..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/dagger/module/TtsModule.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.dagger.module; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import com.amazon.apl.android.render.dagger.ApplicationContext; -import com.amazon.apl.android.render.dagger.ApplicationScope; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; -import com.amazon.apl.android.render.interfaces.IAPLTokenProvider; -import com.amazon.apl.android.render.tts.APLTtsPlayerProvider; - -import dagger.Module; -import dagger.Provides; - -/** - * Provides an instance of {@link APLTtsPlayerProvider}. - */ -@Module(includes = {ApplicationModule.class}) -public class TtsModule { - /** - * @return the {@link APLTtsPlayerProvider}. - */ - @Provides - @ApplicationScope - public APLTtsPlayerProvider provideTtsPlayerProvider(@ApplicationContext final Context context, - @NonNull final IAPLEventSender aplEventSender, @NonNull final IAPLTokenProvider aplTokenProvider) { - return new APLTtsPlayerProvider(context, aplEventSender, aplTokenProvider); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/ExtensionManager.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/ExtensionManager.java deleted file mode 100644 index 70e88c040..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/ExtensionManager.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.extension; - -import android.util.Log; - -import com.amazon.apl.android.Event; -import com.amazon.apl.android.ExtensionCommandDefinition; -import com.amazon.apl.android.ExtensionEventHandler; -import com.amazon.apl.android.ExtensionFilterDefinition; -import com.amazon.apl.android.RootConfig; -import com.amazon.apl.android.dependencies.IExtensionEventCallback; -import com.amazon.apl.android.providers.IExtension; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * Extension Manager responsible for containing available extensions and registering requested extension - * with the root config. - */ -public class ExtensionManager implements IExtensionEventCallback { - private static final String TAG = ExtensionManager.class.getSimpleName(); - - private Map mExtensions; - private RootConfig mRootConfig; - private DiscoveryCallback mDiscoveryCallback; - - //------------------------------------------------------------------------- - // Constructor - //------------------------------------------------------------------------- - - public ExtensionManager(RootConfig rootConfig) { - mRootConfig = rootConfig; - mExtensions = new HashMap<>(); - } - - private IExtension getBuiltInExtension(String uri) { - return mExtensions.get(uri); - } - - //------------------------------------------------------------------------- - // Public methods - //------------------------------------------------------------------------- - - /** - * Interface for notifying when the extensions are loaded and registered. - */ - public interface DiscoveryCallback { void onComplete(); } - - /** - * Adds a built in extension so that it is registered with the APL runtime. - * - * @param extension The extension to add. - */ - public void addBuiltInExtension(IExtension extension) { - mExtensions.put(extension.getUri(), extension); - } - - /** - * This method will register the built in extensions that are requested by the - * APL document only if they are available in the extension manager. - * - * @param requestedExtensionUris Extensions requested through the APL document. - * @param content The APL runtime content. - * @param context The Android context. - * @param discoveryCallback The callback to execute once extensions are registered. - */ - public void registerRequestedExtensions(Set requestedExtensionUris, DiscoveryCallback discoveryCallback) { - mDiscoveryCallback = discoveryCallback; - - for (String requestedExtensionUri : requestedExtensionUris) { - IExtension extension = getBuiltInExtension(requestedExtensionUri); - if (extension != null) { - Log.v(TAG, "Registering extension: " + requestedExtensionUri); - mRootConfig.registerExtensionEnvironment(extension.getUri(), extension.getEnvironment()); - for (ExtensionCommandDefinition command : extension.getCommandDefinitions()) { - mRootConfig.registerExtensionCommand(command); - } - for (ExtensionFilterDefinition filter : extension.getFilterDefinitions()) { - mRootConfig.registerExtensionFilter(filter); - } - for (ExtensionEventHandler handler : extension.getEventHandlers()) { - mRootConfig.registerExtensionEventHandler(handler); - } - } else { - Log.v(TAG, "Extension not supported by runtime: " + requestedExtensionUri); - } - } - - Log.v(TAG, "Finished registering extensions"); - mDiscoveryCallback.onComplete(); - } - - //------------------------------------------------------------------------- - // IExtensionEventCallback - //------------------------------------------------------------------------- - - @Override - public void onExtensionEvent(String name, String uri, Event event, Map source, - Map custom, IExtensionEventCallbackResult resultCallback) { - handleOnExtensionEvent(name, uri, event, source, custom, resultCallback); - } - - @Override - public void onExtensionEvent(String name, String uri, Map source, Map custom, - IExtensionEventCallbackResult resultCallback) { - handleOnExtensionEvent(name, uri, null, source, custom, resultCallback); - } - - private void handleOnExtensionEvent(String name, String uri, Event event, Map source, - Map custom, IExtensionEventCallbackResult resultCallback) { - Log.v(TAG, - "handleOnExtensionEvent uri: " + uri + " event: " + event + " source: " + source - + " custom: " + custom); - IExtension extension = getBuiltInExtension(uri); - if (extension != null) { - IExtensionEventCallback callback = extension.getCallback(); - if (callback != null) { - callback.onExtensionEvent(name, uri, event, source, custom, resultCallback); - } else { - Log.w(TAG, "Callback not handled for uri:" + uri); - } - } else { - Log.w(TAG, "Extension not found uri:" + uri); - } - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackExtension.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackExtension.java deleted file mode 100644 index a9c19c716..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackExtension.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.extension.back; - -import android.text.TextUtils; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.amazon.apl.android.ExtensionCommandDefinition; -import com.amazon.apl.android.ExtensionEventHandler; -import com.amazon.apl.android.LegacyLocalExtension; -import com.amazon.apl.android.dependencies.IExtensionEventCallback; -import com.amazon.apl.android.dependencies.IOnAplFinishCallback; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Implementation of the APL BackStack extension. Allows APL documents to navigate back to previously - * rendered APL documents. - * - * APL-Spec https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-ext-backstack.html - */ -public class BackExtension extends LegacyLocalExtension { - private static final String TAG = BackExtension.class.getSimpleName(); - - public static final String URI = "aplext:backstack:10"; - public static final String COMMAND_GO_BACK_NAME = "GoBack"; - public static final String COMMAND_CLEAR_NAME = "Clear"; - public static final String SETTINGS_PROPERTY_BACKSTACK_ID = "backstackId"; - public static final String PROPERTY_BACK_TYPE = "backType"; - public static final String PROPERTY_BACK_VALUE = "backValue"; - - private static final List COMMANDS = new ArrayList<>(); - - //------------------------------------------------------------------------- - // Supported commands - //------------------------------------------------------------------------- - static { - COMMANDS.add(new ExtensionCommandDefinition(URI, COMMAND_GO_BACK_NAME) - .allowFastMode(true) - .property(PROPERTY_BACK_TYPE, BackType.COUNT.toString(), false) - .property(PROPERTY_BACK_VALUE, 1, false)); - COMMANDS.add(new ExtensionCommandDefinition(URI, COMMAND_CLEAR_NAME).allowFastMode(true)); - } - - @NonNull - private final BackStack mBackStack; - @NonNull - private final IBackCallback mBackCallback; - @NonNull - private final IOnAplFinishCallback mOnFinishCallback; - @Nullable - private BackStackDocument mBackstackDocument; - @Nullable - private IExtensionEventCallbackResult mResultCallback; - - private boolean mResponsibleForBackButton; - private String mCurrentDocumentId; - - /** - * Instantiate a new BackExtension. - * @param backStack the backstack to use - * @param callback the callback for handling GoBack commands - * @param onAplFinishCallback the callback for handling GoBack when the stack is empty - */ - public BackExtension(@NonNull BackStack backStack, @NonNull IBackCallback callback, - @NonNull IOnAplFinishCallback onAplFinishCallback) { - mBackStack = backStack; - mBackCallback = callback; - mOnFinishCallback = onAplFinishCallback; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public String getUri() { - return URI; - } - - /** - * {@inheritDoc} - */ - @Override - public Object getEnvironment() { - Map envObject = new HashMap<>(); - envObject.put("responsibleForBackButton", mResponsibleForBackButton); - envObject.put("backstack", mBackStack.getDocumentIds()); - Log.i(TAG, "getEnvironment"); - return envObject; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public List getCommandDefinitions() { - Log.i(TAG, "getCommandDefinitions"); - return COMMANDS; - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public List getEventHandlers() { - Log.i(TAG, "getEventHandlers"); - return Collections.emptyList(); - } - - /** - * {@inheritDoc} - */ - @Override - @NonNull - public IExtensionEventCallback getCallback() { - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public void applySettings(Map settings) { - Object backStackId = settings.get(SETTINGS_PROPERTY_BACKSTACK_ID); - if (backStackId instanceof String) { - mCurrentDocumentId = (String) backStackId; - } - Log.i(TAG, "applySettings: " + mCurrentDocumentId); - } - - /** - * Returns the current document id. - * @return - */ - public String getDocumentId() { - return mCurrentDocumentId; - } - - /** - * Set the document id. - * @param id - */ - public void setDocumentId(String id) { - mCurrentDocumentId = id; - } - - /** - * {@inheritDoc} - */ - @Override - public void onExtensionEvent(String name, String uri, Map source, Map custom, - IExtensionEventCallbackResult resultCallback) { - mBackstackDocument = null; - mResultCallback = resultCallback; - Log.v(TAG, "onExtensionEvent: " + name + " source: " + source); - switch (name) { - case COMMAND_GO_BACK_NAME: - goBack(custom.get(PROPERTY_BACK_TYPE), custom.get(PROPERTY_BACK_VALUE)); - break; - case COMMAND_CLEAR_NAME: - eventHandled(true); - clear(); - break; - default: - eventHandled(false); - } - } - - /** - * Set the value of the Backstack environment property responsibleForBackButton. - * @param isResponsible true if the document needs to display the back button - */ - public void setResponsibleForBackButton(boolean isResponsible) { - mResponsibleForBackButton = isResponsible; - } - - /** - * Return the current back stack document. - * @return back stack document. - */ - public BackStackDocument getBackstackDocument() { - return mBackstackDocument; - } - - /** - * Add a document to the back stack. - * @param backStackDocument the document to be added to the back stack. - */ - public void addDocument(BackStackDocument backStackDocument) { - mBackStack.addDocument(backStackDocument); - } - - /** - * Go back using document id. - * @param documentId The id - */ - public void goBack(String documentId) { - if (TextUtils.isEmpty(documentId)) { - mBackstackDocument = mBackStack.popDocuments(0); - } else { - mBackstackDocument = mBackStack.popDocuments(documentId); - } - triggerGoBack(); - } - - /** - * Go back using index. - * @param index The index to go back on the stack. - */ - public void goBackIndex(int index) { - mBackstackDocument = mBackStack.popDocumentsAtIndex(index); - triggerGoBack(); - } - - /** - * Go back using count. - * @param count The number of elements that shoupd be popped off the stack. - */ - public void goBackCount(int count) { - mBackstackDocument = mBackStack.popDocuments(count); - triggerGoBack(); - } - - /** - * Clear the back stack. - */ - public void clear() { - mBackStack.clear(); - } - - /** - * Handle the go back command. - * @param objectBackType Back type: count, index, id - * @param backValue - */ - private void goBack(Object objectBackType, Object backValue) { - try { - int intBack = 0; - if (backValue instanceof Double) { - intBack = ((Double) backValue).intValue(); - } else if (backValue instanceof Integer) { - intBack = (Integer) backValue; - } - BackType backType = BackType.valueOf(objectBackType); - switch (backType) { - case ID: - goBack((String) backValue); - break; - case INDEX: - goBackIndex(intBack); - break; - case COUNT: - goBackCount(intBack); - break; - } - } catch (IllegalArgumentException | NullPointerException | ClassCastException e) { - Log.e(TAG, "Invalid keys in document. Doing nothing.", e); - } - } - - /** - * Notified callback of the document to go back to or finish if last element was popped off. - */ - private void triggerGoBack() { - eventHandled(true); - if (mBackstackDocument != null) { - mBackCallback.goBack(mBackstackDocument); - } else if (mBackStack.length() == 0) { - // Finish if we have no documents in the stack - mOnFinishCallback.onAplFinish(); - } - } - - /** - * Call back to signal if event was handled. - * @param handled - */ - private void eventHandled(boolean handled) { - if (mResultCallback != null) { - mResultCallback.onResult(handled); - } - mResultCallback = null; - } - - /** - * Supported back types. - */ - enum BackType { - COUNT, - INDEX, - ID; - - public static BackType valueOf(Object value) { - if (value instanceof BackType) { - return (BackType) value; - } - - String name = ((String) value).toUpperCase(); - return BackType.valueOf(name); - } - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackStack.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackStack.java deleted file mode 100644 index 1195371b7..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackStack.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.extension.back; - -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * This object contains {@link BackStackDocument} objects and methods to support the apl Backstack. - * - * APL-Spec https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-ext-backstack.html - * - * Note: - * The top of the stack is {@link BackStack#length()} - 1. - */ -public class BackStack { - private static final String TAG = BackStack.class.getSimpleName(); - - private ArrayDeque mDocuments; - public BackStack() { - mDocuments = new ArrayDeque<>(); - } - - /** - * Adds a document to the BackStack. - * @param backStackDocument the document to add. - */ - void addDocument(@NonNull BackStackDocument backStackDocument) { - Log.v(TAG, "addDocument: " + backStackDocument.hashCode()); - mDocuments.addLast(backStackDocument); - } - - /** - * @return the length of the backstack. - */ - public int length() { - Log.v(TAG, "length: " + mDocuments.size()); - return mDocuments.size(); - } - - /** - * Clears the stack of documents. - */ - public void clear() { - Log.v(TAG, "clear: " + mDocuments.size()); - mDocuments.clear(); - } - - /** - * @return the list of document ids in the backstack. - */ - public List getDocumentIds() { - Log.v(TAG, "getDocumentIds: size: " + mDocuments.size()); - List documentIds = new ArrayList<>(); - for (BackStackDocument backStackDocument : mDocuments) { - documentIds.add(backStackDocument.getDocumentId()); - } - return documentIds; - } - - /** - * Gets the index of the most recent document with the id documentId. - * - * Note: documents are stored in ascending-recency order. That is, the order ['A','B','C'] means - * that 'C' is the most recent document. - * - * @param documentId the id to search for. - * @return the index of the most recent document in the stack matching documentId, - * or -1 if not found. - */ - int indexOf(@NonNull String documentId) { - int index = mDocuments.size() - 1; - for (Iterator itr = mDocuments.descendingIterator(); itr.hasNext();) { - if (documentId.equals(itr.next().getDocumentId())) { - return index; - } - index--; - } - - return -1; - } - - /** - * Removes all documents in the stack more recent than the most recent document with matching - * documentId and removes and returns that document. - * - * For example, if the stack is ['A','B','B','C'], then popDocuments('B') would return the document - * at index 2 and the stack would be ['A','B']. - * - * @param documentId the id of the document to return - * @return the most recent document in the stack whose document id matches the parameter. - */ - @Nullable - BackStackDocument popDocuments(@NonNull String documentId) { - Log.v(TAG, "popDocuments id: " + documentId); - int indexOfDocument = indexOf(documentId); - if (indexOfDocument == -1) { - return null; - } - return popDocumentsAtIndex(indexOfDocument); - } - - /** - * Removes all documents more recent than and including index and returns the document at index. - * - * For example, if the stack has ['A','B','C'], then both popDocumentsAtIndex(0) and - * popDocumentsAtIndex(-3) would return 'A' and the stack would be []. - * - * @param index the index of the document to return (can be negative to count backwards) - * @return the document at index. - */ - @Nullable - BackStackDocument popDocumentsAtIndex(int index) { - Log.v(TAG, "popDocuments index: " + index); - // Convert negative indexes to positive - if (index < 0) { - index = index + mDocuments.size(); - } - - if (index < 0 || index >= mDocuments.size()) { - return null; - } - - return popDocuments(mDocuments.size() - index); - } - - /** - * Removes count documents from the stack and returns the last one removed. - * - * For example, if the stack has documents ['A', 'B', 'C'], then popDocuments(2) would return 'B', - * and the stack would be: ['A']. - * - * @param count the number of documents to remove - * @return the count document in the stack - */ - @Nullable - BackStackDocument popDocuments(int count) { - Log.v(TAG, "popDocuments count: " + count + " size: " + mDocuments.size()); - if (count < 0 || count > mDocuments.size() || mDocuments.size() == 0) { - return null; - } - - for (int i = 0; i < count - 1; i++) { - mDocuments.removeLast(); - } - - return mDocuments.removeLast(); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackStackDocument.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackStackDocument.java deleted file mode 100644 index f9add018b..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/BackStackDocument.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.extension.back; - -import android.util.Log; - -import androidx.annotation.NonNull; - -import com.amazon.apl.android.DocumentState; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Maintains a document with a specified ID in the backstack. - */ -public class BackStackDocument { - private static final String TAG = BackStackDocument.class.getSimpleName(); - - /** - * The document's backstack id. - */ - @NonNull - private final String mDocumentId; - - /** - * The document's cached state. - */ - @NonNull - private final DocumentState mDocumentState; - - /** - * Map of metadata that can be attached to this document. Metadata - * could be anything that the application can use to restore the - * document. - */ - @NonNull - private final Map mDocumentExtras = new HashMap<>(8); - - /** - * Creates a BackStack document to add to the backstack. - * @param documentId the backstackId - * @param documentState the document's cached state - */ - public BackStackDocument(@NonNull final String documentId, @NonNull final DocumentState documentState) { - mDocumentId = documentId; - mDocumentState = documentState; - } - - /** - * Return the document id. - * @return the document's backstack id. - */ - @NonNull - public String getDocumentId() { - return mDocumentId; - } - - /** - * Return the cached document. - * @return the document's cached state. - */ - @NonNull - public DocumentState getDocumentState() { - return mDocumentState; - } - - /** - * Return metadata associated with this document using a key. - * @param key the key - * @return An extra attached with this document. - */ - @SuppressWarnings("unchecked") - @NonNull - public T getExtra(@NonNull String key, @NonNull T fallbackValue) { - try { - return Objects.requireNonNull((T) mDocumentExtras.get(key)); - } catch (ClassCastException e) { - Log.w(TAG, "Type mismatch for key: " + key, e); - } catch (NullPointerException e) { - Log.i(TAG, "Key not found: " + key); - } - return fallbackValue; - } - - /** - * Check if a document extra exists. - * @param key the key - * @return true if the document extra was added. - */ - public boolean hasExtra(@NonNull String key) { - return mDocumentExtras.containsKey(key); - } - - /** - * Attach additional information with this document. - * @param key the key - * @param extra additional data - * @return this for chaining - */ - public BackStackDocument putExtra(@NonNull String key, @NonNull T extra) { - mDocumentExtras.put(key, extra); - return this; - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/IBackCallback.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/IBackCallback.java deleted file mode 100644 index 76ab64301..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/back/IBackCallback.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.extension.back; - -import androidx.annotation.NonNull; - -public interface IBackCallback { - /** - * Handle a successful GoBack command. - * @param backStackDocument the document to go back to. - */ - void goBack(@NonNull BackStackDocument backStackDocument); -} \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/localinfo/LocalInfoExtension.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/localinfo/LocalInfoExtension.java deleted file mode 100644 index 28c4dba62..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/extension/localinfo/LocalInfoExtension.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.extension.localinfo; - -import android.util.Log; - -import com.amazon.apl.android.APLController; -import com.amazon.apl.android.Event; -import com.amazon.apl.android.ExtensionCommandDefinition; -import com.amazon.apl.android.ExtensionEventHandler; -import com.amazon.apl.android.RootConfig; -import com.amazon.apl.android.dependencies.IExtensionEventCallback; -import com.amazon.apl.android.providers.IExtension; -import com.amazon.apl.android.render.interfaces.ILocalInfoDataConsumer; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * This class implements a built in APL extension used by the local info - * domain to expose data to the platform. This exposes a bidirectional communication - * channel for the platfom and APL runtime to communicate. - */ -public class LocalInfoExtension implements IExtensionEventCallback, IExtension { - public static final String TAG = LocalInfoExtension.class.getSimpleName(); - public static final String URI = "aplext:localinfo:10"; - public static final String COMMAND_SEND_POI_DATA_LIST = "SendPOIDataList"; - public static final String COMMAND_SELECT_POI = "SelectPOI"; - public static final String PROPERTY_DATA_LIST = "poiDataList"; - public static final String PROPERTY_POI_ID = "poiId"; - public static final String ON_SELECT_POI_EVENT_HANDLER = "OnSelectPOI"; - - private ILocalInfoDataConsumer mDataConsumer; - private RootConfig mRootConfig; - - //------------------------------------------------------------------------- - // Constructor - //------------------------------------------------------------------------- - - public LocalInfoExtension(RootConfig rootConfig) { - mRootConfig = rootConfig; - } - - //------------------------------------------------------------------------- - // Events and commands supported by the extension - //------------------------------------------------------------------------- - - private static final List COMMANDS = new ArrayList<>(); - private static final List EVENTS = new ArrayList<>(); - - static { - COMMANDS.add(new ExtensionCommandDefinition(URI, COMMAND_SEND_POI_DATA_LIST) - .allowFastMode(true) - .property(PROPERTY_DATA_LIST, null, true)); - COMMANDS.add(new ExtensionCommandDefinition(URI, COMMAND_SELECT_POI) - .allowFastMode(true) - .property(PROPERTY_POI_ID, "", false)); - EVENTS.add(new ExtensionEventHandler(URI, ON_SELECT_POI_EVENT_HANDLER)); - } - - //------------------------------------------------------------------------- - // IExtension - //------------------------------------------------------------------------- - - @Override - public List getCommandDefinitions() { - return COMMANDS; - } - - @Override - public List getEventHandlers() { - return EVENTS; - } - - @Override - public String getUri() { - return URI; - } - - @Override - public IExtensionEventCallback getCallback() { - return this; - } - - //------------------------------------------------------------------------- - // IExtensionEventCallback - //------------------------------------------------------------------------- - - @Override - public void onExtensionEvent(String name, String uri, Event event, Map source, - Map custom, IExtensionEventCallback.IExtensionEventCallbackResult resultCallback) { - handleOnExtensionEvent(name, uri, event, source, custom, resultCallback); - } - - @Override - public void onExtensionEvent(String name, String uri, Map source, Map custom, - IExtensionEventCallback.IExtensionEventCallbackResult resultCallback) { - handleOnExtensionEvent(name, uri, null, source, custom, resultCallback); - } - - private void handleOnExtensionEvent(String name, String uri, Event event, Map source, - Map custom, IExtensionEventCallback.IExtensionEventCallbackResult resultCallback) { - Log.v(TAG, "onExtensionEvent: " + uri + "/" + name + "/" + event + "/" + source + "/" + custom); - switch (name) { - case COMMAND_SEND_POI_DATA_LIST: - sendPOIDataListHandler(custom.get(PROPERTY_DATA_LIST)); - break; - case COMMAND_SELECT_POI: - selectPoiHandler(custom.get(PROPERTY_POI_ID)); - break; - } - } - - //------------------------------------------------------------------------- - // Public methods - //------------------------------------------------------------------------- - - /** - * The platform instance that will consume local info data from extension commands. - * - * @param consumer The consumer instance. - */ - public void setDataConsumer(ILocalInfoDataConsumer consumer) { - mDataConsumer = consumer; - } - - /** - * External selection of poi data item. - * @param controller The APL runtime instance. - * @param poiId Id of the selected data item. - */ - public void poiSelected(APLController controller, String poiId) { - Map map = new HashMap<>(); - map.put("poiId", poiId); - sendEventToDoc(controller, ON_SELECT_POI_EVENT_HANDLER, map); - } - - //------------------------------------------------------------------------- - // Private methods - //------------------------------------------------------------------------- - - /** - * Handle the SendPOIDataList command. - * @param objectDataList - */ - private void sendPOIDataListHandler(Object objectDataList) { - try { - JSONArray poiDataList = new JSONArray(); - Object[] data = (Object[]) objectDataList; - for (int i = 0; i < data.length; i++) { - HashMap poiItem = (HashMap) data[i]; - JSONObject poiJson = new JSONObject(poiItem); - Log.v(TAG, "data " + poiItem); - poiDataList.put(poiJson); - } - String dataJson = poiDataList.toString(); - if (mDataConsumer != null) { - mDataConsumer.aplDataAvailable(dataJson); - Log.v(TAG, "aplDataAvailable: " + dataJson); - } - } catch (IllegalArgumentException | NullPointerException | ClassCastException e) { - Log.w(TAG, "Invalid keys in document. Doing nothing.", e); - } - } - - /** - * Notify consumer that a data item was selected through the APL document. - * - * @param poiId The id of the data item selected. - */ - private void selectPoiHandler(Object poiId) { - String poiIdString = (String) poiId; - Log.v(TAG, "selectPoiHandler" + poiIdString); - if (mDataConsumer != null) { - mDataConsumer.aplDataItemSelectedById(poiIdString); - } - } - - /** - * Send an APL extension event to the APL document. - * @param controller current APL controller - * @param handler name of the extension event handler in the doc - * @param data map of data to send in the event - */ - private void sendEventToDoc(APLController controller, String handler, Map data) { - if (controller != null) { - Log.v(TAG, "extension sending event to " + handler); - controller.invokeExtensionEventHandler(URI, handler, data, false, null); - } - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/font/AutoEmbeddedFontResolver.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/font/AutoEmbeddedFontResolver.java deleted file mode 100644 index be78e6dee..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/font/AutoEmbeddedFontResolver.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.font; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Typeface; -import android.util.Log; - -import androidx.annotation.FontRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.res.ResourcesCompat; - -import com.amazon.apl.android.font.EmbeddedFontResolver; -import com.amazon.apl.android.font.FontKey; -import com.amazon.apl.android.render.R; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * This class provides support for Bookerly Amazon fonts. The fonts must be downloaded from the - * Amazon development portal. - */ -public class AutoEmbeddedFontResolver extends EmbeddedFontResolver { - private static final String TAG = AutoEmbeddedFontResolver.class.getSimpleName(); - private static final String BOOKERLY_FONT_FAMILY = "bookerly"; - - private final Context mAppContext; - - private static class ResFontKey { - @FontRes - final int fontRes; - final int weight; - - ResFontKey(final int weight, @FontRes final int fontRes) { - this.weight = weight; - this.fontRes = fontRes; - } - } - - // Mapping of font weights to font - private static final List sFontWeights = Collections.unmodifiableList( - Arrays.asList(new ResFontKey(100, R.font.bookerly_lcd_lt), new ResFontKey(300, R.font.bookerly_lcd_rg), - new ResFontKey(600, R.font.bookerly_lcd_rg), new ResFontKey(700, R.font.bookerly_lcd_bd))); - - public AutoEmbeddedFontResolver(@NonNull final Context context) { - super(context); - mAppContext = context; - } - - /** - * If Bookerly font is requested then this method will handle - * returning the correct typeface for that font family. Otherwise - * it delegates to the parent class. - * - * @param key The requested font key. - * @return The requested font, or null if not found. - */ - @NonNull - @Override - public Typeface findFont(@NonNull FontKey key) { - Typeface result = null; - - if (key.getFamily().equalsIgnoreCase(BOOKERLY_FONT_FAMILY)) { - try { - result = findAPLFont(key); - } catch (final Resources.NotFoundException ex) { - Log.e(TAG, "Exception finding embedded app font", ex); - } - } - - if (result == null) { - Log.d(TAG, "Looking for non bookerly font"); - result = super.findFont(key); - } - - return result; - } - - @Nullable - private Typeface findAPLFont(@NonNull final FontKey key) { - // Get the closest APLFont font - int minDiff = Integer.MAX_VALUE; - AutoEmbeddedFontResolver.ResFontKey bestKey = null; - List fontWeights = sFontWeights; - - for (final AutoEmbeddedFontResolver.ResFontKey currentKey : fontWeights) { - final int currentWeight = currentKey.weight; - - if (minDiff > Math.abs(currentWeight - key.getWeight())) { - minDiff = Math.abs(currentWeight - key.getWeight()); - bestKey = currentKey; - } - } - - if (bestKey != null) { - Log.i(TAG, "Best key: " + bestKey.weight + " requested: " + key.getWeight()); - final Typeface result = ResourcesCompat.getFont(mAppContext, bestKey.fontRes); - if (key.isItalic()) { - return Typeface.create(result, Typeface.ITALIC); - } - return result; - } - - return null; - } -} \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLContentListener.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLContentListener.java deleted file mode 100644 index 847ae8be8..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLContentListener.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.interfaces; - -import androidx.annotation.NonNull; - -/** - * Interface for proving APL directive content such render document and - * execute commands payload to the runtime. - */ -public interface IAPLContentListener { - /** - * Notifies that a @c RenderDocument directive has been received. Once called, the - * client should render the document based on the APL specification in the payload in structured JSON format. - * - * @note The payload may contain customer sensitive information and should be used with utmost care. - * Failure to do so may result in exposing or mishandling of customer data. - * - * @param [in] jsonPayload The payload of the Alexa.Presentation.APL.RenderDocument directive which follows the APL - * specification. - * @param [in] token The APL presentation token associated with the document in the payload. - * @param [in] windowId The target windowId. - */ - public void onRenderDocument(String jsonPayload, String token, String windowId); - - /** - * Notifies when the client should clear the APL display card. - * Once the card is cleared, the platform implementation should call clearCard(). - * - * @param [in] token The APL presentation token associated with the current rendered document. - */ - public void onClearDocument(String token); - - /** - * Notifies that an ExecuteCommands directive has been received. - * - * @param [in] jsonPayload The payload of the Alexa.Presentation.APL.ExecuteCommands directive in structured JSON - * format. - * @param [in] token The APL presentation token associated with the current rendered document. - */ - public void onExecuteCommands(String jsonPayload, String token); - - /** - * Notifies of a dynamic data source update. Please refer to - * APL documentation for more information. - * - * https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-data-source.html - * - * @param [in] sourceType DataSource type. - * @param [in] jsonPayload The payload of the directive in structured JSON format. - * @param [in] token The APL presentation token associated with the current rendered document. - */ - public void onDataSourceUpdate(String sourceType, String jsonPayload, String token); - - /** - * Notifies that a command execution sequence should be interrupted. - * - * @param [in] token The APL presentation token associated with the current rendered document. - */ - public void onInterruptCommandSequence(String token); - - /** - * Notifies that APL runtime properties should be changed on the rendered document. - * @param properties JSON string containing one or more properties. - * @code{.json} - * { - * "drivingState" : "parked|moving", - * "theme" : "light|light-gray1|light-gray2|dark|dark-black|dark-gray", - * "video" : "enabled|disabled" - * } - * @endcode - */ - public void onAPLRuntimeProperties(String properties); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLEventSender.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLEventSender.java deleted file mode 100644 index e7aa84939..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLEventSender.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.interfaces; - -/** - * Interface to emit APL related events such as data fetch, user, - * runtime error, activity, etc. - */ -public interface IAPLEventSender { - /** - * Enumeration of activity events that could be sent from GUI to @c AlexaPresentation. - */ - public enum ActivityEvent { - /** - * GUI switched to active state. - * @hideinitializer - */ - ACTIVATED("ACTIVATED"), - /** - * GUI become inactive. - * @hideinitializer - */ - DEACTIVATED("DEACTIVATED"), - /** - * GUI processed one-time event (touch/scroll/etc). - * @hideinitializer - */ - ONE_TIME("ONE_TIME"), - /** - * Interrupt event (touch). - * @hideinitializer - */ - INTERRUPT("INTERRUPT"), - /** - * Guard option for unknown received state. - * @hideinitializer - */ - UNKNOWN("UNKNOWN"); - - /** - * @internal - */ - private String m_name; - - /** - * @internal - */ - private ActivityEvent(String name) { - m_name = name; - } - - /** - * @internal - */ - public String toString() { - return m_name; - } - } - - /** - * Notifies to clear the card from the screen and release any focus being held. - */ - public void sendClearCard(); - - /** - * Notifies to clear all pending ExecuteCommands directives and mark them as failed. - */ - public void sendClearAllExecuteCommands(); - - /** - * Notifies to send @c UserEvent event to AVS. - * - * https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-interface.html#userevent-request - * - * @param payload The @c UserEvent event payload. The caller of this - * function is responsible to pass the payload as it defined by AVS. - */ - public void sendUserEventRequest(String payload); - - /** - * Notifies to send a @c LoadIndexListData event to AVS. - * - * https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-interface.html#loadindexlistdata-request - * https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-data-source.html - * - * @param type The type of data source fetch request. The only supported value is "dynamicIndexList". - * @param payload The @c DataSourceFetchRequest event payload. The caller of this - * function is responsible to pass the payload as defined by AVS. - */ - public void sendDataSourceFetchEventRequest(String type, String payload); - - /** - * Notifies the Engine to send an APL @c RuntimeError event to AVS - * - * https://developer.amazon.com/en-US/docs/alexa/alexa-presentation-language/apl-interface.html#runtimeerror-request - * - * @param payload The @c RuntimeError event payload. The caller of this - * function is responsible to pass the payload as defined by AVS. - */ - public void sendRuntimeErrorEventRequest(String payload); - - /** - * Notifies the result of a @c renderDocument notification. - * - * @param token The APL presentation token associated with the current rendered document. - * @param result Rendering result (true on executed, false on exception). - * @param error Error message provided in case result is false. - */ - public void sendRenderDocumentResult(String token, boolean result, String error); - - /** - * Notifies the result of an @c executeCommands notification. - * - * @param token The APL presentation token associated with the current rendered document. - * @param result Rendering result (true on executed, false on exception). - * @param error Error message provided in case result is false. - */ - public void sendExecuteCommandsResult(String token, boolean result, String error); - - /** - * The APL runtime can report whether the rendered document is active or inactive. If active, - * the idle timer is stopped and prevents @c clearDocument. If inactive, the - * idle timer is started and @c clearDocument will be called after timer expiration. - * - * @param token The APL presentation token associated with the current rendered document. - * @param event The activity change event. - */ - public void sendActivityEventRequest(String token, ActivityEvent event); - - /** - * Sends the current visual context reported by the APL runtime. It is a JSON object containing - * the presentation token, and components visible on screen. - * - * @param context The visual context. - */ - public void sendContext(String context); - - /** - * Sends the current device window state. - * - * https://developer.amazon.com/en-US/docs/alexa/alexa-voice-service/display-window.html#windowstate-context-object - * - * @param state The payload for the device window state. - */ - public void sendWindowState(String state); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLOptionsBuilderProvider.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLOptionsBuilderProvider.java deleted file mode 100644 index 4bada384e..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLOptionsBuilderProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.interfaces; - -import androidx.annotation.NonNull; - -import com.amazon.apl.android.APLOptions; - -/** - * Interface to provide an APL options builder object. The builder - * can be used to override any of the data provides, callback handlers, etc. - */ -public interface IAPLOptionsBuilderProvider { - @NonNull - APLOptions.Builder getAPLOptionsBuilder(); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLTokenProvider.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLTokenProvider.java deleted file mode 100644 index 8b2014c05..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IAPLTokenProvider.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.interfaces; - -/** - * Provides the APL token for the current rendered document. - */ -public interface IAPLTokenProvider { - /** - * Returns the APL token. - * @return String The APL token. - */ - String getToken(); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IDismissible.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IDismissible.java deleted file mode 100644 index 1fee143b1..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IDismissible.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.interfaces; - -/** - * Interface for notifying application UI when to dismiss. - */ -public interface IDismissible { - /** - * Callback to be called for dismissing. - */ - void onDismiss(); -} \ No newline at end of file diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/ILocalInfoDataConsumer.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/ILocalInfoDataConsumer.java deleted file mode 100644 index 2516fb3f3..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/ILocalInfoDataConsumer.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.interfaces; - -/** - * This interface allows the platform to be notified when local info data - * is available or selected inside the APL document. - */ -public interface ILocalInfoDataConsumer { - /** - * Notifies the platform that the APL document contains local info data. - * - * @param data The list of data items containing - * @code{.json} - * [ - * { - * "id" : "", - * "name" : "", - * "coordinate" : { - * "latitude" : , - * "longitude : - * } - * } - * ] - * @endcode - * @li id The identifier for the POI data item. - * @li name The name associated with the POI data item. - * @li coordinate A JSON object containing the geocoordinates for the POI data item. - */ - void aplDataAvailable(String data); - - /** - * Notifies the platform that a POI data item was selected in the APL document. This - * allows the platform to highlight the selected data item. - * - * @param id The identifier for the selected POI data item. - */ - void aplDataItemSelectedById(String id); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/ILocalInfoDataReporter.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/ILocalInfoDataReporter.java deleted file mode 100644 index 01e213b7f..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/ILocalInfoDataReporter.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.interfaces; - -/** - * Interface used for allowing platform to report changes in local info - * that can affect the APL document. - */ -public interface ILocalInfoDataReporter { - /** - * Notifies the APL extension that a POI data item was selected by the platform. - * This allows the APL document to be updated to show details for the selected - * data item. - * - * @param id The identifier for the selected POI data item. - */ - void platformDataItemSelectedById(String id); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IPresenter.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IPresenter.java deleted file mode 100644 index 6615167fb..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/interfaces/IPresenter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.interfaces; - -import android.view.KeyEvent; -import android.view.MotionEvent; - -import com.amazon.apl.android.APLLayout; -import com.amazon.apl.android.IDocumentLifecycleListener; -import com.amazon.apl.android.dependencies.IOnAplFinishCallback; - -/** - * The presenter interface. - */ -public interface IPresenter - extends IAPLContentListener, IOnAplFinishCallback, IAPLOptionsBuilderProvider, IDocumentLifecycleListener { - /** - * Indicates that the user has touched the screen. - * @param event the touch event. - * - * @return whether the touch event was handled in APL layout. - */ - void onTouchEvent(MotionEvent event); - - /** - * Indicates that the user has pressed a keypad button. - * @param event the key event. - * - * @return whether the key event was handled in APL layout. - */ - boolean onKeyEvent(KeyEvent event); - - /** - * @return the APLLayout where the APL document is to be rendered. - */ - APLLayout getAplLayout(); - - /** - * Return the APL event sender. - * @return - */ - IAPLEventSender getAplEventSender(); - - /** - * Saves a reference to the local info data consumer. - * - * @param consumer The object that consume local info data events. - */ - void setLocalInfoDataConsumer(ILocalInfoDataConsumer consumer); - - /** - * Callback to notify when APL window should be dismissed. - * @param dismissibleCallback - */ - void setDismissibleCallback(IDismissible dismissibleCallback); - - /** - * This should be called to stop execution when there is a barge in. - */ - void cancelExecution(); -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/media/APLMediaPlayer.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/media/APLMediaPlayer.java deleted file mode 100644 index 4a771a3c4..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/media/APLMediaPlayer.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.apl.android.render.media; - -import android.content.Context; -import android.media.AudioManager; -import android.util.Log; -import android.view.TextureView; - -import androidx.annotation.NonNull; - -import com.amazon.apl.android.dependencies.impl.MediaPlayer; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; -import com.amazon.apl.android.render.interfaces.IAPLTokenProvider; - -/** - * Provides a wrapper of the MediaPlayer player that can report activity events. - * The Media player is used for playing video content. Android audio focus - * management is built into the base MediaPlayer class. - */ -public class APLMediaPlayer extends MediaPlayer { - private static final String TAG = APLMediaPlayer.class.getSimpleName(); - - private final IAPLEventSender mAplEventSender; - private final IAPLTokenProvider mAplTokenProvider; - - public APLMediaPlayer(@NonNull Context context, @NonNull TextureView view, @NonNull IAPLEventSender aplEventSender, - @NonNull IAPLTokenProvider aplTokenProvider) { - super(context, view); - Log.v(TAG, "Created"); - mAplEventSender = aplEventSender; - mAplTokenProvider = aplTokenProvider; - } - - /** - * {@inheritDoc} - */ - @Override - public void play() { - Log.v(TAG, "play:"); - super.play(); - mAplEventSender.sendActivityEventRequest(mAplTokenProvider.getToken(), IAPLEventSender.ActivityEvent.ACTIVATED); - } - - /** - * {@inheritDoc} - */ - @Override - public void stop() { - Log.v(TAG, "stop:"); - super.stop(); - mAplEventSender.sendActivityEventRequest( - mAplTokenProvider.getToken(), IAPLEventSender.ActivityEvent.DEACTIVATED); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/media/APLMediaPlayerProvider.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/media/APLMediaPlayerProvider.java deleted file mode 100644 index f564aef3e..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/media/APLMediaPlayerProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.amazon.apl.android.render.media; - -import android.content.Context; -import android.view.TextureView; - -import androidx.annotation.NonNull; - -import com.amazon.apl.android.dependencies.IMediaPlayer; -import com.amazon.apl.android.providers.impl.MediaPlayerProvider; -import com.amazon.apl.android.render.interfaces.IAPLEventSender; -import com.amazon.apl.android.render.interfaces.IAPLTokenProvider; - -/** - * This class extends the Media provider that is used by the - * Android view host to create a Media player instance. - */ -public class APLMediaPlayerProvider extends MediaPlayerProvider { - private final IAPLEventSender mAplEventSender; - private final IAPLTokenProvider mAplTokenProvider; - - public APLMediaPlayerProvider( - @NonNull IAPLEventSender aplEventSender, @NonNull IAPLTokenProvider aplTokenProvider) { - super(); - mAplEventSender = aplEventSender; - mAplTokenProvider = aplTokenProvider; - } - - @NonNull - public IMediaPlayer createPlayer(@NonNull Context context, @NonNull TextureView view) { - return new APLMediaPlayer(context, view, mAplEventSender, mAplTokenProvider); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/network/NetworkExecutor.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/network/NetworkExecutor.java deleted file mode 100644 index 933d8b85a..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/network/NetworkExecutor.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.network; - -import com.amazon.apl.android.thread.SequentialExecutor; -import com.amazon.apl.android.thread.Threading; - -/** - * Provides a {@link SequentialExecutor} for use in network calls. - */ -public class NetworkExecutor extends SequentialExecutor { - public NetworkExecutor() { - super(Threading.createSequentialExecutor()); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/network/OkHttpClientWrapper.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/network/OkHttpClientWrapper.java deleted file mode 100644 index 23f8e63a9..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/network/OkHttpClientWrapper.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.network; - -import android.util.Log; - -import java.io.IOException; -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; - -import dagger.Lazy; -import okhttp3.CacheControl; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -/** - * Wrapper around {@link OkHttpClient} to facilitate reading from cache first and refreshing later. - */ -public class OkHttpClientWrapper { - private static final String TAG = OkHttpClientWrapper.class.getSimpleName(); - - public static final String CLOUDFRONT_LOCATION_PREFIX = "https://d2na8397m465mh.cloudfront.net/packages/"; - - private final Lazy mOkHttpClient; - private final Set mRefreshUrls = Collections.newSetFromMap(new ConcurrentHashMap<>()); - - private static final String[] PREFER_CACHE_LIST = {CLOUDFRONT_LOCATION_PREFIX + "alexa-layouts", - CLOUDFRONT_LOCATION_PREFIX + "alexa-styles", CLOUDFRONT_LOCATION_PREFIX + "alexa-viewport-profiles"}; - - /** - * Constructor for wrapper around {@link OkHttpClient}. - * @param client the {@link OkHttpClient} to wrap. - */ - public OkHttpClientWrapper(final Lazy client) { - mOkHttpClient = client; - } - - /** - * Initialize the {@link OkHttpClient} client. - */ - public void init() { - mOkHttpClient.get(); - } - - /** - * Requests a url for download. - * - * If the url is a preferred url, then we use the cached copy immediately and add it to a set of - * urls to refresh via {@link #refreshCache()}, otherwise it defaults to the standard {@link OkHttpClient} - * cache policy: https://square.github.io/okhttp/caching/ - * - * @param url the url to fetch. - * @return the callback when finished. - */ - public Call newCall(final String url) { - return newCall(url, isOnCacheList(url)); - } - - /** - * Cancel all pending requests. - */ - public void cancelAll() { - mOkHttpClient.get().dispatcher().cancelAll(); - } - - /** - * Refreshes documents in the cache that were requested but bypassed network calls to check staleness. - */ - public void refreshCache() { - for (final String url : mRefreshUrls) { - newCall(url, false).enqueue(new Callback() { - @Override - public void onFailure(Call call, IOException e) { - Log.d(TAG, url + " fail."); - } - - @Override - public void onResponse(Call call, Response response) throws IOException { - Log.d(TAG, url + " success."); - } - }); - mRefreshUrls.remove(url); - } - } - - private Call newCall(final String url, final boolean preferCache) { - return mOkHttpClient.get().newCall(buildRequest(url, preferCache)); - } - - private Request buildRequest(final String url, final boolean preferCache) { - Request.Builder requestBuilder = new Request.Builder().url(url); - if (preferCache) { - mRefreshUrls.add(url); - requestBuilder.cacheControl(new CacheControl.Builder().maxStale(14, TimeUnit.DAYS).build()); - } - return requestBuilder.build(); - } - - private static boolean isOnCacheList(String url) { - for (String refreshUrls : PREFER_CACHE_LIST) { - if (url.startsWith(refreshUrls)) { - return true; - } - } - return false; - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/APLPayload.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/APLPayload.java deleted file mode 100644 index 25f837d27..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/APLPayload.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.payload; - -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * Base class for an APL payload. - */ -@AllArgsConstructor -@Getter -public abstract class APLPayload { - private static final String TAG = APLPayload.class.getSimpleName(); - - public static final String FIELD_PRESENTATION_TOKEN = "presentationToken"; - - /** - * Identifier for the payload. - */ - private final String mPresentationToken; - - protected JSONObject toJson() throws JSONException { - return new JSONObject().put(FIELD_PRESENTATION_TOKEN, mPresentationToken); - } - - public String toString() { - try { - return toJson().toString(); - } catch (JSONException e) { - Log.wtf(TAG, e); - return ""; - } - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/ExecuteCommandPayload.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/ExecuteCommandPayload.java deleted file mode 100644 index 08b08cba9..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/ExecuteCommandPayload.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.payload; - -import org.json.JSONException; -import org.json.JSONObject; - -import lombok.Builder; -import lombok.Getter; - -/** - * Represents a Render Document directive payload. The directive looks like the following: - *

- *     {@code
- *  {
- *           "header":{
- *              "namespace":"Alexa.Presentation.APL",
- *               "name":"executeCommands",
- *               "eventId":,
- *               "messageId":
- *           },
- *           "payload":{
- *               "presentationToken": STRING, //eg.
- * amzn1.as-tt.v1.ThirdPartySdkSpeechlet#TID#a974fcff-963f-4585-8d6e-5597b2eaadab "commands": 
- *           }
- *   }
- * }
- * 
- */ -@Getter -public class ExecuteCommandPayload extends APLPayload { - /** - * Commands in the payload. - */ - private final String mCommands; - public static final String FIELD_COMMANDS = "commands"; - - @Builder - public ExecuteCommandPayload(final String presentationToken, final String commands) { - super(presentationToken); - mCommands = commands; - } - - public JSONObject toJson() throws JSONException { - return super.toJson().put(FIELD_COMMANDS, mCommands); - } - - /** - * TODO move this into {@link ExecuteCommandPayload} and add tests - */ - public static ExecuteCommandPayload convertToExecuteCommand(final String payload) throws JSONException { - JSONObject jsonPayload = new JSONObject(payload); - return ExecuteCommandPayload.builder() - .presentationToken(jsonPayload.optString("presentationToken", "")) - .commands(jsonPayload.optString("commands", "")) - .build(); - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/PresentationSession.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/PresentationSession.java deleted file mode 100644 index 88b44b9cb..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/PresentationSession.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.payload; - -import android.text.TextUtils; -import android.util.Log; - -import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; - -import com.amazon.apl.android.render.utils.RenderDocumentUtils; - -import org.json.JSONException; -import org.json.JSONObject; - -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NonNull; - -/** - * Presentation Session Information included in a RenderDocumentPayload. - * - */ -@Getter -@EqualsAndHashCode -@Builder -public class PresentationSession { - private static final String TAG = PresentationSession.class.getSimpleName(); - public static final String FIELD_SKILL_ID = "skillId"; - public static final String FIELD_ID = "id"; - - @Builder.Default - private final String mSkillId = ""; - @Builder.Default - private final String mId = ""; - - /** - * Build a PresentationSession from a JSONObject with a fallback for using the PresentationToken. - * @param sessionJson the presentation session json - * @param presentationToken the presentation presentationToken - * @return a new PresentationSession - */ - @NonNull - public static PresentationSession get(JSONObject sessionJson, String presentationToken) { - PresentationSession fromJson = fromJson(sessionJson); - if (fromJson == null) { - Log.i(TAG, - "Error extracting presentation session from payload. Falling back to parsing presentation token."); - return fromToken(presentationToken); - } - - return fromJson; - } - - /** - * Build a PresentationSession from a JSONObject. - * @param sessionJson the presentation session json - * @return a new PresentationSession or null if session json is null of malformed. - */ - @Nullable - public static PresentationSession fromJson(@Nullable JSONObject sessionJson) { - if (sessionJson == null) { - return null; - } - try { - return PresentationSession.builder() - .skillId(sessionJson.getString(FIELD_SKILL_ID)) - .id(sessionJson.getString(FIELD_ID)) - .build(); - } catch (JSONException e) { - return null; - } - } - - @NonNull - private static PresentationSession fromToken(String presentationToken) { - final String clientId = RenderDocumentUtils.getClientId(presentationToken); - String skillId = ""; - if (TextUtils.equals(RenderDocumentUtils.SKILL_CLIENT_ID, clientId)) { - skillId = RenderDocumentUtils.getSkillId(presentationToken); - } - - return PresentationSession.builder().skillId(clientId).id(skillId).build(); - } - - /** - * @return this presentation session as a JSONObject. - */ - public JSONObject toJson() throws JSONException { - return new JSONObject().put(FIELD_SKILL_ID, getSkillId()).put(FIELD_ID, getId()); - } - - public String toString() { - try { - return toJson().toString(); - } catch (JSONException e) { - Log.wtf(TAG, e); - return ""; - } - } -} diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/RenderDocumentPayload.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/RenderDocumentPayload.java deleted file mode 100644 index 9e83afdb1..000000000 --- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/RenderDocumentPayload.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). - * You may not use this file except in compliance with the License. - * A copy of the License is located at - * - * http://aws.amazon.com/apache2.0/ - * - * or in the "license" file accompanying this file. This file is distributed - * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.amazon.apl.android.render.payload; - -import com.amazon.apl.android.scaling.Scaling; -import com.amazon.apl.enums.ViewportMode; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import lombok.Builder; -import lombok.Getter; -import lombok.NonNull; - -/** - * Represents a Render Document directive payload. The directive looks like the following: - * - *
- *     {@code
- *  {
- *           "header":{
- *              "namespace":"Alexa.Presentation.APL",
- *               "name":"RenderDocument",
- *               "eventId":,
- *               "messageId":
- *           },
- *           "payload":{
- *               "presentationToken": STRING, //eg.
- * amzn1.as-tt.v1.ThirdPartySdkSpeechlet#TID#a974fcff-963f-4585-8d6e-5597b2eaadab "presentationSession": { "skillId":
- * String, "id": String
- *               },
- *               "document": ,       // APL Document
- *               "datasources":,     // Data sources
- *               "windowId": STRING
- *           }
- *   }
- * }
- * 
- */
-@Getter
-public class RenderDocumentPayload extends APLPayload {
-    private static final String TAG = RenderDocumentPayload.class.getSimpleName();
-
-    private static final Map MODE_MAP = new HashMap() {
-        {
-            put("HUB", ViewportMode.kViewportModeHub);
-            put("TV", ViewportMode.kViewportModeTV);
-            put("PC", ViewportMode.kViewportModePC);
-            put("AUTO", ViewportMode.kViewportModeAuto);
-            put("MOBILE", ViewportMode.kViewportModeMobile);
-        }
-    };
-
-    public static final float BIAS_CONSTANT = 10.0f;
-
-    public static final String FIELD_DATASOURCES = "datasources";
-    public static final String FIELD_DOCUMENT = "document";
-    public static final String FIELD_TIMEOUT_TYPE = "timeoutType";
-    public static final String FIELD_WINDOW_ID = "windowId";
-    public static final String FIELD_SUPPORTED_VIEWPORTS = "supportedViewports";
-    public static final String FIELD_PRESENTATION_SESSION = "presentationSession";
-    public static final String FIELD_EXTENSIONS = "extensions";
-
-    private static final String FIELD_EMPTY_FALLBACK_VALUE = "";
-
-    /**
-     * Bindable metadata
-     */
-    private final JSONObject mDataSources;
-
-    /**
-     * A document to render.
-     */
-    private final String mDocument;
-
-    /**
-     * Document timeout type
-     */
-    private final TimeoutType mTimeoutType;
-
-    /**
-     * Viewport Specifications
-     */
-    private final JSONArray mSupportedViewports;
-
-    /**
-     * Used for partial screen
-     */
-    private final String mWindowId;
-
-    /**
-     * PresentationSession used to determine if a directive should launch a new Activity.
-     */
-    private final PresentationSession mPresentationSession;
-
-    @Builder
-    public RenderDocumentPayload(String presentationToken, TimeoutType timeoutType, String document, String windowId,
-            JSONObject dataSources, JSONArray supportedViewports, PresentationSession presentationSession) {
-        super(presentationToken);
-        mDocument = document;
-        mTimeoutType = timeoutType;
-        mWindowId = windowId;
-        mDataSources = dataSources;
-        mSupportedViewports = supportedViewports;
-        mPresentationSession = presentationSession;
-    }
-
-    /**
-     * Gets the supported viewports from this directive. If "supported viewports" was not part of the directive, this
-     * returns an empty list.
-     */
-    @NonNull
-    public final List getViewportSpecifications() {
-        if (mSupportedViewports == null) {
-            return Collections.emptyList();
-        }
-        List viewports = new ArrayList<>();
-
-        try {
-            for (int i = 0; i < mSupportedViewports.length(); i++) {
-                final JSONObject viewport = mSupportedViewports.getJSONObject(i);
-                final int wmin = viewport.optInt("minWidth", 1);
-                final int wmax = viewport.optInt("maxWidth", Integer.MAX_VALUE);
-                final int hmin = viewport.optInt("minHeight", 1);
-                final int hmax = viewport.optInt("maxHeight", Integer.MAX_VALUE);
-                final boolean isRound = viewport.getString("shape").equals("ROUND");
-                ViewportMode mode = MODE_MAP.get(viewport.getString("mode"));
-                mode = mode == null ? ViewportMode.kViewportModeHub : mode;
-                viewports.add(Scaling.ViewportSpecification.builder()
-                                      .minWidth(wmin)
-                                      .maxWidth(wmax)
-                                      .minHeight(hmin)
-                                      .maxHeight(hmax)
-                                      .round(isRound)
-                                      .mode(mode)
-                                      .build());
-            }
-            return viewports;
-        } catch (JSONException ex) {
-            return Collections.emptyList();
-        }
-    }
-
-    /**
-     * Converts a JSONObject payload to a {@link RenderDocumentPayload}.
-     *
-     * @param payload a RenderDocumentPayload
-     * @return a RenderDocumentPayload
-     */
-    @NonNull
-    public static RenderDocumentPayload fromJson(@NonNull JSONObject payload) {
-        String presentationToken = payload.optString(FIELD_PRESENTATION_TOKEN, FIELD_EMPTY_FALLBACK_VALUE);
-        return RenderDocumentPayload.builder()
-                .presentationToken(presentationToken)
-                .timeoutType(TimeoutType.getTimeoutType(payload.optString(FIELD_TIMEOUT_TYPE)))
-                .dataSources(payload.optJSONObject(FIELD_DATASOURCES))
-                .document(payload.optString(FIELD_DOCUMENT, FIELD_EMPTY_FALLBACK_VALUE))
-                .supportedViewports(payload.optJSONArray(FIELD_SUPPORTED_VIEWPORTS))
-                .windowId(payload.optString(FIELD_WINDOW_ID, FIELD_EMPTY_FALLBACK_VALUE))
-                .presentationSession(
-                        PresentationSession.get(payload.optJSONObject(FIELD_PRESENTATION_SESSION), presentationToken))
-                .build();
-    }
-
-    public JSONObject toJson() throws JSONException {
-        return super.toJson()
-                .put(FIELD_TIMEOUT_TYPE, getTimeoutType())
-                .put(FIELD_DOCUMENT, getDocument())
-                .put(FIELD_DATASOURCES, getDataSources())
-                .put(FIELD_PRESENTATION_SESSION,
-                        getPresentationSession() != null ? getPresentationSession().toJson() : null)
-                .put(FIELD_SUPPORTED_VIEWPORTS, getSupportedViewports())
-                .put(FIELD_WINDOW_ID, getWindowId());
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/RenderedDocumentStatePayload.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/RenderedDocumentStatePayload.java
deleted file mode 100644
index 43431d64d..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/RenderedDocumentStatePayload.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.apl.android.render.payload;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import lombok.Builder;
-import lombok.Getter;
-
-/**
- * Represents the device context state of an APML payload
- */
-@Getter
-public class RenderedDocumentStatePayload extends APLPayload {
-    // For some reason, the key for PresentationToken in RenderedDocumentState is "token" and not "presentationToken"
-    public static final String FIELD_TOKEN = "token";
-    public static final String FIELD_COMPONENTS_VISIBLE_ON_SCREEN = "componentsVisibleOnScreen";
-    public static final String FIELD_VERSION = "version";
-
-    private final String mVersionName;
-    private final PresentationSession mPresentationSession;
-    private final JSONArray mComponentsVisibleOnScreenArray;
-
-    @Builder
-    public RenderedDocumentStatePayload(String presentationToken, String versionName,
-            PresentationSession presentationSession, JSONArray componentsVisibleOnScreenArray) {
-        super(presentationToken);
-        mVersionName = versionName;
-        mPresentationSession = presentationSession;
-        mComponentsVisibleOnScreenArray = componentsVisibleOnScreenArray;
-    }
-
-    public JSONObject toJson() throws JSONException {
-        return new JSONObject()
-                .put(FIELD_TOKEN, getPresentationToken())
-                .put(RenderDocumentPayload.FIELD_PRESENTATION_SESSION, mPresentationSession.toJson())
-                .put(FIELD_VERSION, mVersionName)
-                .put(FIELD_COMPONENTS_VISIBLE_ON_SCREEN, mComponentsVisibleOnScreenArray);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/TimeoutType.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/TimeoutType.java
deleted file mode 100644
index 21aec969a..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/TimeoutType.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.apl.android.render.payload;
-
-/**
- * Supported timeout types in an APL document.
- *
- * https://developer.amazon.com/en-US/docs/alexa/alexa-voice-service/presentation-apl.html#renderdocument
- */
-public enum TimeoutType {
-    SHORT(0),
-    LONG(1),
-    TRANSIENT(4);
-    private int timeoutFlag;
-    private static final String TIMEOUT_LONG = "LONG";
-    private static final String TIMEOUT_TRANSIENT = "TRANSIENT";
-
-    /**
-     * Returns the flag associated with TimeoutType.
-     * @return the timeout flag {@link TimeoutPolicy flags}
-     */
-    public int getTimeoutFlag() {
-        return this.timeoutFlag;
-    }
-
-    public static TimeoutType getTimeoutType(String timeoutType) {
-        switch (timeoutType) {
-            case TIMEOUT_LONG:
-                return TimeoutType.LONG;
-            case TIMEOUT_TRANSIENT:
-                return TimeoutType.TRANSIENT;
-            default:
-                return TimeoutType.SHORT;
-        }
-    }
-
-    TimeoutType(int timeoutFlag) {
-        this.timeoutFlag = timeoutFlag;
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/UserEventPayload.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/UserEventPayload.java
deleted file mode 100644
index 6ddd8ab1b..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/payload/UserEventPayload.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.apl.android.render.payload;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import lombok.Getter;
-
-/**
- * Represents the payload of User Event.
- */
-@Getter
-public class UserEventPayload {
-    private static final String PRESENTATION_TOKEN = "presentationToken";
-    private static final String ARGUMENTS = "arguments";
-    private static final String SOURCE = "source";
-    private static final String COMPONENTS = "components";
-
-    private final String mPresentationToken;
-    private final JSONArray mArguments;
-    private final JSONObject mSource;
-    private final JSONObject mComponents;
-
-    public static UserEventPayload fromJson(final JSONObject object) throws JSONException {
-        return new UserEventPayload(object.getString(PRESENTATION_TOKEN), object.optJSONArray(ARGUMENTS),
-                object.optJSONObject(SOURCE), object.optJSONObject(COMPONENTS));
-    }
-
-    public UserEventPayload(final String presentationToken, final JSONArray arguments, final JSONObject components,
-            final JSONObject source) {
-        mPresentationToken = presentationToken;
-        mArguments = arguments;
-        mComponents = components;
-        mSource = source;
-    }
-
-    public JSONObject toJson() throws JSONException {
-        return new JSONObject()
-                .put(PRESENTATION_TOKEN, mPresentationToken)
-                .put(ARGUMENTS, mArguments)
-                .put(SOURCE, mSource)
-                .put(COMPONENTS, mComponents);
-    }
-
-    @Override
-    public String toString() {
-        try {
-            return toJson().toString();
-        } catch (JSONException e) {
-            return "{\"warning\":\"serialization error\"}";
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/tts/APLTtsPlayer.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/tts/APLTtsPlayer.java
deleted file mode 100644
index 61cab1c74..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/tts/APLTtsPlayer.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.apl.android.render.tts;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.amazon.apl.android.render.audio.AudioFocusController;
-import com.amazon.apl.android.render.interfaces.IAPLEventSender;
-import com.amazon.apl.android.render.interfaces.IAPLTokenProvider;
-import com.amazon.apl.player.audio.AudioPlayer;
-import com.amazon.apl.player.tts.TtsPlayer;
-
-/**
- * Provides a wrapper of the TTS player that can report activity events
- * and request Android audio focus.
- */
-public class APLTtsPlayer extends TtsPlayer implements AudioFocusController.PlaybackController {
-    private static final String TAG = APLTtsPlayer.class.getSimpleName();
-
-    private final IAPLEventSender mAplEventSender;
-    private final IAPLTokenProvider mAplTokenProvider;
-    private final AudioFocusController mAudioFocusController;
-
-    public APLTtsPlayer(@NonNull Context context, @NonNull IAPLEventSender aplEventSender,
-            @NonNull IAPLTokenProvider aplTokenProvider) {
-        super(context);
-        mAplEventSender = aplEventSender;
-        mAplTokenProvider = aplTokenProvider;
-        AudioManager audioManager =
-                (AudioManager) context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
-        mAudioFocusController = new AudioFocusController(audioManager, this);
-    }
-
-    @Override
-    public void play() {
-        Log.v(TAG, "play: intercepted for audio focus");
-        mAudioFocusController.startPlaybackAfterAcquiringFocus();
-    }
-
-    @Override
-    public void onPlayerStateChanged(boolean playWhenReady, @NonNull AudioPlayer.AudioPlayerState state) {
-        Log.v(TAG, playWhenReady + " state: " + state);
-
-        if (state == AudioPlayer.AudioPlayerState.STATE_PREPARING) {
-            Log.v(TAG, "Acquire APL focus");
-        } else if (state == AudioPlayer.AudioPlayerState.STATE_ENDED
-                || state == AudioPlayer.AudioPlayerState.STATE_IDLE) {
-            mAplEventSender.sendActivityEventRequest(
-                    mAplTokenProvider.getToken(), IAPLEventSender.ActivityEvent.DEACTIVATED);
-            Log.v(TAG, "Release APL focus");
-            mAudioFocusController.relinquishAudioFocusIfCurrentlyAcquired();
-        } else if (state == AudioPlayer.AudioPlayerState.STATE_READY) {
-            mAplEventSender.sendActivityEventRequest(
-                    mAplTokenProvider.getToken(), IAPLEventSender.ActivityEvent.ACTIVATED);
-        }
-
-        super.onPlayerStateChanged(playWhenReady, state);
-    }
-
-    @Override
-    public void startPlaybackNow() {
-        Log.v(TAG, "startPlaybackNow: ");
-        super.play();
-    }
-
-    @Override
-    public void requestResumingPlayback() {
-        Log.v(TAG, "requestResumingPlayback: ");
-        super.play();
-    }
-
-    @Override
-    public void requestPausePlayback() {
-        Log.v(TAG, "requestPausePlayback: ");
-        super.stop();
-    }
-
-    @Override
-    public void requestStopPlayback() {
-        Log.v(TAG, "requestStopPlayback: ");
-        super.stop();
-    }
-
-    @Override
-    public void adjustPlaybackVolume(float volumeMultiplier) {
-        Log.v(TAG, "adjustPlaybackVolume: " + volumeMultiplier);
-    }
-
-    @Override
-    public void failedToAcquireFocus() {
-        Log.e(TAG, "failedToAcquireFocus: ");
-        super.stop();
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/tts/APLTtsPlayerProvider.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/tts/APLTtsPlayerProvider.java
deleted file mode 100644
index dd8399ca8..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/tts/APLTtsPlayerProvider.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.apl.android.render.tts;
-
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.amazon.apl.android.dependencies.ITtsPlayer;
-import com.amazon.apl.android.dependencies.ITtsSourceProvider;
-import com.amazon.apl.android.providers.ITtsPlayerProvider;
-import com.amazon.apl.android.render.interfaces.IAPLEventSender;
-import com.amazon.apl.android.render.interfaces.IAPLTokenProvider;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * This class implements the TTS provider that is used by the
- * Android view host to create a TTS player instance.
- */
-public class APLTtsPlayerProvider implements ITtsPlayerProvider {
-    private static final String TAG = APLTtsPlayerProvider.class.getSimpleName();
-
-    private Context mContext;
-    private APLTtsPlayer mTtsPlayer;
-    private IAPLEventSender mAplEventSender;
-    private IAPLTokenProvider mAplTokenProvider;
-
-    public APLTtsPlayerProvider(@NonNull Context context, @NonNull IAPLEventSender aplEventSender,
-            @NonNull IAPLTokenProvider aplTokenProvider) {
-        mContext = context;
-        mAplEventSender = aplEventSender;
-        mAplTokenProvider = aplTokenProvider;
-    }
-
-    @Override
-    public ITtsPlayer getPlayer() {
-        if (mTtsPlayer == null) {
-            mTtsPlayer = new APLTtsPlayer(mContext, mAplEventSender, mAplTokenProvider);
-            Log.v(TAG, "Created TTS player");
-        }
-        return mTtsPlayer;
-    }
-
-    @Override
-    public void prepare(@NonNull String source, @NonNull ITtsSourceProvider ttsSourceProvider) {
-        try {
-            Log.v(TAG, "prepare: " + source);
-            ttsSourceProvider.onSource(new URL(source));
-        } catch (MalformedURLException e) {
-            Log.e(TAG, "Malformed TTS Url " + source);
-        }
-    }
-
-    @Override
-    public void prepare(@NonNull String source) {
-        try {
-            getPlayer().prepare(source, new URL(source));
-        } catch (Exception e) {
-            Log.e(TAG, "Could not set the speech source", e);
-        }
-    }
-
-    @Override
-    public void onDocumentFinish() {
-        if (mTtsPlayer != null) {
-            Log.i(TAG, "Releasing TTS player");
-            mTtsPlayer.release();
-            mTtsPlayer = null;
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/utils/RenderDocumentUtils.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/utils/RenderDocumentUtils.java
deleted file mode 100644
index 1018f1504..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/utils/RenderDocumentUtils.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.apl.android.render.utils;
-
-import android.text.TextUtils;
-
-import com.amazon.apl.android.render.payload.RenderDocumentPayload;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import lombok.Synchronized;
-
-/**
- * Utility for parsing render document payload.
- */
-public final class RenderDocumentUtils {
-    private static final String TAG = RenderDocumentUtils.class.getSimpleName();
-    public static final String SKILL_CLIENT_ID = "ThirdPartySdkSpeechlet";
-    private static final String TID_DELIMITER = "#TID#";
-
-    private static String sLastPayloadString;
-    private static RenderDocumentPayload sLastPayload;
-
-    private RenderDocumentUtils() {
-        // Do nothing.
-    }
-
-    /**
-     * Converts a {@link String} to the {@link RenderDocumentPayload} format.
-     *
-     * @param payload The JSON string with the render document payload.
-     * @return RenderDocument payload.
-     * @throws JSONException The
-     */
-    @Synchronized
-    public static RenderDocumentPayload convertToRenderDocument(final String payload) throws Exception {
-        if (payload.equals(sLastPayloadString)) {
-            return sLastPayload;
-        }
-
-        final JSONObject jsonPayload = new JSONObject(payload);
-
-        sLastPayloadString = payload;
-        sLastPayload = RenderDocumentPayload.fromJson(jsonPayload);
-
-        return sLastPayload;
-    }
-
-    /**
-     * The presentationToken format is as follows:
-     * amzn{Amazon Common Id version}.{namespace}.{templateToken
-     * version}.{clientId}#TID#{SkillId}:{Skill-Sent-Token}:{Random-Number}.
-     *
-     * @param token presentation presentationToken from {@link RenderDocumentPayload}
-     * @return a client id extracted from the presentationToken
-     */
-    public static String getClientId(final String token) {
-        if (TextUtils.isEmpty(token)) {
-            return "";
-        }
-
-        final String[] parts = token.split("\\.");
-        if (parts.length < 4) {
-            return "";
-        }
-
-        final int endIdx = parts[3].indexOf("#");
-        return parts[3].substring(0, endIdx);
-    }
-
-    /**
-     * The presentationToken format is as follows:
-     * amzn{Amazon Common Id version}.{namespace}.{templateToken
-     * version}.{clientId}#TID#{SkillId}:{Skill-Sent-Token}:{Random-Number}. We use the skillId to determine if a
-     * document should clear our back stack.
-     *
-     * @param token the presentation presentationToken from the {@link RenderDocumentPayload}
-     * @return a skill id extracted from the presentationToken
-     */
-    public static String getSkillId(final String token) {
-        if (TextUtils.isEmpty(token)) {
-            return "";
-        }
-
-        final String[] parts = token.split(TID_DELIMITER);
-        if (parts.length < 2) {
-            return "";
-        }
-
-        final String skillId = parts[1];
-        // Take the first part of the skillId if there's a colon, otherwise take the whole string.
-        int endIdx = skillId.indexOf(":");
-        if (endIdx == -1) {
-            endIdx = skillId.length();
-        }
-
-        return skillId.substring(0, endIdx);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/utils/ViewportUtils.java b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/utils/ViewportUtils.java
deleted file mode 100644
index 6f283456d..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/java/com/amazon/apl/android/render/utils/ViewportUtils.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.apl.android.render.utils;
-
-import com.amazon.apl.android.scaling.Scaling;
-
-import java.util.Collection;
-
-import lombok.NonNull;
-
-public final class ViewportUtils {
-    // [1280 x 800] 160 dpi -> [960 x 600] 213 dpi
-    public static final int CROWN_REAL_WIDTH_DP = 960;
-    public static final int CROWN_REAL_HEIGHT_DP = 600;
-
-    private ViewportUtils() {}
-
-    /**
-     * Determines if a viewport's width and height are both within the ranges defined by the given list of
-     * specifications.
-     * @param viewportWidth the viewport width
-     * @param viewportHeight the viewport height
-     * @param supportedViewports a list of objects defining the valid ranges for a viewport's width and height
-     */
-    public static boolean isWithinSpecification(int viewportWidth, int viewportHeight,
-            @NonNull final Collection supportedViewports) {
-        for (Scaling.ViewportSpecification viewportSpecification : supportedViewports) {
-            if (isWithinSpecification(viewportWidth, viewportHeight, viewportSpecification)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Determines if a viewport's width and height are both within the ranges defined by the given specification.
-     * @param viewportWidth the viewport width
-     * @param viewportHeight the viewport height
-     * @param viewportSpecification an object defining the valid ranges for a viewport's width and height
-     */
-    public static boolean isWithinSpecification(
-            int viewportWidth, int viewportHeight, @NonNull final Scaling.ViewportSpecification viewportSpecification) {
-        int minWidth = viewportSpecification.getMinWidth();
-        int maxWidth = viewportSpecification.getMaxWidth();
-        int minHeight = viewportSpecification.getMinHeight();
-        int maxHeight = viewportSpecification.getMaxHeight();
-
-        return isInsideBounds(viewportWidth, minWidth, maxWidth)
-                && isInsideBounds(viewportHeight, minHeight, maxHeight);
-    }
-
-    /**
-     * Determines whether the given value is inside the specified boundaries.
-     * @param value the value to verify
-     * @param lowerBound the lower bound to be satisfied
-     * @param upperBound the upper bound to be satisfied
-     */
-    public static boolean isInsideBounds(int value, int lowerBound, int upperBound) {
-        return (lowerBound <= value) && (value <= upperBound);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/libs/.gitignore b/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/libs/.gitignore
deleted file mode 100644
index d6b7ef32c..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/modules/apl-render/src/main/libs/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/proguard-rules.pro b/aacs/android/app-components/alexa-auto-apl-renderer/proguard-rules.pro
deleted file mode 100644
index f1b424510..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/AndroidManifest.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/AndroidManifest.xml
deleted file mode 100644
index 434de34cd..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-    
-
-    
-
-        
-            
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-            
-        
-
-        
-            
-                
-                
-            
-        
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/assets/APLViewport.json b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/assets/APLViewport.json
deleted file mode 100644
index 99c186ba6..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/assets/APLViewport.json
+++ /dev/null
@@ -1,113 +0,0 @@
-{
-    "_comment": "AACS config for APL visual characteristics.",
-    "aacs.alexa": {
-        "gui": {
-            "visualCharacteristics": [
-                {
-                    "type": "AlexaInterface",
-                    "interface": "Alexa.InteractionMode",
-                    "version": "1.1",
-                    "configurations": {
-                        "interactionModes": [
-                            {
-                                "id": "{{STRING}}",
-                                "uiMode": "AUTO",
-                                "interactionDistance": {
-                                    "unit": [ "CENTIMETERS", "INCHES" ],
-                                    "value": "{INTEGER}"
-                                },
-                                "touch": [ "SUPPORTED", "UNSUPPORTED" ],
-                                "keyboard": [ "SUPPORTED", "UNSUPPORTED" ],
-                                "video": [ "SUPPORTED", "UNSUPPORTED" ],
-                                "dialog": [ "SUPPORTED", "UNSUPPORTED" ]
-                            }
-                        ]
-                    }
-                },
-                {
-                    "type": "AlexaInterface",
-                    "interface": "Alexa.Presentation.APL.Video",
-                    "version": "1.0",
-                    "configurations": {
-                        "video": {
-                            "codecs": [
-                                "H_264_42",
-                                "H_264_41"
-                            ]
-                        }
-                    }
-                },
-                {
-                    "type": "AlexaInterface",
-                    "interface": "Alexa.Display.Window",
-                    "version": "1.0",
-                    "configurations": {
-                        "templates": [
-                            {
-                                "id": "{STRING}",
-                                "type": "STANDARD",
-                                "configuration": {
-                                    "sizes": [
-                                        {
-                                            "type": "DISCRETE",
-                                            "id": "{STRING}",
-                                            "value": {
-                                                "unit": "PIXEL",
-                                                "value": {
-                                                    "width": "{INTEGER}",
-                                                    "height": "{INTEGER}"
-                                                }
-                                            }
-                                        }
-                                    ],
-                                    "interactionModes": [
-                                        "{STRING}"
-                                    ]
-                                }
-                            }
-                        ]
-                    }
-                },
-                {
-                    "type": "AlexaInterface",
-                    "interface": "Alexa.Display",
-                    "version": "1.0",
-                    "configurations": {
-                        "display": {
-                            "type": "PIXEL",
-                            "touch": [ "SINGLE", "UNSUPPORTED" ],
-                            "shape": [ "RECTANGLE", "ROUND" ],
-                            "dimensions": {
-                                "resolution": {
-                                    "unit": "PIXEL",
-                                    "value": {
-                                        "width": "{INTEGER}",
-                                        "height": "{INTEGER}"
-                                    }
-                                },
-                                "physicalSize": {
-                                    "unit": [ "CENTIMETERS", "INCHES" ],
-                                    "value": {
-                                        "width": "{DECIMAL}",
-                                        "height": "{DECIMAL}"
-                                    }
-                                },
-                                "pixelDensity": {
-                                    "unit": "DPI",
-                                    "value": "{INTEGER}"
-                                },
-                                "densityIndependentResolution": {
-                                    "unit": "DP",
-                                    "value": {
-                                        "width": "{INTEGER}",
-                                        "height": "{INTEGER}"
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            ]
-        }
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/assets/aacs-sample-app/modules-aplrenderer.json b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/assets/aacs-sample-app/modules-aplrenderer.json
deleted file mode 100644
index b7d12df71..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/assets/aacs-sample-app/modules-aplrenderer.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "module": {
-    "name": "com.amazon.alexa.auto.apl.APLRendererModule"
-  }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLDirective.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLDirective.java
deleted file mode 100644
index bd9e37d27..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLDirective.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apl;
-
-import androidx.annotation.NonNull;
-
-import com.amazon.alexa.auto.aacs.common.AACSMessage;
-
-public class APLDirective {
-    @NonNull
-    public AACSMessage message;
-
-    public APLDirective(@NonNull AACSMessage message) {
-        this.message = message;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLFragment.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLFragment.java
deleted file mode 100644
index 1d05f7ff7..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLFragment.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apl;
-
-import static com.amazon.aacsconstants.AASBConstants.AlexaClient.DIALOG_STATE_LISTENING;
-import static com.amazon.alexa.auto.apl.Constants.STATE;
-import static com.amazon.alexa.auto.apps.common.Constants.APL_RUNTIME_PROPERTIES;
-import static com.amazon.alexa.auto.apps.common.Constants.APL_RUNTIME_PROPERTY_DRIVING_STATE_NAME;
-import static com.amazon.alexa.auto.apps.common.Constants.APL_RUNTIME_PROPERTY_THEME_NAME;
-import static com.amazon.alexa.auto.apps.common.Constants.APL_RUNTIME_PROPERTY_VIDEO_NAME;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-
-import com.amazon.aacsconstants.Action;
-import com.amazon.alexa.auto.apis.apl.APLVisualController;
-import com.amazon.alexa.auto.apis.app.AlexaApp;
-import com.amazon.alexa.auto.apis.session.SessionActivityController;
-import com.amazon.alexa.auto.apl.handler.APLHandler;
-import com.amazon.alexa.auto.apps.common.util.FileUtil;
-import com.amazon.alexa.auto.apps.common.util.Preconditions;
-import com.amazon.apl.android.APLLayout;
-import com.amazon.apl.android.render.APLPresenter;
-
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.lang.ref.WeakReference;
-
-/**
- * Fragment for Alexa Auto APL screen.
- */
-public class APLFragment extends Fragment {
-    private static final String TAG = APLFragment.class.getSimpleName();
-
-    private static final double APL_FRAGMENT_MARGIN_RATIO = 0.05;
-
-    @Nullable
-    private APLHandler mAplHandler;
-    @NonNull
-    private final APLDirectiveReceiver mAPLReceiver;
-
-    private JSONArray mVisualConfig;
-    private String mDefaultWindowId;
-    private int mAPLViewPortWidth;
-    private int mAPLViewPortHeight;
-    private Bundle mCreationArgs;
-
-    private String mRenderPayload = "";
-
-    private APLLayout mAPLLayout;
-
-    public APLFragment() {
-        mAPLReceiver = new APLDirectiveReceiver();
-    }
-
-    @Override
-    public void onStart() {
-        Log.d(TAG, "onStart");
-        super.onStart();
-        EventBus.getDefault().register(mAPLReceiver);
-    }
-
-    @Override
-    public void onStop() {
-        Log.d(TAG, "onStop");
-        super.onStop();
-
-        Context context = getContext();
-        Preconditions.checkNotNull(context);
-
-        AlexaApp.from(getContext())
-                .getRootComponent()
-                .getComponent(APLVisualController.class)
-                .ifPresent(aplVisualController -> {
-                    aplVisualController.cancelExecution();
-                    handleClearDocumentIntent(mRenderPayload);
-                });
-
-        EventBus.getDefault().unregister(mAPLReceiver);
-    }
-
-    @Override
-    public void onDestroy() {
-        Log.d(TAG, "onDestroy");
-        super.onDestroy();
-    }
-
-    @Override
-    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        Log.d(TAG, "onViewCreated");
-        super.onViewCreated(view, savedInstanceState);
-
-        Context context = getContext();
-        Preconditions.checkNotNull(context);
-
-        mCreationArgs = getArguments();
-        if (mCreationArgs != null) {
-            View fragmentView = requireView();
-            View aplview = fragmentView.findViewById(R.id.apl);
-            mAPLLayout = (APLLayout) aplview;
-
-            AlexaApp.from(context)
-                    .getRootComponent()
-                    .getComponent(APLVisualController.class)
-                    .ifPresent(aplVisualController -> { aplVisualController.setAPLLayout(aplview); });
-
-            FileUtil.readAACSConfigurationAsync(context).subscribe(this::constructAPLLayout);
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        Context context = getContext();
-        Preconditions.checkNotNull(context);
-
-        // Inflate the layout for this fragment
-        return inflater.inflate(R.layout.fragment_apl, container, false);
-    }
-
-    private void handleRenderDocumentIntent(@NonNull Bundle creationArgs) {
-        try {
-            String payload = creationArgs.getString(Constants.PAYLOAD);
-            Log.i(TAG, "handleRenderDocumentIntent payload: " + payload);
-            Preconditions.checkNotNull(payload);
-
-            JSONObject json = new JSONObject(payload);
-            String token = json.getString(Constants.TOKEN);
-            String renderPayload = json.getString(Constants.PAYLOAD);
-
-            AlexaApp.from(getContext())
-                    .getRootComponent()
-                    .getComponent(APLVisualController.class)
-                    .ifPresent(aplVisualController -> {
-                        aplVisualController.renderDocument(renderPayload, token, mDefaultWindowId);
-                    });
-        } catch (Exception exception) {
-            Log.w(TAG, "Failed to handle render document. Error:" + exception);
-        }
-    }
-
-    private void handleClearDocumentIntent(@NonNull String payload) {
-        try {
-            JSONObject json = new JSONObject(payload);
-            String token = json.getString(Constants.TOKEN);
-
-            AlexaApp.from(getContext())
-                    .getRootComponent()
-                    .getComponent(APLVisualController.class)
-                    .ifPresent(aplVisualController -> { aplVisualController.clearDocument(token); });
-        } catch (Exception exception) {
-            Log.w(TAG, "Failed to handle clear document. Error:" + exception);
-        }
-    }
-
-    private void handleExecuteCommandsIntent(@NonNull String payload) {
-        try {
-            JSONObject json = new JSONObject(payload);
-            String token = json.getString(Constants.TOKEN);
-            String executeCommandPayload = json.getString(Constants.PAYLOAD);
-
-            AlexaApp.from(getContext())
-                    .getRootComponent()
-                    .getComponent(APLVisualController.class)
-                    .ifPresent(aplVisualController -> {
-                        aplVisualController.executeCommands(executeCommandPayload, token);
-                    });
-        } catch (Exception exception) {
-            Log.w(TAG, "Failed to handle execute commands. Error:" + exception);
-        }
-    }
-
-    private void handleUpdateAPLRuntimePropertiesIntent(@NonNull String payload) {
-        try {
-            // Construct APL runtime properties with local cached values.
-            String aplRuntimeProperties = constructAPLRuntimeProperties();
-
-            AlexaApp.from(getContext())
-                    .getRootComponent()
-                    .getComponent(APLVisualController.class)
-                    .ifPresent(aplVisualController -> {
-                        aplVisualController.handleAPLRuntimeProperties(aplRuntimeProperties);
-                    });
-        } catch (Exception exception) {
-            Log.w(TAG, "Failed to handle update APL runtime properties commands. Error:" + exception);
-        }
-    }
-
-    private void handleDataSourceUpdateIntent(@NonNull String payload) {
-        try {
-            Log.v(TAG, "handleUpdateAPLDataSourceUpdateIntent: " + payload);
-            JSONObject json = new JSONObject(payload);
-            String dataType = json.getString(Constants.TYPE);
-            String token = json.getString(Constants.TOKEN);
-            String dataSourceUpdatePayload = json.getString(Constants.PAYLOAD);
-
-            AlexaApp.from(getContext())
-                    .getRootComponent()
-                    .getComponent(APLVisualController.class)
-                    .ifPresent(aplVisualController -> {
-                        aplVisualController.handleAPLDataSourceUpdate(dataType, dataSourceUpdatePayload, token);
-                    });
-        } catch (Exception exception) {
-            Log.w(TAG, "Failed to handle data source update. Error:" + exception);
-        }
-    }
-
-    private void handleDialogStateChangedIntent(@NonNull String payload) {
-        try {
-            Log.v(TAG, "handleDialogStateChangedIntent: " + payload);
-            JSONObject dialogState = new JSONObject(payload);
-            // Cancel APL execution when we go into listening state
-            if (dialogState.getString(STATE).equals(DIALOG_STATE_LISTENING)) {
-                Log.v(TAG, "handleDialogStateChangedIntent: cancellingExecution");
-                AlexaApp.from(getContext())
-                        .getRootComponent()
-                        .getComponent(APLVisualController.class)
-                        .ifPresent(APLVisualController::cancelExecution);
-            }
-        } catch (Exception exception) {
-            Log.w(TAG, "Failed to handle dialog state change. Error:" + exception);
-        }
-    }
-
-    /**
-     * Construct APL layout with visual characteristics configs.
-     *
-     * @param configs AACS configs.
-     */
-    private void constructAPLLayout(@NonNull String configs) {
-        try {
-            JSONObject config = new JSONObject(configs);
-            mVisualConfig =
-                    config.getJSONObject("aacs.alexa").getJSONObject("gui").getJSONArray("visualCharacteristics");
-
-            if (mVisualConfig.length() > 0) {
-                for (int i = 0; i < mVisualConfig.length(); i++) {
-                    JSONObject currentElement = mVisualConfig.getJSONObject(i);
-                    if ("Alexa.Display.Window".equals(currentElement.getString("interface"))) {
-                        JSONArray templates = currentElement.getJSONObject("configurations").getJSONArray("templates");
-                        JSONObject template = templates.getJSONObject(0);
-                        mDefaultWindowId = template.getString("id");
-                        mAPLViewPortWidth = template.getJSONObject("configuration")
-                                                    .getJSONArray("sizes")
-                                                    .getJSONObject(0)
-                                                    .getJSONObject("value")
-                                                    .getJSONObject("value")
-                                                    .getInt("width");
-                        mAPLViewPortHeight = template.getJSONObject("configuration")
-                                                     .getJSONArray("sizes")
-                                                     .getJSONObject(0)
-                                                     .getJSONObject("value")
-                                                     .getJSONObject("value")
-                                                     .getInt("height");
-                    }
-                }
-            }
-
-            setAPLFragmentLayout(mAPLLayout);
-
-            mRenderPayload = mCreationArgs.getString(Constants.PAYLOAD);
-
-            handleRenderDocumentIntent(mCreationArgs);
-
-            String aplRuntimeProperties = constructAPLRuntimeProperties();
-            if (!aplRuntimeProperties.isEmpty()) {
-                AlexaApp.from(getContext())
-                        .getRootComponent()
-                        .getComponent(APLVisualController.class)
-                        .ifPresent(aplVisualController -> {
-                            aplVisualController.handleAPLRuntimeProperties(aplRuntimeProperties);
-                        });
-            }
-        } catch (JSONException e) {
-            Log.w(TAG, "Failed to parse APL visual characteristics" + e);
-        }
-    }
-
-    class APLDirectiveReceiver {
-        @Subscribe
-        public void OnReceive(APLDirective directive) {
-            switch (directive.message.action) {
-                case Action.AlexaClient.DIALOG_STATE_CHANGED:
-                    Preconditions.checkNotNull(directive.message.payload);
-                    handleDialogStateChangedIntent(directive.message.payload);
-                    break;
-                case Action.APL.RENDER_DOCUMENT:
-                    Preconditions.checkNotNull(directive.message.payload);
-                    Bundle args = new Bundle();
-                    args.putString(Constants.PAYLOAD, directive.message.payload);
-                    handleRenderDocumentIntent(args);
-                    break;
-                case Action.APL.EXECUTE_COMMANDS:
-                    Preconditions.checkNotNull(directive.message.payload);
-                    handleExecuteCommandsIntent(directive.message.payload);
-                    break;
-                case Action.APL.CLEAR_DOCUMENT:
-                    handleClearDocumentIntent(directive.message.payload);
-
-                    Context context = getContext();
-                    Preconditions.checkNotNull(context);
-
-                    AlexaApp.from(context)
-                            .getRootComponent()
-                            .getComponent(SessionActivityController.class)
-                            .ifPresent(SessionActivityController::removeFragment);
-                    break;
-                case Action.APL.UPDATE_APL_RUNTIME_PROPERTIES:
-                    Preconditions.checkNotNull(directive.message.payload);
-                    handleUpdateAPLRuntimePropertiesIntent(directive.message.payload);
-                    break;
-                case Action.APL.DATA_SOURCE_UPDATE:
-                    Preconditions.checkNotNull(directive.message.payload);
-                    handleDataSourceUpdateIntent(directive.message.payload);
-                    break;
-                case Action.Navigation.START_NAVIGATION:
-                    context = getContext();
-                    Preconditions.checkNotNull(context);
-                    handleClearDocumentIntent(mRenderPayload);
-                    AlexaApp.from(context)
-                            .getRootComponent()
-                            .getComponent(SessionActivityController.class)
-                            .ifPresent(SessionActivityController::removeFragment);
-                    break;
-                default:
-                    Log.d(TAG, "Unknown APL intent, action is " + directive.message.action);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Adjust APL fragment based on the APL Automotive viewport defined from the config, and set margins
-     * based on device's screen size.
-     * @param layout APL fragment layout
-     */
-    private void setAPLFragmentLayout(APLLayout layout) {
-        ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) layout.getLayoutParams();
-        marginLayoutParams.width = mAPLViewPortWidth;
-        marginLayoutParams.height = mAPLViewPortHeight;
-
-        if(getContext() != null) {
-            DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
-            int height = displayMetrics.heightPixels;
-            int width = displayMetrics.widthPixels;
-            marginLayoutParams.topMargin = (int) (height * APL_FRAGMENT_MARGIN_RATIO);
-            marginLayoutParams.leftMargin = (int) (width * APL_FRAGMENT_MARGIN_RATIO);
-        }
-        else {
-            Log.w(TAG, "getContext() was null");
-        }
-
-        layout.setLayoutParams(marginLayoutParams);
-    }
-
-    /**
-     * Construct APL runtime properties to render APL with updated properties value.
-     * Sample APL runtime properties format: {"drivingState":"parked","theme":"dark-gray"}
-     * @return APL runtime properties
-     */
-    private String constructAPLRuntimeProperties() {
-        try {
-            JSONObject properties = new JSONObject();
-
-            SharedPreferences sharedPreferences = getContext().getSharedPreferences(APL_RUNTIME_PROPERTIES, 0);
-            Preconditions.checkNotNull(sharedPreferences);
-            String drivingStateValue = sharedPreferences.getString(APL_RUNTIME_PROPERTY_DRIVING_STATE_NAME, "");
-            String themeValue = sharedPreferences.getString(APL_RUNTIME_PROPERTY_THEME_NAME, "");
-            String videoValue = sharedPreferences.getString(APL_RUNTIME_PROPERTY_VIDEO_NAME, "");
-
-            if (!drivingStateValue.isEmpty()) {
-                properties.put(APL_RUNTIME_PROPERTY_DRIVING_STATE_NAME, drivingStateValue);
-            }
-            if (!themeValue.isEmpty()) {
-                properties.put(APL_RUNTIME_PROPERTY_THEME_NAME, themeValue);
-            }
-            if (!videoValue.isEmpty()) {
-                properties.put(APL_RUNTIME_PROPERTY_VIDEO_NAME, videoValue);
-            }
-
-            return properties.toString();
-        } catch (JSONException e) {
-            Log.d(TAG, "Failed to construct APL runtime properties");
-            return "";
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLRendererModule.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLRendererModule.java
deleted file mode 100644
index d10a34740..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLRendererModule.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apl;
-
-import android.content.Context;
-import android.util.Log;
-
-import com.amazon.aacsipc.AACSSender;
-import com.amazon.alexa.auto.aacs.common.AACSMessageSender;
-import com.amazon.alexa.auto.apis.apl.APLVisualController;
-import com.amazon.alexa.auto.apis.app.AlexaApp;
-import com.amazon.alexa.auto.apis.module.ModuleInterface;
-import com.amazon.alexa.auto.apl.handler.APLHandler;
-
-import java.lang.ref.WeakReference;
-
-public class APLRendererModule implements ModuleInterface {
-    private static final String TAG = APLRendererModule.class.getSimpleName();
-
-    @Override
-    public void initialize(Context context) {
-        Log.d(TAG, "initialize");
-        WeakReference contextWk = new WeakReference<>(context);
-        AlexaApp.from(context).getRootComponent().activateScope(
-                new APLHandler(contextWk, new AACSMessageSender(contextWk, new AACSSender())));
-    }
-
-    @Override
-    public void uninitialize(Context context) {
-        Log.d(TAG, "uninitialize");
-        AlexaApp.from(context).getRootComponent().deactivateScope(APLVisualController.class);
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLThemeDirective.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLThemeDirective.java
deleted file mode 100644
index bb8f7f6b0..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/APLThemeDirective.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apl;
-
-import androidx.annotation.NonNull;
-
-public class APLThemeDirective {
-    @NonNull
-    public String themePayload;
-
-    public APLThemeDirective(@NonNull String themePayload) {
-        this.themePayload = themePayload;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/Constants.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/Constants.java
deleted file mode 100644
index 4597096fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/Constants.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apl;
-
-public class Constants {
-    // AACS Intents
-    public static final String ID = "id";
-    public static final String TOKEN = "token";
-    public static final String PAYLOAD = "payload";
-    public static final String NAME = "name";
-    public static final String VALUE = "value";
-    public static final String TYPE = "type";
-    public static final String STATE = "state";
-    public static final String RESULT = "result";
-    public static final String ERROR = "error";
-    public static final String SOURCE = "source";
-    public static final String EVENT = "event";
-    public static final String DOCUMENT = "document";
-    public static final String VERSION = "version";
-    public static final String PROPERTIES = "properties";
-    public static final String COORDINATE = "coordinate";
-    public static final String LONGITUDE = "longitude";
-    public static final String LATITUDE = "latitude";
-
-    // APL Event States
-    public static final String APL_EVENT_STATE_ACTIVATED = "ACTIVATED";
-    public static final String APL_EVENT_STATE_DEACTIVATED = "DEACTIVATED";
-    public static final String APL_EVENT_STATE_ONE_TIME = "ONE_TIME";
-    public static final String APL_EVENT_STATE_INTERRUPT = "INTERRUPT";
-    public static final String APL_EVENT_STATE_UNKNOWN = "UNKNOWN";
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/handler/APLHandler.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/handler/APLHandler.java
deleted file mode 100644
index 8d1550b9c..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/handler/APLHandler.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apl.handler;
-
-import android.content.Context;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-
-import com.amazon.aacsconstants.Action;
-import com.amazon.aacsconstants.Topic;
-import com.amazon.alexa.auto.aacs.common.AACSMessageSender;
-import com.amazon.alexa.auto.apis.apl.APLVisualController;
-import com.amazon.alexa.auto.apl.Constants;
-import com.amazon.alexa.auto.apps.common.util.FileUtil;
-import com.amazon.apl.android.APLLayout;
-import com.amazon.apl.android.render.APLPresenter;
-import com.amazon.apl.android.render.interfaces.IAPLEventSender;
-import com.amazon.apl.android.render.interfaces.IDismissible;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONStringer;
-
-import java.lang.ref.WeakReference;
-import java.util.HashMap;
-
-/**
- * This class provides the functionality to handle AACS APL events.
- */
-public class APLHandler implements APLVisualController, IAPLEventSender, IDismissible {
-    private static final String TAG = APLHandler.class.getSimpleName();
-
-    @NonNull
-    private final WeakReference mContextWk;
-    @NonNull
-    private AACSMessageSender mAACSSender;
-
-    private JSONArray mVisualConfig;
-    private String mDefaultWindowId;
-
-    private String mToken;
-    private String mVersion;
-
-    @VisibleForTesting
-    APLPresenter mPresenter;
-
-    public APLHandler(@NonNull WeakReference contextWk, @NonNull AACSMessageSender aacsSender) {
-        mContextWk = contextWk;
-        mAACSSender = aacsSender;
-
-        Log.d(TAG, "Initializing APL presenter.");
-        APLPresenter.initialize(contextWk.get());
-        FileUtil.readAACSConfigurationAsync(contextWk.get())
-                .subscribe(configs -> initializeAPLPresenter(contextWk.get(), configs));
-    }
-
-    @Override
-    public void renderDocument(String jsonPayload, String token, String windowId) {
-        try {
-            // Extract document and data
-            JSONObject payload = new JSONObject(jsonPayload);
-            Log.i(TAG, "APL render document: " + payload.toString(4));
-            JSONObject document = payload.getJSONObject(Constants.DOCUMENT);
-
-            mToken = token;
-            mVersion = document.getString(Constants.VERSION);
-        } catch (JSONException e) {
-            Log.e(TAG, e.getMessage());
-        }
-
-        Log.i(TAG, "APL render document version: " + mVersion + " token: " + mToken + " windowId: " + windowId);
-
-        mPresenter.onRenderDocument(jsonPayload, token, windowId);
-    }
-
-    @Override
-    public void clearDocument(String token) {
-        Log.i(TAG, "clearDocument and visual context");
-        mPresenter.onClearDocument(token);
-    }
-
-    @Override
-    public void executeCommands(String payload, String token) {
-        Log.v(TAG, "executeCommands: token: " + token);
-        mToken = token;
-
-        mPresenter.onExecuteCommands(payload, token);
-    }
-
-    @Override
-    public void handleAPLRuntimeProperties(String aplRuntimeProperties) {
-        Log.v(TAG, "handleAPLRuntimeProperties: aplRuntimeProperties: " + aplRuntimeProperties);
-        mPresenter.onAPLRuntimeProperties(aplRuntimeProperties);
-    }
-
-    @Override
-    public void handleAPLDataSourceUpdate(String dataType, String payload, String token) {
-        Log.v(TAG, "handleAPLDataSourceUpdate");
-        mPresenter.onDataSourceUpdate(dataType, payload, token);
-    }
-
-    @Override
-    public void interruptCommandSequence(String token) {
-        Log.v(TAG, "interruptCommandSequence: token: " + token);
-        mPresenter.onInterruptCommandSequence(token);
-    }
-
-    private void processActivityEvent(String source, String event) {
-        try {
-            String payload = new JSONStringer()
-                                     .object()
-                                     .key(Constants.SOURCE)
-                                     .value(source)
-                                     .key(Constants.EVENT)
-                                     .value(event)
-                                     .endObject()
-                                     .toString();
-
-            mAACSSender.sendMessage(Topic.APL, Action.APL.PROCESS_ACTIVITY_EVENT, payload);
-        } catch (Exception exception) {
-            Log.e(TAG, "Failed to process activity event. Error: " + exception);
-        }
-    }
-
-    private void renderDocumentResult(String token, boolean result, String error) {
-        sendResult(Action.APL.RENDER_DOCUMENT_RESULT, token, result, error);
-    }
-
-    private void executeCommandsResult(String token, boolean result, String error) {
-        sendResult(Action.APL.EXECUTE_COMMANDS_RESULT, token, result, error);
-    }
-
-    private void sendResult(String resultAction, String token, boolean result, String error) {
-        try {
-            String payload = new JSONStringer()
-                                     .object()
-                                     .key(Constants.TOKEN)
-                                     .value(token)
-                                     .key(Constants.RESULT)
-                                     .value(result)
-                                     .key(Constants.ERROR)
-                                     .value(error == null ? "" : error)
-                                     .endObject()
-                                     .toString();
-
-            mAACSSender.sendMessage(Topic.APL, resultAction, payload);
-        } catch (Exception exception) {
-            Log.e(TAG, "Failed to send result for " + resultAction + " Error: " + exception);
-        }
-    }
-
-    private void sendUserEvent(String payload) {
-        try {
-            String msgPayload =
-                    new JSONStringer().object().key(Constants.PAYLOAD).value(payload).endObject().toString();
-
-            mAACSSender.sendMessage(Topic.APL, Action.APL.SEND_USER_EVENT, msgPayload);
-        } catch (Exception exception) {
-            Log.e(TAG, "Failed to send user event. Error: " + exception);
-        }
-    }
-
-    // IAPLEventSender implementation.
-
-    @Override
-    public void sendWindowState(String state) {
-        Log.v(TAG, "sendWindowState: " + state);
-        try {
-            String msgPayload = new JSONStringer().object().key(Constants.STATE).value(state).endObject().toString();
-
-            mAACSSender.sendMessage(Topic.APL, Action.APL.SEND_DEVICE_WINDOW_STATE, msgPayload);
-        } catch (Exception exception) {
-            Log.e(TAG, "Failed to send device window state. Error: " + exception);
-        }
-    }
-
-    @Override
-    public void sendClearCard() {
-        Log.v(TAG, "sendClearCard");
-        mAACSSender.sendMessage(Topic.APL, Action.APL.CLEAR_CARD, null);
-    }
-
-    @Override
-    public void sendClearAllExecuteCommands() {
-        Log.v(TAG, "sendClearAllExecuteCommands");
-        mAACSSender.sendMessage(Topic.APL, Action.APL.CLEAR_ALL_EXECUTE_COMMANDS, null);
-    }
-
-    @Override
-    public void sendUserEventRequest(String payload) {
-        Log.v(TAG, "sendUserEventRequest: payload: " + payload);
-        sendUserEvent(payload);
-    }
-
-    @Override
-    public void sendDataSourceFetchEventRequest(String type, String payload) {
-        Log.v(TAG, "sendDataSourceFetchEventRequest: type: " + type + " payload: " + payload);
-        try {
-            String msgPayload = new JSONStringer()
-                                        .object()
-                                        .key(Constants.TYPE)
-                                        .value(type)
-                                        .key(Constants.PAYLOAD)
-                                        .value(payload)
-                                        .endObject()
-                                        .toString();
-
-            mAACSSender.sendMessage(Topic.APL, Action.APL.SEND_DATA_SOURCE_FETCH_REQUEST_EVENT, msgPayload);
-        } catch (Exception exception) {
-            Log.e(TAG, "Failed to send data source fetch request event. Error: " + exception);
-        }
-    }
-
-    @Override
-    public void sendRuntimeErrorEventRequest(String payload) {
-        Log.v(TAG, "sendRuntimeErrorEvent: payload: " + payload);
-        try {
-            String msgPayload =
-                    new JSONStringer().object().key(Constants.PAYLOAD).value(payload).endObject().toString();
-
-            mAACSSender.sendMessage(Topic.APL, Action.APL.SEND_RUNTIME_ERROR_EVENT, msgPayload);
-        } catch (Exception exception) {
-            Log.e(TAG, "Failed to send runtime error event. Error: " + exception);
-        }
-    }
-
-    @Override
-    public void sendRenderDocumentResult(String token, boolean result, String error) {
-        Log.v(TAG, "sendRenderDocumentResult: token: " + token + " boolean: " + result + " error: " + error);
-        renderDocumentResult(token, result, error);
-    }
-
-    @Override
-    public void sendExecuteCommandsResult(String token, boolean result, String error) {
-        Log.v(TAG, "sendExecuteCommandsResult: token: " + token + " result: " + result + " error: " + error);
-        executeCommandsResult(token, result, error);
-    }
-
-    @Override
-    public void sendActivityEventRequest(String token, IAPLEventSender.ActivityEvent event) {
-        Log.v(TAG, "sendActivityEventRequest: token: " + token + " event: " + event);
-        processActivityEvent(token, translateActivityEvent(event));
-    }
-
-    @Override
-    public void sendContext(String state) {
-        Log.v(TAG, "sendContext: " + state);
-        try {
-            String msgPayload = new JSONStringer().object().key(Constants.STATE).value(state).endObject().toString();
-
-            mAACSSender.sendMessage(Topic.APL, Action.APL.SEND_DOCUMENT_STATE, msgPayload);
-        } catch (Exception exception) {
-            Log.e(TAG, "Failed to send user event. Error: " + exception);
-        }
-    }
-
-    /**
-     * Cancel execution of APL commands. Should be called
-     * on a barge in.
-     */
-    @Override
-    public void cancelExecution() {
-        if (mPresenter != null) {
-            mPresenter.cancelExecution();
-        }
-    }
-
-    private String translateActivityEvent(IAPLEventSender.ActivityEvent event) {
-        switch (event) {
-            case ACTIVATED:
-                return Constants.APL_EVENT_STATE_ACTIVATED;
-            case DEACTIVATED:
-                return Constants.APL_EVENT_STATE_DEACTIVATED;
-            case ONE_TIME:
-                return Constants.APL_EVENT_STATE_ONE_TIME;
-            case INTERRUPT:
-                return Constants.APL_EVENT_STATE_INTERRUPT;
-            case UNKNOWN:
-                return Constants.APL_EVENT_STATE_UNKNOWN;
-        }
-
-        return Constants.APL_EVENT_STATE_UNKNOWN;
-    }
-
-    @Override
-    public void onDismiss() {
-        Log.d(TAG, "onDismiss");
-        clearDocument(mToken);
-    }
-
-    @Override
-    public void initializeAPLPresenter(Context context, String configs) {
-        try {
-            JSONObject config = new JSONObject(configs);
-            mVisualConfig =
-                    config.getJSONObject("aacs.alexa").getJSONObject("gui").getJSONArray("visualCharacteristics");
-
-            if (mVisualConfig.length() > 0) {
-                for (int i = 0; i < mVisualConfig.length(); i++) {
-                    JSONObject currentElement = mVisualConfig.getJSONObject(i);
-                    if ("Alexa.Display.Window".equals(currentElement.getString("interface"))) {
-                        JSONArray templates = currentElement.getJSONObject("configurations").getJSONArray("templates");
-                        JSONObject template = templates.getJSONObject(0);
-                        mDefaultWindowId = template.getString("id");
-                    }
-                }
-            }
-        } catch (JSONException e) {
-            Log.w(TAG, "Failed to parse APL visual characteristics" + e);
-        }
-
-        mPresenter = new APLPresenter(mVisualConfig, mDefaultWindowId, this);
-
-        mPresenter.setDismissibleCallback(this);
-    }
-
-    @Override
-    public void setAPLLayout(View view) {
-        Log.d(TAG, "Setting APL layout");
-        HashMap aplLayouts = new HashMap();
-        aplLayouts.put(mDefaultWindowId, (APLLayout) view);
-
-        mPresenter.setAPLLayout(aplLayouts);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/receiver/APLReceiver.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/receiver/APLReceiver.java
deleted file mode 100644
index faae9f35d..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/receiver/APLReceiver.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apl.receiver;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.fragment.app.Fragment;
-
-import com.amazon.aacsconstants.Action;
-import com.amazon.alexa.auto.aacs.common.AACSMessage;
-import com.amazon.alexa.auto.aacs.common.AACSMessageBuilder;
-import com.amazon.alexa.auto.apis.app.AlexaApp;
-import com.amazon.alexa.auto.apis.session.SessionActivityController;
-import com.amazon.alexa.auto.apis.session.SessionViewController;
-import com.amazon.alexa.auto.apl.*;
-import com.amazon.alexa.auto.voiceinteraction.common.AutoVoiceInteractionMessage;
-import com.amazon.alexa.auto.voiceinteraction.common.Constants;
-
-import org.greenrobot.eventbus.EventBus;
-
-public class APLReceiver extends BroadcastReceiver {
-    private static final String TAG = APLReceiver.class.getSimpleName();
-
-    @RequiresApi(api = Build.VERSION_CODES.N)
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (intent == null || intent.getAction() == null) {
-            return;
-        }
-
-        AACSMessageBuilder.parseEmbeddedIntent(intent).ifPresent(message -> {
-            Log.d(TAG, "APL msg.action " + message.action + " payload: " + message.payload);
-            if (Action.APL.RENDER_DOCUMENT.equals(message.action)) {
-                handleRenderDocument(context, message);
-            } else {
-                APLDirective directive = new APLDirective(message);
-                EventBus.getDefault().post(directive);
-            }
-        });
-    }
-
-    private void handleRenderDocument(@NonNull Context context, @NonNull final AACSMessage message) {
-        AlexaApp app = AlexaApp.from(context);
-
-        app.getRootComponent().getComponent(SessionActivityController.class).ifPresent(sessionActivityController -> {
-            Fragment aplFragment;
-            Bundle args = new Bundle();
-            args.putString(com.amazon.alexa.auto.apl.Constants.PAYLOAD, message.payload);
-            if (!sessionActivityController.isFragmentAdded()) {
-                aplFragment = new APLFragment();
-                aplFragment.setArguments(args);
-                sessionActivityController.addFragment(aplFragment);
-
-                app.getRootComponent().getComponent(SessionViewController.class).ifPresent(sessionViewController -> {
-                    if (!sessionViewController.isSessionActive()) {
-                        Log.d(TAG, "Session was closed before document received. Recreating session");
-                        EventBus.getDefault().post(new AutoVoiceInteractionMessage(
-                                com.amazon.alexa.auto.voiceinteraction.common.Constants.TOPIC_RELAUNCH_SESSION, "",
-                                ""));
-                    }
-                });
-            } else {
-                APLDirective directive = new APLDirective(message);
-                EventBus.getDefault().post(directive);
-            }
-        });
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/receiver/APLThemeReceiver.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/receiver/APLThemeReceiver.java
deleted file mode 100644
index 8cf43a501..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/java/com/amazon/alexa/auto/apl/receiver/APLThemeReceiver.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apl.receiver;
-
-import static com.amazon.alexa.auto.apps.common.Constants.APL_RUNTIME_PROPERTIES;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_ID;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_NAME;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_VALUE_BLACK;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_VALUE_GRAY;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_VALUE_GRAY_ONE;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_VALUE_GRAY_TWO;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.UI_DARK_THEME;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.UI_LIGHT_THEME;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.UI_MODE_VALUE_DARK;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.UI_MODE_VALUE_LIGHT;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.amazon.alexa.auto.apis.apl.APLTheme;
-import com.amazon.alexa.auto.apl.Constants;
-import com.amazon.alexa.auto.apps.common.util.Preconditions;
-
-import org.greenrobot.eventbus.EventBus;
-import org.json.JSONException;
-import org.json.JSONStringer;
-
-/**
- * Receiver for APL theme intent and send theme id to APL cloud.
- *
- * There are six APL themes available for automotive devices (uiMode-themeId):
- * dark (default for dark or night mode)
- * dark-black
- * dark-gray
- * light (default for light or day mode)
- * light-gray1
- * light-gray2
- */
-public class APLThemeReceiver extends BroadcastReceiver {
-    private static final String TAG = APLThemeReceiver.class.getSimpleName();
-    private static final String UI_MODE = "com.amazon.alexa.auto.uiMode";
-
-    @VisibleForTesting
-    String mPayload;
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        Log.d(TAG, "onReceive: " + intent.getAction());
-
-        if (intent.getExtras() == null) {
-            Log.e(TAG, "APL theme intent's extra payload is null.");
-            return;
-        }
-
-        String themeId = intent.getExtras().getString(THEME_ID);
-        Preconditions.checkNotNull(themeId);
-
-        switch (getCurrentUiMode(context).toLowerCase()) {
-            case UI_MODE_VALUE_DARK:
-                if (themeId.equals(THEME_VALUE_BLACK) || themeId.equals(THEME_VALUE_GRAY) || themeId.isEmpty()) {
-                    saveCurrentUiThemeBasedOnMode(context, UI_MODE_VALUE_DARK, themeId);
-                    generateAPLThemePayload(themeId);
-                } else {
-                    // If device is in dark mode, only black, gray and default themes are available
-                    Log.e(TAG, "Invalid theme id is provided in dark mode.");
-                }
-                break;
-            case UI_MODE_VALUE_LIGHT:
-                if (themeId.equals(THEME_VALUE_GRAY_ONE) || themeId.equals(THEME_VALUE_GRAY_TWO) || themeId.isEmpty()) {
-                    saveCurrentUiThemeBasedOnMode(context, UI_MODE_VALUE_LIGHT, themeId);
-                    generateAPLThemePayload(themeId);
-                } else {
-                    // If device is in dark mode, only gray1, gray2 and default themes are available
-                    Log.e(TAG, "Invalid theme id is provided in light mode.");
-                }
-                break;
-            default:
-                Log.e(TAG, "Failed to get valid UI mode.");
-                mPayload = "";
-        }
-
-        APLTheme directive = new APLTheme(mPayload);
-        EventBus.getDefault().post(directive);
-    }
-
-    private void saveCurrentUiThemeBasedOnMode(Context context, String uiMode, String theme) {
-        SharedPreferences.Editor editor;
-        if (uiMode.equals(UI_MODE_VALUE_DARK)) {
-            editor = context.getSharedPreferences(UI_DARK_THEME, 0).edit();
-        } else {
-            editor = context.getSharedPreferences(UI_LIGHT_THEME, 0).edit();
-        }
-        editor.putString(THEME_ID, theme);
-        editor.apply();
-
-        saveAPLThemeProperties(context, uiMode, theme);
-    }
-
-    private String getCurrentUiMode(Context context) {
-        SharedPreferences sharedPreferences = context.getSharedPreferences(UI_MODE, 0);
-        if (sharedPreferences != null) {
-            return sharedPreferences.getString(UI_MODE, "");
-        } else {
-            return "";
-        }
-    }
-
-    /**
-     * Saving APL theme properties for rendering APL template with the updated APL theme.
-     * @param context Android context
-     * @param uiMode day/night mode
-     * @param theme APL theme
-     */
-    private void saveAPLThemeProperties(Context context, String uiMode, String theme) {
-        SharedPreferences.Editor editor = context.getSharedPreferences(APL_RUNTIME_PROPERTIES, 0).edit();
-        if (theme.isEmpty()) {
-            editor.putString(THEME_NAME, uiMode);
-        } else {
-            editor.putString(THEME_NAME, uiMode + "-" + theme);
-        }
-        editor.apply();
-    }
-
-    @VisibleForTesting
-    String generateAPLThemePayload(String themeId) {
-        try {
-            mPayload = new JSONStringer()
-                               .object()
-                               .key(Constants.NAME)
-                               .value(THEME_ID)
-                               .key(Constants.VALUE)
-                               .value(themeId)
-                               .endObject()
-                               .toString();
-        } catch (JSONException e) {
-            Log.e(TAG, "Failed to parse APL theme payload.");
-            mPayload = "";
-        }
-        return mPayload;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/layout/fragment_apl.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/layout/fragment_apl.xml
deleted file mode 100644
index ed4274630..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/layout/fragment_apl.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-ar/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-ar/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-ar/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-de/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-de/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-de/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rAU/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rAU/strings.xml
deleted file mode 100644
index 7330a37e5..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APL Activity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rCA/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rCA/strings.xml
deleted file mode 100644
index 7330a37e5..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APL Activity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rIN/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rIN/strings.xml
deleted file mode 100644
index 7330a37e5..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APL Activity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en/strings.xml
deleted file mode 100644
index 7330a37e5..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-en/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APL Activity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es-rMX/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es-rMX/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es-rMX/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es-rUS/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es-rUS/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-es/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-fr-rCA/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-fr-rCA/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-fr/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-fr/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-fr/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-hi-rIN/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-hi-rIN/strings.xml
deleted file mode 100644
index 6b9a57861..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-hi-rIN/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APL गतिविधि
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-it/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-it/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-it/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-ja/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-ja/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-ja/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-pt-rBR/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-pt-rBR/strings.xml
deleted file mode 100644
index 91fa869fc..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values/dimens.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values/dimens.xml
deleted file mode 100644
index b023083be..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-    25dp
-    25dp
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values/strings.xml b/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values/strings.xml
deleted file mode 100644
index 35d42268d..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    APLActivity
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/TestResourceFileReader.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/TestResourceFileReader.java
deleted file mode 100644
index dfa234d6b..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/TestResourceFileReader.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.amazon.alexa.auto.apl;
-
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Optional;
-
-public class TestResourceFileReader {
-    /**
-     * Read contents of a file from test resources folder under test.
-     *
-     * @param fileName Name of the file.
-     * @return content of the file as String.
-     */
-    public static Optional readFileContent(String fileName) {
-        URL fileURL = ClassLoader.getSystemResource(fileName);
-
-        try {
-            String fileContent = new String(Files.readAllBytes(Paths.get(fileURL.getPath())));
-            return Optional.of(fileContent);
-        } catch (Exception e) {
-            return Optional.empty();
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/handler/APLHandlerTest.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/handler/APLHandlerTest.java
deleted file mode 100644
index 90d90bc77..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/handler/APLHandlerTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.amazon.alexa.auto.apl.handler;
-
-import static org.mockito.Mockito.times;
-
-import android.content.Context;
-
-import com.amazon.alexa.auto.aacs.common.AACSMessageSender;
-import com.amazon.apl.android.APLLayout;
-import com.amazon.apl.android.render.APLPresenter;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.robolectric.RobolectricTestRunner;
-
-import java.lang.ref.WeakReference;
-
-@RunWith(RobolectricTestRunner.class)
-public class APLHandlerTest {
-    private Context mContext;
-    private AACSMessageSender mAACSSender;
-    private APLLayout mAPLLayout;
-    private APLPresenter mAPLPresenter;
-    private APLLocalInfoHandler mAPLLocalInfoHandler;
-
-    private APLHandler mClassUnderTest;
-
-    @Before
-    public void setup() {
-        mContext = Mockito.mock(Context.class);
-        mAACSSender = Mockito.mock(AACSMessageSender.class);
-        mAPLLayout = Mockito.mock(APLLayout.class);
-        mAPLPresenter = Mockito.mock(APLPresenter.class);
-        mAPLLocalInfoHandler = Mockito.mock(APLLocalInfoHandler.class);
-
-        mClassUnderTest = new APLHandler(new WeakReference<>(mContext), mAACSSender, mAPLLayout);
-        mClassUnderTest.mPresenter = mAPLPresenter;
-        mClassUnderTest.mAPLLocalInfoHandler = mAPLLocalInfoHandler;
-    }
-
-    @Test
-    public void renderDocumentTest() {
-        mClassUnderTest.renderDocument("samplePayload", "sampleToken", "sampleWindowId");
-        Mockito.verify(mClassUnderTest.mPresenter, times(1))
-                .onRenderDocument("samplePayload", "sampleToken", "sampleWindowId");
-    }
-
-    @Test
-    public void clearDocumentTest() {
-        mClassUnderTest.clearDocument("sampleToken");
-        Mockito.verify(mClassUnderTest.mPresenter, times(1)).onClearDocument("sampleToken");
-        Mockito.verify(mClassUnderTest.mAPLLocalInfoHandler, times(1)).clearLocalInfoData();
-    }
-
-    @Test
-    public void executeCommandTest() {
-        mClassUnderTest.executeCommands("samplePayload", "sampleToken");
-        Mockito.verify(mClassUnderTest.mPresenter, times(1)).onExecuteCommands("samplePayload", "sampleToken");
-    }
-
-    @Test
-    public void handleAPLRuntimePropertiesTest() {
-        mClassUnderTest.handleAPLRuntimeProperties("sampleAPLProperties");
-        Mockito.verify(mClassUnderTest.mPresenter, times(1)).onAPLRuntimeProperties("sampleAPLProperties");
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/receiver/APLReceiverTest.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/receiver/APLReceiverTest.java
deleted file mode 100644
index 577d39206..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/receiver/APLReceiverTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.amazon.alexa.auto.apl.receiver;
-
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-
-import com.amazon.aacsconstants.Action;
-import com.amazon.aacsconstants.Topic;
-import com.amazon.alexa.auto.apl.APLDirective;
-import com.amazon.alexa.auto.apl.TestResourceFileReader;
-import com.amazon.alexa.auto.apl.receiver.APLReceiver;
-import com.amazon.alexa.auto.apps.common.util.Preconditions;
-
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Optional;
-
-@RunWith(RobolectricTestRunner.class)
-public class APLReceiverTest {
-    @Mock
-    private Context mContext;
-
-    private APLReceiver mClassUnderTest;
-    private EventBus eventBus;
-
-    private String receiveMessageTopic;
-    private String receiveMessageAction;
-    private String receiveMessagePayload;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mClassUnderTest = spy(new APLReceiver());
-        EventBus.getDefault().register(this);
-        eventBus = spy(EventBus.getDefault());
-    }
-
-    @Test
-    public void handleRenderDocumentTest() {
-        Intent getRenderDocumentIntent =
-                generateIntent("aacs/RenderDocument.json", "com.amazon.aacs.aasb.RenderDocument");
-        mClassUnderTest.onReceive(mContext, getRenderDocumentIntent);
-        ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class);
-        Mockito.verify(mContext, Mockito.times(1)).startActivity(intentCaptor.capture());
-        Intent launchedIntent = intentCaptor.getValue();
-        Preconditions.checkNotNull(launchedIntent.getExtras());
-        Assert.assertEquals(launchedIntent.getExtras().getString("payload"),
-                "{\"payload\":\"{this is a sample payload for APL}\"}");
-    }
-
-    @Test
-    public void handleClearDocumentTest() {
-        Intent getClearDocumentIntent = generateIntent("aacs/ClearDocument.json", "com.amazon.aacs.aasb.ClearDocument");
-        mClassUnderTest.onReceive(mContext, getClearDocumentIntent);
-        Assert.assertEquals(receiveMessageTopic, Topic.APL);
-        Assert.assertEquals(receiveMessageAction, Action.APL.CLEAR_DOCUMENT);
-    }
-
-    @Test
-    public void handleUpdateAPLRuntimePropertiesTest() {
-        Intent getClearDocumentIntent = generateIntent(
-                "aacs/UpdateAPLRuntimeProperties.json", "com.amazon.aacs.aasb.UpdateAPLRuntimeProperties");
-        mClassUnderTest.onReceive(mContext, getClearDocumentIntent);
-        Assert.assertEquals(receiveMessageTopic, Topic.APL);
-        Assert.assertEquals(receiveMessageAction, Action.APL.UPDATE_APL_RUNTIME_PROPERTIES);
-    }
-
-    private Intent generateIntent(String resPath, String action) {
-        Intent intent = new Intent(action);
-        Optional sampleAACSAPLMessage = TestResourceFileReader.readFileContent(resPath);
-        Bundle samplePayload = new Bundle();
-        samplePayload.putString("message", sampleAACSAPLMessage.get());
-        intent.putExtra("payload", samplePayload);
-        return intent;
-    }
-
-    @Subscribe
-    public void testOnReceiveEvent(APLDirective directive) {
-        receiveMessageTopic = directive.message.topic;
-        receiveMessageAction = directive.message.action;
-        receiveMessagePayload = directive.message.payload;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/receiver/APLThemeReceiverTest.java b/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/receiver/APLThemeReceiverTest.java
deleted file mode 100644
index f55e0176d..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/java/com/amazon/alexa/auto/apl/receiver/APLThemeReceiverTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.amazon.alexa.auto.apl.receiver;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-
-import com.amazon.alexa.auto.apis.apl.APLTheme;
-
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-public class APLThemeReceiverTest {
-    @Mock
-    private Context mContext;
-
-    private APLThemeReceiver mClassUnderTest;
-    private EventBus eventBus;
-
-    private SharedPreferences mSharedPrefs;
-    private SharedPreferences.Editor mEditor;
-
-    private String receiveThemePayload;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mClassUnderTest = spy(new APLThemeReceiver());
-
-        mSharedPrefs = Mockito.mock(SharedPreferences.class);
-        mEditor = Mockito.mock(SharedPreferences.Editor.class);
-        Mockito.when(mContext.getSharedPreferences(anyString(), anyInt())).thenReturn(mSharedPrefs);
-        Mockito.when(mSharedPrefs.edit()).thenReturn(mEditor);
-
-        EventBus.getDefault().register(this);
-        eventBus = spy(EventBus.getDefault());
-    }
-
-    @Test
-    public void handleValidAPLDarkThemeUpdateTest() {
-        String themeId = "gray";
-        Mockito.when(mSharedPrefs.getString("com.amazon.alexa.auto.uiMode", "")).thenReturn("dark");
-        Intent getAPLThemeUpdateIntent = generateIntent(themeId);
-        mClassUnderTest.onReceive(mContext, getAPLThemeUpdateIntent);
-        Assert.assertNotNull(mClassUnderTest.mPayload);
-        Assert.assertEquals(receiveThemePayload, mClassUnderTest.generateAPLThemePayload(themeId));
-    }
-
-    @Test
-    public void handleInvalidAPLDarkThemeUpdateTest() {
-        Mockito.when(mSharedPrefs.getString("com.amazon.alexa.auto.uiMode", "")).thenReturn("dark");
-        Intent getAPLThemeUpdateIntent = generateIntent("gray1");
-        mClassUnderTest.onReceive(mContext, getAPLThemeUpdateIntent);
-        Assert.assertNull(mClassUnderTest.mPayload);
-    }
-
-    @Test
-    public void handleValidAPLLightThemeUpdateTest() {
-        String themeId = "gray1";
-        Mockito.when(mSharedPrefs.getString("com.amazon.alexa.auto.uiMode", "")).thenReturn("light");
-        Intent getAPLThemeUpdateIntent = generateIntent(themeId);
-        mClassUnderTest.onReceive(mContext, getAPLThemeUpdateIntent);
-        Assert.assertNotNull(mClassUnderTest.mPayload);
-        Assert.assertEquals(receiveThemePayload, mClassUnderTest.generateAPLThemePayload(themeId));
-    }
-
-    @Test
-    public void handleInvalidAPLLightThemeUpdateTest() {
-        Mockito.when(mSharedPrefs.getString("com.amazon.alexa.auto.uiMode", "")).thenReturn("light");
-        Intent getAPLThemeUpdateIntent = generateIntent("black");
-        mClassUnderTest.onReceive(mContext, getAPLThemeUpdateIntent);
-        Assert.assertNull(mClassUnderTest.mPayload);
-    }
-
-    private Intent generateIntent(String themeId) {
-        Intent intent = new Intent("com.amazon.alexa.auto.apl.UpdateAPLTheme");
-        intent.putExtra("themeId", themeId);
-        return intent;
-    }
-
-    @Subscribe
-    public void testOnReceiveEvent(APLTheme theme) {
-        receiveThemePayload = theme.getThemePayload();
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/ClearDocument.json b/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/ClearDocument.json
deleted file mode 100644
index 367b639e4..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/ClearDocument.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "header": {
-    "id": "7fd5e391-572b-47ef-bf4f-34792d283e63",
-    "messageDescription": {
-      "action": "ClearDocument",
-      "topic": "APL"
-    },
-    "messageType": "Publish",
-    "version": "3.3"
-  },
-  "payload": {
-    "payload": ""
-  }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/RenderDocument.json b/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/RenderDocument.json
deleted file mode 100644
index 0073d905b..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/RenderDocument.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "header": {
-    "id": "7fd5e391-572b-47ef-bf4f-34792d283e63",
-    "messageDescription": {
-      "action": "RenderDocument",
-      "topic": "APL"
-    },
-    "messageType": "Publish",
-    "version": "3.3"
-  },
-  "payload": {
-    "payload": "{this is a sample payload for APL}"
-  }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/UpdateAPLRuntimeProperties.json b/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/UpdateAPLRuntimeProperties.json
deleted file mode 100644
index 40137d067..000000000
--- a/aacs/android/app-components/alexa-auto-apl-renderer/src/test/resources/aacs/UpdateAPLRuntimeProperties.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "header": {
-    "id": "7fd5e391-572b-47ef-bf4f-34792d283e63",
-    "messageDescription": {
-      "action": "UpdateAPLRuntimeProperties",
-      "topic": "APL"
-    },
-    "messageType": "Publish",
-    "version": "3.3"
-  },
-  "payload": {
-    "properties": "{This is the sample for APL runtime properties}"
-  }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/.gitignore b/aacs/android/app-components/alexa-auto-apps-common-ui/.gitignore
deleted file mode 100644
index 567609b12..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build/
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/README.md b/aacs/android/app-components/alexa-auto-apps-common-ui/README.md
deleted file mode 100644
index a15057081..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Alexa Auto Apps Common UI
-
-This package provides themes, colors, fonts, styles, icons, and other common UI elements for the Alexa Auto App and app components to use.
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/build.gradle b/aacs/android/app-components/alexa-auto-apps-common-ui/build.gradle
deleted file mode 100644
index 8b2e13e86..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/build.gradle
+++ /dev/null
@@ -1,67 +0,0 @@
-apply plugin: 'com.android.library'
-android {
-    compileSdkVersion 32
-    defaultConfig {
-        minSdkVersion 27
-        targetSdkVersion 27
-        versionCode Integer.parseInt(new Date().format("yyyyMMdd"))
-        versionName "4.2"
-        testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-        debug {
-            testCoverageEnabled true
-            debuggable true
-        }
-    }
-    sourceSets {
-        main {
-            def restrictedAssetsDir = file("$gradle.ext.aacsRootDir/restrictedAssets")
-            if (restrictedAssetsDir.exists()) {
-                project.logger.lifecycle("Building alexa-auto-apps-common-ui using Alexa assets..")
-                res.srcDirs = ['src/main/res', restrictedAssetsDir]
-            } else {
-                project.logger.lifecycle("Building alexa-auto-apps-common-ui using placeholders..")
-                res.srcDirs = ['src/main/res', 'src/main/res-placeholders']
-            }
-        }
-    }
-
-    testOptions {
-        // Unit Test: Make all android methods return true by default
-        unitTests.returnDefaultValues = true
-        unitTests.includeAndroidResources = true
-    }
-
-    compileOptions {
-        targetCompatibility 1.8
-        sourceCompatibility 1.8
-    }
-
-    libraryVariants.all { variant ->
-        variant.outputs.all {
-            def project = "alexa-auto-apps-common-ui"
-            def separator = "_"
-            def buildType = variant.buildType.name
-            def apkName = project + separator + buildType + ".aar"
-            outputFileName = file(apkName).name
-        }
-    }
-
-}
-
-dependencies {
-    implementation project(':alexa-auto-apps-common-util')
-    implementation deps.androidx_appcompat
-    implementation deps.androidx_constraint
-    implementation deps.eventbus
-    implementation deps.androidx_recycler_view
-
-    testImplementation deps.junit
-    testImplementation deps.mockito
-    testImplementation deps.roboelectric
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/proguard-rules.pro b/aacs/android/app-components/alexa-auto-apps-common-ui/proguard-rules.pro
deleted file mode 100644
index f1b424510..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/AndroidManifest.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/AndroidManifest.xml
deleted file mode 100644
index ac0e9e52e..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/CirclePageIndicatorDecoration.java b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/CirclePageIndicatorDecoration.java
deleted file mode 100644
index 2672a4b35..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/CirclePageIndicatorDecoration.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.app.common.ui;
-
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.view.View;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.Interpolator;
-
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-/**
- * Adds circular page indicators at the bottom of view
- */
-public class CirclePageIndicatorDecoration extends RecyclerView.ItemDecoration {
-
-    private static final float DP = Resources.getSystem().getDisplayMetrics().density;
-
-    /**
-     * Height of the space the indicator takes up at the bottom of the view.
-     */
-    private final int mIndicatorHeight = (int) (DP * 16);
-
-    /**
-     * Indicator width.
-     */
-    private final float mIndicatorItemLength = DP * 8;
-    /**
-     * Padding between indicators.
-     */
-    private final float mIndicatorItemPadding = DP * 16;
-
-    /**
-     * Some more natural animation interpolation
-     */
-    private final Interpolator mInterpolator = new AccelerateDecelerateInterpolator();
-
-    private final Paint mPaint = new Paint();
-
-    public CirclePageIndicatorDecoration() {
-        /**
-         * Indicator stroke width.
-         */
-        float mIndicatorStrokeWidth = DP * 8;
-        mPaint.setStrokeWidth(mIndicatorStrokeWidth);
-        mPaint.setStyle(Paint.Style.STROKE);
-        mPaint.setAntiAlias(true);
-    }
-
-    @Override
-    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
-        super.onDrawOver(c, parent, state);
-
-        int itemCount = parent.getAdapter().getItemCount();
-
-        // center horizontally, calculate width and subtract half from center
-        float totalLength = mIndicatorItemLength * itemCount;
-        float paddingBetweenItems = Math.max(0, itemCount - 1) * mIndicatorItemPadding;
-        float indicatorTotalWidth = totalLength + paddingBetweenItems;
-        float indicatorStartX = (parent.getWidth() - indicatorTotalWidth) / 2F;
-
-        // center vertically in the allotted space
-        float indicatorPosY = parent.getHeight() - mIndicatorHeight / 2F - (20 * DP);
-
-        drawInactiveIndicators(c, indicatorStartX, indicatorPosY, itemCount);
-
-        // find active page (which should be highlighted)
-        LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
-        int activePosition = layoutManager.findFirstVisibleItemPosition();
-        if (activePosition == RecyclerView.NO_POSITION) {
-            return;
-        }
-
-        // find offset of active page (if the user is scrolling)
-        final View activeChild = layoutManager.findViewByPosition(activePosition);
-        int left = activeChild.getLeft();
-        int width = activeChild.getWidth();
-        int right = activeChild.getRight();
-
-        // on swipe the active item will be positioned from [-width, 0]
-        // interpolate offset for smooth animation
-        float progress = mInterpolator.getInterpolation(left * -1 / (float) width);
-
-        drawHighlights(c, indicatorStartX, indicatorPosY, activePosition, progress);
-    }
-
-    private void drawInactiveIndicators(Canvas c, float indicatorStartX, float indicatorPosY, int itemCount) {
-        int colorInactive = 0x66FFFFFF;
-        mPaint.setColor(colorInactive);
-
-        // width of item indicator including padding
-        final float itemWidth = mIndicatorItemLength + mIndicatorItemPadding;
-
-        float start = indicatorStartX;
-        for (int i = 0; i < itemCount; i++) {
-            c.drawCircle(start, indicatorPosY, mIndicatorItemLength / 2F, mPaint);
-
-            start += itemWidth;
-        }
-    }
-
-    private void drawHighlights(
-            Canvas c, float indicatorStartX, float indicatorPosY, int highlightPosition, float progress) {
-        int colorActive = 0xFFFFFFFF;
-        mPaint.setColor(colorActive);
-
-        // width of item indicator including padding
-        final float itemWidth = mIndicatorItemLength + mIndicatorItemPadding;
-        float highlightStart = indicatorStartX + itemWidth * highlightPosition;
-        if (progress == 0F) {
-            // no swipe, draw a normal indicator
-            c.drawCircle(highlightStart, indicatorPosY, mIndicatorItemLength / 2F, mPaint);
-        } else {
-            // calculate partial highlight
-            float partialLength = mIndicatorItemLength * progress + mIndicatorItemPadding * progress;
-            c.drawCircle(highlightStart + partialLength, indicatorPosY, mIndicatorItemLength / 2F, mPaint);
-        }
-    }
-
-    @Override
-    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
-        super.getItemOffsets(outRect, view, parent, state);
-        outRect.bottom = mIndicatorHeight;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/LoadingDialog.java b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/LoadingDialog.java
deleted file mode 100644
index 366eb1cb8..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/LoadingDialog.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.app.common.ui;
-
-import android.app.Dialog;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.fragment.app.DialogFragment;
-
-import com.amazon.alexa.auto.apps.common.ui.R;
-import com.amazon.alexa.auto.apps.common.util.Preconditions;
-
-import org.greenrobot.eventbus.EventBus;
-
-/**
- * Dialog class to present loading screen.
- */
-public class LoadingDialog extends DialogFragment {
-    @Override
-    public void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setStyle(DialogFragment.STYLE_NO_TITLE, R.style.Alexa_DialogStyle);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        return inflater.inflate(R.layout.loading_dialog_layout, container, false);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        Dialog dialog = getDialog();
-        if (dialog != null) {
-            Window window = dialog.getWindow();
-            if (window != null) {
-                window.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
-            }
-        }
-    }
-
-    @Override
-    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
-        Bundle args = getArguments();
-        Preconditions.checkNotNull(args);
-
-        Params params = args.getParcelable("args");
-        Preconditions.checkNotNull(params);
-
-        TextView headerTxt = view.findViewById(R.id.header_text);
-        headerTxt.setText(params.title);
-
-        TextView contentTxt = view.findViewById(R.id.content_text);
-        contentTxt.setText(params.content);
-    }
-
-    /**
-     * Creates an instance of {@link LoadingDialog} with required parameters.
-     *
-     * @param params Parameters needed to construct the dialog object.
-     * @return an instance of {@link LoadingDialog}.
-     */
-    public static LoadingDialog createDialog(Params params) {
-        LoadingDialog dialog = new LoadingDialog();
-        Bundle args = new Bundle();
-        args.putParcelable("args", params);
-        dialog.setArguments(args);
-
-        return dialog;
-    }
-
-    /**
-     * Class to encapsulate parameters required for building the dialog object.
-     */
-    public static class Params implements Parcelable {
-        @NonNull
-        public final String title;
-        @NonNull
-        public final String content;
-
-        /**
-         * Construct the Parameters required for this dialog.
-         *
-         * @param title Title of the dialog.
-         * @param content Content to be displayed in the dialog.
-         */
-        public Params(@NonNull String title, @NonNull String content) {
-            this.title = title;
-            this.content = content;
-        }
-
-        public Params(Parcel in) {
-            this.title = in.readString();
-            this.content = in.readString();
-        }
-
-        public static final Creator CREATOR = new Creator() {
-            @Override
-            public Params createFromParcel(Parcel in) {
-                return new Params(in);
-            }
-
-            @Override
-            public Params[] newArray(int size) {
-                return new Params[size];
-            }
-        };
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel parcel, int i) {
-            parcel.writeString(title);
-            parcel.writeString(content);
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/TwoChoiceDialog.java b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/TwoChoiceDialog.java
deleted file mode 100644
index aad511611..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/ui/TwoChoiceDialog.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.app.common.ui;
-
-import android.app.Dialog;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.fragment.app.DialogFragment;
-
-import com.amazon.alexa.auto.apps.common.ui.R;
-import com.amazon.alexa.auto.apps.common.util.Preconditions;
-
-import org.greenrobot.eventbus.EventBus;
-
-/**
- * Dialog class to present confirmation screen with two choices.
- */
-public class TwoChoiceDialog extends DialogFragment {
-    @VisibleForTesting
-    TextView mBtn1;
-
-    @VisibleForTesting
-    TextView mBtn2;
-
-    @Override
-    public void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setStyle(DialogFragment.STYLE_NO_TITLE, R.style.DeviceDefaults_Dialog);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        return inflater.inflate(R.layout.two_choice_dialog_layout, container, false);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        Dialog dialog = getDialog();
-        if (dialog != null) {
-            Window window = dialog.getWindow();
-            if (window != null) {
-                window.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
-            }
-        }
-    }
-
-    @Override
-    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
-        Bundle args = getArguments();
-        Preconditions.checkNotNull(args);
-
-        Params params = args.getParcelable("args");
-        Preconditions.checkNotNull(params);
-
-        TextView headerTxt = view.findViewById(R.id.header_text);
-        headerTxt.setText(params.title);
-
-        TextView contentTxt = view.findViewById(R.id.content_text);
-        contentTxt.setText(params.content);
-
-        mBtn1 = view.findViewById(R.id.button1);
-        mBtn1.setText(params.button1Text);
-
-        mBtn2 = view.findViewById(R.id.button2);
-        mBtn2.setText(params.button2Text);
-
-        mBtn1.setOnClickListener(btn1View -> {
-            EventBus.getDefault().post(new Button1Clicked(params.dialogKey));
-            dismiss();
-        });
-
-        mBtn2.setOnClickListener(btn2View -> {
-            EventBus.getDefault().post(new Button2Clicked(params.dialogKey));
-            dismiss();
-        });
-    }
-
-    /**
-     * Creates an instance of {@link TwoChoiceDialog} with required parameters.
-     *
-     * @param params Parameters needed to construct the dialog object.
-     * @return an instance of {@link TwoChoiceDialog}.
-     */
-    public static TwoChoiceDialog createDialog(Params params) {
-        TwoChoiceDialog dialog = new TwoChoiceDialog();
-        Bundle args = new Bundle();
-        args.putParcelable("args", params);
-        dialog.setArguments(args);
-
-        return dialog;
-    }
-
-    // Note the choice selection events are raised through event bus so that
-    // events could be delivered even after device is rotated.
-
-    /**
-     * Event bus event that is raised on click of button 1.
-     */
-    public static class Button1Clicked {
-        @NonNull
-        public final String dialogKey;
-
-        public Button1Clicked(@NonNull String dialogKey) {
-            this.dialogKey = dialogKey;
-        }
-    }
-
-    /**
-     * Event bus event that is raised on click of button 2.
-     */
-    public static class Button2Clicked {
-        @NonNull
-        public final String dialogKey;
-
-        public Button2Clicked(@NonNull String dialogKey) {
-            this.dialogKey = dialogKey;
-        }
-    }
-
-    /**
-     * Class to encapsulate parameters required for building the dialog object.
-     */
-    public static class Params implements Parcelable {
-        @NonNull
-        public final String dialogKey;
-        @NonNull
-        public final String title;
-        @NonNull
-        public final String content;
-        @NonNull
-        public final String button1Text;
-        @NonNull
-        public final String button2Text;
-
-        /**
-         * Construct the Parameters required for this dialog.
-         *
-         * @param dialogKey Key for the dialog that is delivered to listener along with
-         *        following events raised from dialog: {@link Button1Clicked} and
-         *        {@link Button2Clicked}.
-         * @param title Title of the dialog.
-         * @param content Content to be displayed in the dialog.
-         * @param button1Text Text for first button.
-         * @param button2Text Text for second button.
-         */
-        public Params(@NonNull String dialogKey, @NonNull String title, @NonNull String content,
-                @NonNull String button1Text, @NonNull String button2Text) {
-            this.title = title;
-            this.content = content;
-            this.button1Text = button1Text;
-            this.button2Text = button2Text;
-            this.dialogKey = dialogKey;
-        }
-
-        public Params(Parcel in) {
-            this.dialogKey = in.readString();
-            this.title = in.readString();
-            this.content = in.readString();
-            this.button1Text = in.readString();
-            this.button2Text = in.readString();
-        }
-
-        public static final Creator CREATOR = new Creator() {
-            @Override
-            public Params createFromParcel(Parcel in) {
-                return new Params(in);
-            }
-
-            @Override
-            public Params[] newArray(int size) {
-                return new Params[size];
-            }
-        };
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel parcel, int i) {
-            parcel.writeString(dialogKey);
-            parcel.writeString(title);
-            parcel.writeString(content);
-            parcel.writeString(button1Text);
-            parcel.writeString(button2Text);
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/util/PopupDialogUtil.java b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/util/PopupDialogUtil.java
deleted file mode 100644
index b8bfb8862..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/util/PopupDialogUtil.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.app.common.util;
-
-import android.app.Dialog;
-import android.content.Context;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.TextPaint;
-import android.text.method.LinkMovementMethod;
-import android.text.style.ClickableSpan;
-import android.view.View;
-import android.webkit.WebView;
-import android.widget.ImageButton;
-import android.widget.TextView;
-
-import com.amazon.alexa.auto.apps.common.ui.R;
-
-import org.jetbrains.annotations.NotNull;
-
-import kotlin.jvm.internal.Intrinsics;
-
-/**
- * Contains Popup UI utility methods
- */
-public class PopupDialogUtil {
-    public static final String USER_AGENT_ANDROID = "Android Mobile";
-
-    /***
-     * Converts part of textView to a clickable popup with a close button
-     * and embeds the given url onto it
-     *
-     * @param context View context
-     * @param textView TextView to apply change on
-     * @param startIndex Start index of text to be converted into a clickable link
-     * @param endIndex End index of text to be converted into a clickable link
-     * @param url URL to emned in the popup
-     * @param color Link Color (defaults to current textView colour if null)
-     *
-     */
-    public static void embedUrlInPopupDialog(
-            Context context, TextView textView, int startIndex, int endIndex, String url, Integer color) {
-        SpannableString spannableString = new SpannableString(textView.getText());
-        final int textColor = color != null ? color : textView.getCurrentTextColor();
-        ClickableSpan clickableSpan = new ClickableSpan() {
-            @Override
-            public void onClick(@NotNull View textView) {
-                final Dialog dialog = new Dialog(context);
-                dialog.setContentView(R.layout.simple_dialog_layout);
-
-                WebView webView = dialog.findViewById(R.id.webView);
-                webView.getSettings().setUserAgentString(USER_AGENT_ANDROID);
-                webView.loadUrl(url);
-
-                ImageButton closeButton = dialog.findViewById(R.id.dialogButtonClose);
-                closeButton.setOnClickListener(v -> dialog.dismiss());
-                dialog.show();
-            }
-
-            @Override
-            public void updateDrawState(@NotNull TextPaint drawState) {
-                Intrinsics.checkNotNullParameter(drawState, "drawState");
-                super.updateDrawState(drawState);
-                drawState.setUnderlineText(true);
-                drawState.setColor(textColor);
-            }
-        };
-
-        spannableString.setSpan(clickableSpan, startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        textView.setText(spannableString);
-        textView.setMovementMethod(LinkMovementMethod.getInstance());
-        textView.setHighlightColor(0);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/util/ViewUtils.java b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/util/ViewUtils.java
deleted file mode 100644
index 0d10ecce0..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/java/com/amazon/alexa/auto/app/common/util/ViewUtils.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.app.common.util;
-
-import static android.view.View.GONE;
-import static android.view.View.INVISIBLE;
-import static android.view.View.VISIBLE;
-
-import android.view.View;
-
-/**
- * Contains reusable view utilities
- */
-public class ViewUtils {
-    public static void toggleViewVisibility(View view, int visible) {
-        switch (visible) {
-            case VISIBLE:
-                view.setVisibility(INVISIBLE);
-                break;
-            case GONE:
-            case INVISIBLE:
-                view.setVisibility(VISIBLE);
-                break;
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res-placeholders/drawable/alexa_bubble_small.png b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res-placeholders/drawable/alexa_bubble_small.png
deleted file mode 100755
index 90d478281..000000000
Binary files a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res-placeholders/drawable/alexa_bubble_small.png and /dev/null differ
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res-placeholders/drawable/alexa_logo.png b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res-placeholders/drawable/alexa_logo.png
deleted file mode 100755
index f3dc7fc36..000000000
Binary files a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res-placeholders/drawable/alexa_logo.png and /dev/null differ
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/color/radio_button_color_selector.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/color/radio_button_color_selector.xml
deleted file mode 100644
index 476d06330..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/color/radio_button_color_selector.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-    
-    
-    
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/gradient_background.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/gradient_background.xml
deleted file mode 100644
index 768473cf8..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/gradient_background.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-    
-        
-            
-        
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/ic_close.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/ic_close.xml
deleted file mode 100644
index 9afd1a6d7..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/ic_close.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-  
-
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/light_button_background.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/light_button_background.xml
deleted file mode 100644
index 8697925b2..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/light_button_background.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-    
-    
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/medium_component_background.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/medium_component_background.xml
deleted file mode 100644
index e19a26572..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/medium_component_background.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-    
-
-    
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/selected_rect_button_background.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/selected_rect_button_background.xml
deleted file mode 100644
index 3c750dc9d..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/selected_rect_button_background.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-    
-    
-    
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/small_component_background.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/small_component_background.xml
deleted file mode 100644
index f0bb0f0f3..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/small_component_background.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-    
-
-    
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/transparent_button_background.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/transparent_button_background.xml
deleted file mode 100644
index 840fae20b..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/transparent_button_background.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-    
-    
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/transparent_rect_button_background.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/transparent_rect_button_background.xml
deleted file mode 100644
index cadf0c494..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/drawable/transparent_rect_button_background.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-    
-    
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-port/two_choice_dialog_layout.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-port/two_choice_dialog_layout.xml
deleted file mode 100644
index a523c6a8d..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-port/two_choice_dialog_layout.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-    
-    
-
-    
-    
-
-    
-    
-
-
-    
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w1100dp-land/two_choice_dialog_layout.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w1100dp-land/two_choice_dialog_layout.xml
deleted file mode 100644
index 4292fecb9..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w1100dp-land/two_choice_dialog_layout.xml
+++ /dev/null
@@ -1,115 +0,0 @@
-
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-    
-
-    
-    
-
-    
-    
-
-
-    
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w1550dp-land/two_choice_dialog_layout.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w1550dp-land/two_choice_dialog_layout.xml
deleted file mode 100644
index 900673756..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w1550dp-land/two_choice_dialog_layout.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-    
-    
-
-    
-    
-
-    
-    
-
-
-    
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w500dp-land/two_choice_dialog_layout.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w500dp-land/two_choice_dialog_layout.xml
deleted file mode 100644
index 8d8c4c253..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout-w500dp-land/two_choice_dialog_layout.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-    
-    
-
-    
-    
-
-    
-    
-
-
-    
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/loading_dialog_layout.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/loading_dialog_layout.xml
deleted file mode 100644
index 891fddc5a..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/loading_dialog_layout.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-    
-    
-
-    
-    
-
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/simple_dialog_layout.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/simple_dialog_layout.xml
deleted file mode 100644
index e49bf3913..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/simple_dialog_layout.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-    
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/two_choice_dialog_layout.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/two_choice_dialog_layout.xml
deleted file mode 100644
index a523c6a8d..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/layout/two_choice_dialog_layout.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-    
-    
-
-    
-    
-
-    
-    
-
-
-    
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-port/dimens.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-port/dimens.xml
deleted file mode 100644
index 0e4b8c282..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-port/dimens.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-    40sp
-    23sp
-
-    36sp
-    400
-    41sp
-
-    120sp
-    49sp
-    23sp
-
-    36sp
-
-    
-    572dp
-    924dp
-    87dp
-    12dp
-    96dp
-    4dp
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-port/styles.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-port/styles.xml
deleted file mode 100644
index b61c74626..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-port/styles.xml
+++ /dev/null
@@ -1,219 +0,0 @@
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-
-    
-    
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1100dp-land/dimens.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1100dp-land/dimens.xml
deleted file mode 100644
index 11d30083a..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1100dp-land/dimens.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-    40sp
-    30sp
-
-    24sp
-    400
-    28sp
-
-    125sp
-    49sp
-    30sp
-
-    32sp
-
-    
-    442dp
-    663dp
-    57dp
-    20dp
-    73dp
-    5dp
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1100dp-land/styles.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1100dp-land/styles.xml
deleted file mode 100644
index 4cf46ee22..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1100dp-land/styles.xml
+++ /dev/null
@@ -1,215 +0,0 @@
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-
-    
-    
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1550dp-land/dimens.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1550dp-land/dimens.xml
deleted file mode 100644
index d2e9c2078..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1550dp-land/dimens.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-    40sp
-    34sp
-
-    36sp
-    400
-    41sp
-
-    125sp
-    60sp
-    34sp
-
-    25sp
-
-    
-    455dp
-    1272dp
-    142dp
-    10dp
-    15dp
-    7dp
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1550dp-land/styles.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1550dp-land/styles.xml
deleted file mode 100644
index 2a27cc8dd..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w1550dp-land/styles.xml
+++ /dev/null
@@ -1,218 +0,0 @@
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-
-    
-    
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w500dp-land/dimens.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w500dp-land/dimens.xml
deleted file mode 100644
index 73505a589..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w500dp-land/dimens.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-    30sp
-    20sp
-
-    20sp
-    400
-    37sp
-
-    96sp
-    40sp
-    23sp
-
-    16sp
-
-    
-    221dp
-    470dp
-    63dp
-    10dp
-    38dp
-    5dp
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w500dp-land/styles.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w500dp-land/styles.xml
deleted file mode 100644
index b15d13e16..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values-w500dp-land/styles.xml
+++ /dev/null
@@ -1,218 +0,0 @@
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-
-    
-    
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/alexa-app-theme.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/alexa-app-theme.xml
deleted file mode 100644
index a6d51ad9b..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/alexa-app-theme.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-    
-
-    
-
-    
-
-    
-
-        
-
-        
-
-        
-
-        
-
-        
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/app-colors.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/app-colors.xml
deleted file mode 100644
index 919a62ab1..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/app-colors.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-    #FFFFFF
-
-    #383F49
-    #FFFFFF
-    #FFFFFF
-    #465150
-    #32435B
-    #10161E
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/app_launcher_icon_background.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/app_launcher_icon_background.xml
deleted file mode 100644
index 31448433e..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/app_launcher_icon_background.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-    #05A0D1
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/attrs.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/attrs.xml
deleted file mode 100644
index 501ae4e5d..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-    
-    
-    
-    
-    
-    
-
-    
-    
-    
-    
-    
-    
-    
-    
-
-    
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/colors.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/colors.xml
deleted file mode 100644
index a6868bbe2..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-#00CFFF
-#555A62
-#FFFFFF
-#000000
-#2F3747
-#232F3E
-#A6ABAF
-#99000000
-
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/dimens.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/dimens.xml
deleted file mode 100644
index 59e0c97c8..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-    40sp
-    34sp
-
-    36sp
-    400
-    41sp
-
-    125sp
-    60sp
-    34sp
-
-    25sp
-
-    36sp
-    28sp
-    24sp
-    12sp
-
-    
-    8dp
-    16dp
-    64dp
-    8dp
-    16dp
-
-    42dp
-
-    
-    
-    
-    40sp
-    30sp
-
-    .12
-    .88
-
-    
-    .20
-    .80
-
-    
-    455dp
-    1272dp
-    142dp
-    10dp
-    15dp
-    7dp
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles-backup.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles-backup.xml
deleted file mode 100644
index 617c3f342..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles-backup.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles.app.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles.app.xml
deleted file mode 100644
index 879faa9c3..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles.app.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles.xml
deleted file mode 100644
index bd155db19..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-
-    
-    
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/theme-alexa-standard.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/theme-alexa-standard.xml
deleted file mode 100644
index dc795ccad..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/theme-alexa-standard.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/theme-device-defaults.xml b/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/theme-device-defaults.xml
deleted file mode 100644
index edceec315..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/main/res/values/theme-device-defaults.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-ui/src/test/java/com/amazon/alexa/auto/app/common/ui/TwoChoiceDialogTest.java b/aacs/android/app-components/alexa-auto-apps-common-ui/src/test/java/com/amazon/alexa/auto/app/common/ui/TwoChoiceDialogTest.java
deleted file mode 100644
index 57b88c9a0..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-ui/src/test/java/com/amazon/alexa/auto/app/common/ui/TwoChoiceDialogTest.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.amazon.alexa.auto.app.common.ui;
-
-import android.os.Bundle;
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.android.controller.ActivityController;
-
-import java.util.Optional;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(RobolectricTestRunner.class)
-public class TwoChoiceDialogTest {
-    private static final String DIALOG_KEY = "dlg-key";
-    private static final String TITLE = "title";
-    private static final String CONTENT = "content";
-    private static final String BTN1TEXT = "btn1";
-    private static final String BTN2TEXT = "btn2";
-
-    private ActivityController mActivityController;
-    private FragmentActivity mActivity;
-    private TwoChoiceDialog mClassUnderTest;
-
-    public static class EventReceiver {
-        private CountDownLatch mBtn1Latch = new CountDownLatch(1);
-        private CountDownLatch mBtn2Latch = new CountDownLatch(1);
-        private TwoChoiceDialog.Button1Clicked mBtn1ClickEvent;
-        private TwoChoiceDialog.Button2Clicked mBtn2ClickEvent;
-
-        @Subscribe
-        public void onBtn1EventReceived(TwoChoiceDialog.Button1Clicked clicked) {
-            mBtn1ClickEvent = clicked;
-            mBtn1Latch.countDown();
-        }
-
-        @Subscribe
-        public void onBtn1EventReceived(TwoChoiceDialog.Button2Clicked clicked) {
-            mBtn2ClickEvent = clicked;
-            mBtn2Latch.countDown();
-        }
-
-        public Optional awaitForBtn1(int timeoutMs) {
-            try {
-                if (mBtn1Latch.await(timeoutMs, TimeUnit.MILLISECONDS))
-                    return Optional.of(mBtn1ClickEvent);
-            } catch (Exception exception) {
-            }
-            return Optional.empty();
-        }
-
-        public Optional awaitForBtn2(int timeoutMs) {
-            try {
-                if (mBtn2Latch.await(timeoutMs, TimeUnit.MILLISECONDS))
-                    return Optional.of(mBtn2ClickEvent);
-            } catch (Exception exception) {
-            }
-            return Optional.empty();
-        }
-    }
-
-    @Before
-    public void setup() {
-        mActivityController = Robolectric.buildActivity(FragmentActivity.class);
-        mActivityController.create().start().resume();
-        mActivity = mActivityController.get();
-        mClassUnderTest = TwoChoiceDialog.createDialog(
-                new TwoChoiceDialog.Params(DIALOG_KEY, TITLE, CONTENT, BTN1TEXT, BTN2TEXT));
-    }
-
-    @Test
-    public void testBtn1Click() {
-        EventReceiver eventReceiver = new EventReceiver();
-        EventBus.getDefault().register(eventReceiver);
-
-        mClassUnderTest.show(mActivity.getSupportFragmentManager(), "test");
-        mClassUnderTest.mBtn1.performClick();
-
-        Optional event = eventReceiver.awaitForBtn1(10000);
-        Assert.assertTrue(event.isPresent());
-        Assert.assertEquals(DIALOG_KEY, event.get().dialogKey);
-
-        EventBus.getDefault().unregister(eventReceiver);
-    }
-
-    @Test
-    public void testBtn2Click() {
-        EventReceiver eventReceiver = new EventReceiver();
-        EventBus.getDefault().register(eventReceiver);
-
-        mClassUnderTest.show(mActivity.getSupportFragmentManager(), "test");
-        mClassUnderTest.mBtn2.performClick();
-
-        Optional event = eventReceiver.awaitForBtn2(10000);
-        Assert.assertTrue(event.isPresent());
-        Assert.assertEquals(DIALOG_KEY, event.get().dialogKey);
-
-        EventBus.getDefault().unregister(eventReceiver);
-    }
-
-    @Test
-    public void testDialogSurvivesScreenRotation() {
-        EventReceiver eventReceiver = new EventReceiver();
-        EventBus.getDefault().register(eventReceiver);
-
-        mClassUnderTest.show(mActivity.getSupportFragmentManager(), "test");
-
-        // Force the activity to restart (and restore from the saved instance data).
-        Bundle bundle = new Bundle();
-        mActivityController.saveInstanceState(bundle).pause().stop().destroy();
-        mActivityController = Robolectric.buildActivity(FragmentActivity.class)
-                                      .create(bundle)
-                                      .start()
-                                      .restoreInstanceState(bundle)
-                                      .resume();
-        mActivity = mActivityController.get();
-
-        TwoChoiceDialog dialogAfterConfigChange = null;
-        for (Fragment fragment : mActivity.getSupportFragmentManager().getFragments()) {
-            if (fragment instanceof TwoChoiceDialog) {
-                dialogAfterConfigChange = (TwoChoiceDialog) fragment;
-                break;
-            }
-        }
-
-        Assert.assertNotNull(dialogAfterConfigChange);
-        dialogAfterConfigChange.mBtn2.performClick();
-
-        Optional event = eventReceiver.awaitForBtn2(10000);
-        Assert.assertTrue(event.isPresent());
-        Assert.assertEquals(DIALOG_KEY, event.get().dialogKey);
-
-        EventBus.getDefault().unregister(eventReceiver);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/.gitignore b/aacs/android/app-components/alexa-auto-apps-common-util/.gitignore
deleted file mode 100644
index 796b96d1c..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/README.md b/aacs/android/app-components/alexa-auto-apps-common-util/README.md
deleted file mode 100644
index 3b7b11912..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Alexa Auto Apps Common Util
-
-This package provides the Alexa Auto App and app components with various helper classes to simplify the implementation. The provided utilities include:
-
-*  Start, Stop and share files with the Alexa Auto App.
-*  Get and set the Alexa properties.
-*  Handle the file operations.
-*  Get the enabled Alexa Auto SDK extra modules.
-*  Get the network connectivity status.
-*  Check the preconditions.
-*  Manage the ambient light sensor and Alexa Auto theme update.
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/build.gradle b/aacs/android/app-components/alexa-auto-apps-common-util/build.gradle
deleted file mode 100644
index b6fbd8431..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/build.gradle
+++ /dev/null
@@ -1,68 +0,0 @@
-apply plugin: 'com.android.library'
-apply plugin: "org.jetbrains.kotlin.android"
-apply plugin: "org.jetbrains.kotlin.kapt"
-
-android {
-    compileSdkVersion 32
-    defaultConfig {
-        minSdkVersion 27
-        targetSdkVersion 27
-        versionCode Integer.parseInt(new Date().format("yyyyMMdd"))
-        versionName "4.2"
-        testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-        debug {
-            testCoverageEnabled true
-            debuggable true
-        }
-    }
-
-    testOptions {
-        // Unit Test: Make all android methods return true by default
-        unitTests.returnDefaultValues = true
-    }
-
-    compileOptions {
-        targetCompatibility 1.8
-        sourceCompatibility 1.8
-    }
-
-    libraryVariants.all { variant ->
-        variant.outputs.all {
-            def project = "alexa-auto-apps-common-util"
-            def separator = "_"
-            def buildType = variant.buildType.name
-            def apkName = project + separator + buildType + ".aar"
-            outputFileName = new File(apkName)
-        }
-    }
-
-}
-
-dependencies {
-    implementation project(':aacsconstants')
-    implementation project(':aacsipc')
-    implementation project(':aacscommonutils')
-    implementation project(':alexa-auto-apis')
-
-    implementation deps.androidx_annotation
-    implementation deps.androidx_core
-
-    // RX
-    implementation deps.rxjava3
-
-    // Eventbus
-    implementation deps.eventbus
-
-    //Unit Tests
-    testImplementation deps.junit
-    testImplementation deps.mockito
-    testImplementation deps.mockito_inline
-    testImplementation deps.androidx_test_core
-    testImplementation deps.roboelectric
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/proguard-rules.pro b/aacs/android/app-components/alexa-auto-apps-common-util/proguard-rules.pro
deleted file mode 100644
index f1b424510..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/AndroidManifest.xml b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/AndroidManifest.xml
deleted file mode 100644
index 395650b02..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-    
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/Constants.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/Constants.java
deleted file mode 100644
index d35f59099..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/Constants.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common;
-
-public class Constants {
-    // Voice Assistance Constants
-    public static final String ALEXA = "ALEXA";
-    public static final String NONALEXA = "NONALEXA";
-    public static final String ALEXA_AND_PTT = "ALEXA_AND_PTT";
-    public static final String NONALEXA_AND_PTT = "NONALEXA_AND_PTT";
-    public static final String VOICE_ASSISTANCE = "VOICE_ASSISTANCE";
-    public static final String ALEXA_LOG_IN = "ALEXA_LOG_IN";
-    public static final String SETUP_DONE = "SETUP_DONE";
-    public static final String PUSH_TO_TALK = "PUSH_TO_TALK";
-    public static final String CBL_START = "CBL_START";
-    public static final String WORK_TOGETHER = "WORK_TOGETHER";
-
-    public static final String UPDATE_ASSISTANT_STATUS = "UPDATE_ASSISTANT_STATUS";
-    public static final String UPDATE_ASSISTANT_GESTURE = "UPDATE_ASSISTANT_GESTURE";
-    public static final String ENABLE_ASSISTANT_AND_ASSIGN_TAP = "ENABLE_ASSISTANT_AND_ASSIGN_TAP";
-    public static final String ASSISTANTS_STATE_CHANGED = "ASSISTANTS_STATE_CHANGED";
-    public static final String ASSISTANTS_GESTURE_CHANGED = "ASSISTANTS_GESTURE_CHANGED";
-    public static final String ENABLE = "ENABLE";
-    public static final String DISABLE = "DISABLE";
-
-    // Assistant State
-    public static final String ALEXA_DISABLED = "ALEXA_DISABLED";
-    public static final String NON_ALEXA_DISABLED = "NON_ALEXA_DISABLED";
-    public static final String BOTH_DISABLED = "BOTH_DISABLED";
-    public static final String BOTH_ENABLED = "BOTH_ENABLED";
-
-    // Amazonlite
-    public static final String MODELS = "models";
-    public static final String PATH = "path";
-
-    // File provider
-    public static final String AACS_SAMPLE_APP_FILE_PROVIDER = "com.amazon.alexa.auto.app.fileprovider";
-
-    // APL Runtime Properties
-    public static final String APL_RUNTIME_PROPERTIES = "com.amazon.alexa.auto.apl.runtime.properties";
-    public static final String APL_RUNTIME_PROPERTY_NAME_KEY = "name";
-    public static final String APL_RUNTIME_PROPERTY_VALUE_KEY = "value";
-    public static final String APL_RUNTIME_PROPERTY_DRIVING_STATE_NAME = "drivingState";
-    public static final String APL_RUNTIME_PROPERTY_THEME_NAME = "theme";
-    public static final String APL_RUNTIME_PROPERTY_DRIVING_STATE_VALUE_MOVING = "moving";
-    public static final String APL_RUNTIME_PROPERTY_DRIVING_STATE_VALUE_PARKED = "parked";
-    public static final String APL_RUNTIME_PROPERTY_VIDEO_NAME = "video";
-    public static final String APL_RUNTIME_PROPERTY_VIDEO_VALUE_ENABLED = "enabled";
-    public static final String APL_RUNTIME_PROPERTY_VIDEO_VALUE_DISABLED = "disabled";
-
-    // Car UX Restrictions
-    public static final String CAR_UX_RESTRICTIONS_DRIVING_STATE_ACTION =
-            "com.amazon.alexa.auto.uxrestrictions.drivingStateChanged";
-    public static final String CAR_UX_RESTRICTIONS_DRIVING_STATE_ACTION_EXTRA_KEY = "drivingState";
-    public static final String CAR_UX_RESTRICTIONS_DRIVING_STATE_VALUE_MOVING = "moving";
-    public static final String CAR_UX_RESTRICTIONS_DRIVING_STATE_VALUE_PARKED = "parked";
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/aacs/AACSServiceController.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/aacs/AACSServiceController.java
deleted file mode 100644
index 0f79db4dd..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/aacs/AACSServiceController.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.aacs;
-
-import static com.amazon.alexa.auto.apps.common.Constants.AACS_SAMPLE_APP_FILE_PROVIDER;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.core.content.FileProvider;
-
-import com.amazon.aacsconstants.AACSConstants;
-import com.amazon.aacsconstants.Action;
-import com.amazon.aacsipc.IPCUtils;
-
-import java.io.File;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-/**
- * Service Controller for AACS.
- */
-public class AACSServiceController {
-    private static final String TAG = AACSServiceController.class.getSimpleName();
-
-    /**
-     * Start Alexa Auto Client Service.
-     *
-     * @param context Android Context to start the service.
-     * @param waitForNewConfig Signal AACS to use new configuration, which will
-     *                         be sent after service start.
-     */
-    public static void startAACS(@NonNull Context context, boolean waitForNewConfig) {
-        Log.i(TAG, "Sending start signal to Alexa Client Service.");
-        Intent intent = new Intent();
-        intent.setComponent(new ComponentName(
-                AACSConstants.getAACSPackageName(new WeakReference(context)), AACSConstants.AACS_CLASS_NAME));
-        intent.setAction(Action.LAUNCH_SERVICE);
-        intent.putExtra(AACSConstants.NEW_CONFIG, waitForNewConfig);
-        checkAndroidVersionAndStartService(context, intent);
-    }
-
-    /**
-     * Stop the Alexa Auto Client Service.
-     *
-     * @param context Android Context to stop the service.
-     */
-    public static void stopAACS(@NonNull Context context) {
-        Intent intent = new Intent();
-        intent.setComponent(new ComponentName(
-                AACSConstants.getAACSPackageName(new WeakReference(context)), AACSConstants.AACS_CLASS_NAME));
-        context.stopService(intent);
-    }
-
-    public static void shareFilePermissionsOfSameType(
-            @NonNull Context context, File parent, String[] filenames, String module) {
-        Log.i(TAG, "shareFilePermissionsOfSameType");
-        ArrayList fileUris = new ArrayList<>();
-        for (String name : filenames) {
-            File file = new File(parent, name);
-            Uri fileUri = FileProvider.getUriForFile(context, AACS_SAMPLE_APP_FILE_PROVIDER, file);
-            context.grantUriPermission(AACSConstants.getAACSPackageName(new WeakReference(context)), fileUri,
-                    Intent.FLAG_GRANT_READ_URI_PERMISSION);
-            fileUris.add(fileUri);
-        }
-
-        Intent shareFileIntent = new Intent();
-        shareFileIntent.setComponent(new ComponentName(
-                AACSConstants.getAACSPackageName(new WeakReference(context)), AACSConstants.AACS_CLASS_NAME));
-        shareFileIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
-        shareFileIntent.setType(context.getContentResolver().getType(fileUris.get(0)));
-        shareFileIntent.putExtra(AACSConstants.CONFIG_MODULE, module);
-        shareFileIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, fileUris);
-        checkAndroidVersionAndStartService(context, shareFileIntent);
-    }
-
-    public static void checkAndroidVersionAndStartService(@NonNull Context context, Intent intent) {
-        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O
-                && !IPCUtils.getInstance(context).isSystemApp()) {
-            context.startForegroundService(intent);
-        } else {
-            context.startService(intent);
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/message/AssistantMessage.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/message/AssistantMessage.java
deleted file mode 100644
index 76513e12b..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/message/AssistantMessage.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.message;
-
-import androidx.annotation.Nullable;
-
-/**
- * Assistant Message
- */
-public class AssistantMessage {
-    private String assistantName;
-    private String action;
-    private String payload;
-
-    public AssistantMessage(String assistantName, String action, @Nullable String payload) {
-        this.assistantName = assistantName;
-        this.action = action;
-        this.payload = payload;
-    }
-
-    public String getAssistantName() {
-        return this.assistantName;
-    }
-
-    public String getAction() {
-        return this.action;
-    }
-
-    public String getPayload() {
-        return this.payload;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/DNDSettingsProvider.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/DNDSettingsProvider.java
deleted file mode 100644
index 04be62318..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/DNDSettingsProvider.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.amazon.aacsconstants.Action;
-import com.amazon.aacsconstants.Topic;
-import com.amazon.aacsipc.AACSSender;
-import com.amazon.alexa.auto.aacs.common.AACSMessageSender;
-
-import org.jetbrains.annotations.NotNull;
-import org.json.JSONException;
-import org.json.JSONStringer;
-
-import java.lang.ref.WeakReference;
-
-/**
- * Service class for interacting with Alexa Do Not Disturb Settings
- */
-public class DNDSettingsProvider {
-    private static final String TAG = DNDSettingsProvider.class.getCanonicalName();
-
-    public static final String DND_SETTINGS = "dnd-settings";
-    public static final String DND_SETTING_ENABLED = "dnd-setting-enabled";
-    public static final String DO_NOT_DISTURB_JSON_KEY = "doNotDisturb";
-    public static final boolean DEFAULT_DND_PREFERENCE = false;
-
-    public static boolean updateDNDSetting(@NonNull Context context, boolean value) {
-        try {
-            updateDNDSettingInAACS(context, value);
-            updateDNDInPreferences(context, value);
-            return true;
-        } catch (JSONException e) {
-            Log.e(TAG, "Failed to update DND setting to:" + value);
-            return false;
-        }
-    }
-
-    public static void updateDNDInPreferences(@NotNull Context context, boolean value) {
-        SharedPreferences.Editor editor = context.getSharedPreferences(DND_SETTINGS, 0).edit();
-        editor.putBoolean(DND_SETTING_ENABLED, value);
-        editor.commit();
-    }
-
-    public static boolean isDNDSettingEnabled(@NonNull Context context) {
-        SharedPreferences sharedPreferences = context.getSharedPreferences(DND_SETTINGS, 0);
-        return sharedPreferences.getBoolean(DND_SETTING_ENABLED, DEFAULT_DND_PREFERENCE);
-    }
-
-    public static void resetDNDSetting(@NonNull Context context) {
-        updateDNDSetting(context, DEFAULT_DND_PREFERENCE);
-    }
-
-    private static void updateDNDSettingInAACS(@NotNull Context context, boolean value) throws JSONException {
-        String payload = new JSONStringer().object().key(DO_NOT_DISTURB_JSON_KEY).value(value).endObject().toString();
-        new AACSMessageSender(new WeakReference<>(context), new AACSSender())
-                .sendMessage(Topic.DO_NOT_DISTURB, Action.DoNotDisturb.DO_NOT_DISTURB_CHANGED, payload);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/DefaultAssistantUtil.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/DefaultAssistantUtil.java
deleted file mode 100644
index 3edcd475f..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/DefaultAssistantUtil.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.provider.Settings;
-import android.service.voice.VoiceInteractionService;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import java.util.List;
-
-/**
- * Util class for default assistant setting.
- */
-public class DefaultAssistantUtil {
-    private static final String TAG = DefaultAssistantUtil.class.getSimpleName();
-    private static final String KEY_ASSISTANT = "assistant";
-    private static final String KEY_VIS = "voice_interaction_service";
-    private static final String KEY_VRS = "voice_recognition_service";
-
-    /**
-     * Get the name of the Voice Interaction Service implemented in the Alexa app.
-     *
-     * @param context Android Context.
-     * @return the name of the Voice Interaction Service.
-     */
-    public static String getAlexaVoiceInteractionServiceName(@NonNull Context context) {
-        final List services = context.getPackageManager().queryIntentServices(
-                new Intent(VoiceInteractionService.SERVICE_INTERFACE), 0);
-        String packageName = "";
-        String serviceName = "";
-        for (final ResolveInfo info : services) {
-            packageName = info.serviceInfo.packageName;
-            serviceName = info.serviceInfo.name;
-            if (context.getPackageName().equals(packageName)) {
-                return serviceName;
-            }
-        }
-        return "";
-    }
-
-    /**
-     * Set the Alexa app as the Android default assist app.
-     *
-     * @param context Android Context.
-     * @return true if Alexa is set to the default assistant successfully,
-     *         or false if the operation fails.
-     */
-    public static boolean setAlexaAppAsDefault(@NonNull Context context) {
-        try {
-            String alexaVoiceInteractionServiceName = getAlexaVoiceInteractionServiceName(context);
-            int isPermissionGranted = context.checkSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS);
-            if (PackageManager.PERMISSION_GRANTED != isPermissionGranted) {
-                Log.e(TAG, "WRITE_SECURE_SETTINGS permission is not granted");
-                return false;
-            }
-            String component = context.getPackageName() + "/" + alexaVoiceInteractionServiceName;
-            Settings.Secure.putString(context.getContentResolver(), KEY_ASSISTANT, component);
-            Settings.Secure.putString(context.getContentResolver(), KEY_VIS, component);
-            Settings.Secure.putString(context.getContentResolver(), KEY_VRS, component);
-            return true;
-        } catch (Exception e) {
-            Log.e(TAG, "failed to set Alexa as default Assist App. Exception: " + e.getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * Check whether the Alexa app is set as the Android default assist app.
-     *
-     * @param context Android Context.
-     * @return true if Alexa is selected as the default assistant,
-     *         or false if Alexa is not.
-     */
-    public static boolean isAlexaAppDefaultAssist(@NonNull Context context) {
-        String component = Settings.Secure.getString(context.getContentResolver(), KEY_ASSISTANT);
-        return component != null && component.contains(context.getPackageName());
-    }
-
-    /**
-     * Check whether the default assistant is not selected.
-     *
-     * @param context Android Context.
-     * @return true if no default assistant is set, or false if there is an assistant set as default.
-     */
-    public static boolean isDefaultAssistantNone(@NonNull Context context) {
-        String component = Settings.Secure.getString(context.getContentResolver(), KEY_ASSISTANT);
-        return component == null || component.isEmpty();
-    }
-
-    /**
-     * Check whether the assist app selection screen should be skipped.
-     * The assist app selection screen is skipped in the following scenarios:
-     *  1. The Alexa app is already selected as the default assist app.
-     *  2. if no assist app is selected, the Alexa app successfully sets itself
-     *     as the default assist app.
-     *
-     * @param context Android Context.
-     * @return true if the screen should be skipped, or false if the screen should be displayed.
-     */
-    public static boolean shouldSkipAssistAppSelectionScreen(@NonNull Context context) {
-        if (isAlexaAppDefaultAssist(context)) {
-            Log.i(TAG, "Alexa is already selected as default.");
-            return true;
-        }
-        if (isDefaultAssistantNone(context) && setAlexaAppAsDefault(context)) {
-            Log.i(TAG, "No assist app is selected, thus setting Alexa as default directly.");
-            return true;
-        }
-        Log.i(TAG, "the assist app selection screen should be displayed.");
-        return false;
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/EarconSoundSettingsProvider.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/EarconSoundSettingsProvider.java
deleted file mode 100644
index 7f9c328e7..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/EarconSoundSettingsProvider.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-/**
- * Service class for interacting with Alexa Earcon Settings
- */
-public class EarconSoundSettingsProvider {
-    private static final String TAG = EarconSoundSettingsProvider.class.getCanonicalName();
-
-    public static final String EARCON_SETTINGS = "earcon-settings";
-    public static final String EARCON_SETTINGS_START = "earcon-settings-start";
-    public static final String EARCON_SETTINGS_END = "earcon-settings-end";
-    public static final boolean DEFAULT_SOUND_PREFERENCE = true;
-
-    public static void setStartEarconSetting(@NonNull Context context, boolean value) {
-        Log.d(TAG, "SETTING START SOUND EARCON VALUE TO: " + value);
-        SharedPreferences.Editor editor = context.getSharedPreferences(EARCON_SETTINGS, 0).edit();
-        editor.putBoolean(EARCON_SETTINGS_START, value);
-        editor.apply();
-    }
-
-    public static boolean isStartEarconSettingEnabled(@NonNull Context context) {
-        SharedPreferences sharedPreferences = context.getSharedPreferences(EARCON_SETTINGS, 0);
-        return sharedPreferences.getBoolean(EARCON_SETTINGS_START, DEFAULT_SOUND_PREFERENCE);
-    }
-
-    public static void setEndEarconSetting(@NonNull Context context, boolean value) {
-        Log.d(TAG, "SETTING END SOUND EARCON VALUE TO: " + value);
-        SharedPreferences.Editor editor = context.getSharedPreferences(EARCON_SETTINGS, 0).edit();
-        editor.putBoolean(EARCON_SETTINGS_END, value);
-        editor.apply();
-    }
-
-    public static boolean isEndEarconSettingEnabled(@NonNull Context context) {
-        SharedPreferences sharedPreferences = context.getSharedPreferences(EARCON_SETTINGS, 0);
-        return sharedPreferences.getBoolean(EARCON_SETTINGS_END, DEFAULT_SOUND_PREFERENCE);
-    }
-
-    public static void resetEarconSettings(@NonNull Context context) {
-        setStartEarconSetting(context, DEFAULT_SOUND_PREFERENCE);
-        setEndEarconSetting(context, DEFAULT_SOUND_PREFERENCE);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/FeatureDiscoveryUtil.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/FeatureDiscoveryUtil.java
deleted file mode 100644
index f4a6f16f6..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/FeatureDiscoveryUtil.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Log;
-import android.view.View;
-import android.widget.TextView;
-
-import com.amazon.aacsconstants.AACSPropertyConstants;
-import com.amazon.aacsconstants.Action;
-import com.amazon.aacsconstants.FeatureDiscoveryConstants;
-import com.amazon.aacsconstants.FeatureDiscoveryConstants.Domain;
-import com.amazon.aacsconstants.FeatureDiscoveryConstants.EventType;
-import com.amazon.aacsconstants.Topic;
-import com.amazon.aacsipc.AACSSender;
-import com.amazon.alexa.auto.aacs.common.AACSMessageSender;
-import com.amazon.alexa.auto.apps.common.util.config.AlexaPropertyManager;
-
-import org.json.JSONException;
-import org.json.JSONStringer;
-
-import java.lang.ref.WeakReference;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-/**
- * Helper class that provides feature discovery utilities
- */
-public class FeatureDiscoveryUtil {
-    private static final String TAG = FeatureDiscoveryUtil.class.getSimpleName();
-    public static final String FEATURE_DISCOVERY = "feature-discovery";
-    public static final Integer DEFAULT_LIMIT = 5;
-    public static final long GET_FEATURE_MIN_INTERVAL_IN_MS = 500;
-    public static final Set SUPPORTED_DOMAINS;
-    static {
-        SUPPORTED_DOMAINS = new HashSet<>();
-        SUPPORTED_DOMAINS.add(Domain.GETTING_STARTED);
-        SUPPORTED_DOMAINS.add(Domain.TALENTS);
-        SUPPORTED_DOMAINS.add(Domain.ENTERTAINMENT);
-        SUPPORTED_DOMAINS.add(Domain.COMMS);
-        SUPPORTED_DOMAINS.add(Domain.WEATHER);
-        SUPPORTED_DOMAINS.add(Domain.SMART_HOME);
-        SUPPORTED_DOMAINS.add(Domain.NEWS);
-        SUPPORTED_DOMAINS.add(Domain.NAVIGATION);
-        SUPPORTED_DOMAINS.add(Domain.TRAFFIC);
-        SUPPORTED_DOMAINS.add(Domain.SKILLS);
-        SUPPORTED_DOMAINS.add(Domain.LISTS);
-        SUPPORTED_DOMAINS.add(Domain.SHOPPING);
-        SUPPORTED_DOMAINS.add(Domain.QUESTIONS_ANSWERS);
-        SUPPORTED_DOMAINS.add(Domain.SPORTS);
-        SUPPORTED_DOMAINS.add(Domain.CALENDAR);
-    }
-
-    /**
-     * Create a tag for the feature discovery request from the locale, domain and eventType.
-     *
-     * @param locale The locale of the returned features. If the locale is a language
-     *               combination, the primary language will be used in the tag. For example,
-     *                if the locale is "en-US/es-ES", "en-US" will be used to create the tag.
-     * @param domain The domain of the returned features. {@link Domain}
-     * @param eventType The eventType of the returned features. {@link EventType}
-     * @return String The tag for the returned features.
-     */
-    public static String createTag(String locale, String domain, String eventType) {
-        try {
-            Preconditions.checkNotNull(locale);
-            Preconditions.checkNotNull(domain);
-            Preconditions.checkNotNull(eventType);
-            Preconditions.checkArgument(!locale.isEmpty());
-            Preconditions.checkArgument(!domain.isEmpty());
-            Preconditions.checkArgument(!eventType.isEmpty());
-
-            String normalizedLocale = locale;
-            if (locale.contains("/")) {
-                normalizedLocale = locale.split("/")[0];
-            }
-            return String.format("%s#%s#%s", normalizedLocale, domain, eventType);
-        } catch (Exception e) {
-            Log.e(TAG, "failed to create tag. " + e.getMessage());
-            return "";
-        }
-    }
-
-    /**
-     * Save the features in the shared preference by their tag.
-     *
-     * @param context The application context.
-     * @param tag The tag of the feature discovery request. The tag can be created
-     *            using {@link #createTag(String, String, String)} method.
-     * @param features A set of utterance strings to save in the shared preference.
-     */
-    public static void saveFeaturesByTag(Context context, String tag, Set features) {
-        if (context == null) {
-            Log.e(TAG, "context is null");
-            return;
-        }
-        if (features == null || features.size() == 0) {
-            Log.w(TAG, "No feature is saved. Tag: " + tag);
-            return;
-        }
-        SharedPreferences.Editor editor = context.getSharedPreferences(FEATURE_DISCOVERY, 0).edit();
-        editor.putStringSet(tag, features);
-        editor.apply();
-    }
-
-    /**
-     * Retrieve the features from the shared preference by their tag.
-     *
-     * @param context The application context.
-     * @param tag The tag of the feature discovery request. The tag can be created
-     *            using {@link #createTag(String, String, String)} method.
-     * @return The set of utterance strings retrieved from the shared preference.
-     */
-    public static Set getFeaturesByTag(Context context, String tag) {
-        try {
-            Preconditions.checkNotNull(context);
-            Preconditions.checkNotNull(tag);
-            SharedPreferences sharedPreferences = context.getSharedPreferences(FEATURE_DISCOVERY, 0);
-            Set featureSet = sharedPreferences.getStringSet(tag, null);
-            if (featureSet == null) {
-                throw new NullPointerException("No feature found for tag: " + tag);
-            }
-            return featureSet;
-        } catch (Exception e) {
-            Log.e(TAG, "failed to get features by tag. Error: " + e.getMessage());
-            return new HashSet<>();
-        }
-    }
-
-    /**
-     * Clear all the discovered features in the shared preference.
-     *
-     * @param context The application context.
-     */
-    public static void clearDiscoveredFeatures(Context context) {
-        try {
-            Preconditions.checkNotNull(context);
-            SharedPreferences.Editor editor = context.getSharedPreferences(FEATURE_DISCOVERY, 0).edit();
-            editor.clear();
-            editor.apply();
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to clear cache. Error: " + e.getMessage());
-        }
-    }
-
-    /**
-     * Get the cached features and assign the text to the list of text views displayed in setup flow.
-     *
-     * @param textViews A list of {@link TextView} to be assigned with the retrieved features.
-     * @param propertyManager The {@link AlexaPropertyManager} used to get the Alexa locale.
-     * @param context The application context.
-     */
-    public static void setFeaturesInSetupFlow(
-            List textViews, AlexaPropertyManager propertyManager, Context context) {
-        if (propertyManager == null) {
-            Log.e(TAG, "propertyManager is null");
-            return;
-        }
-        propertyManager.getAlexaProperty(AACSPropertyConstants.LOCALE)
-                .filter(Optional::isPresent)
-                .map(Optional::get)
-                .subscribe(alexaLocale -> {
-                    Set featureSet = FeatureDiscoveryUtil.getFeaturesByTag(context,
-                            FeatureDiscoveryUtil.createTag(alexaLocale,
-                                    FeatureDiscoveryConstants.Domain.GETTING_STARTED,
-                                    FeatureDiscoveryConstants.EventType.SETUP));
-                    int i = 0;
-                    for (String feature : featureSet) {
-                        if (i == textViews.size())
-                            break;
-                        textViews.get(i).setText(feature);
-                        i++;
-                    }
-                    Log.i(TAG, "Dynamic hints set for setup flow. Number of hints: " + i);
-                });
-    }
-
-    /**
-     * Construct and publish the GetFeatures message to the engine if the network is connected.
-     *
-     * @param context The application context.
-     * @param requests The string of the feature discovery requests.
-     */
-    public static void checkNetworkAndPublishGetFeaturesMessage(Context context, String requests) {
-        if (NetworkUtil.TYPE_NOT_CONNECTED == NetworkUtil.getConnectivityStatus(context)) {
-            Log.e(TAG, "Network is not connected. Aborting the GetFeatures request.");
-            return;
-        }
-        try {
-            String payload = new JSONStringer()
-                                     .object()
-                                     .key(FeatureDiscoveryConstants.DISCOVERY_REQUESTS)
-                                     .value(requests)
-                                     .endObject()
-                                     .toString();
-            new AACSMessageSender(new WeakReference<>(context), new AACSSender())
-                    .sendMessage(Topic.FEATURE_DISCOVERY, Action.FeatureDiscovery.GET_FEATURES, payload);
-        } catch (JSONException e) {
-            Log.e(TAG, "Fail to generate GetFeatures message.");
-        }
-    }
-
-    /**
-     * Construct and publish the GetFeatures message to the engine if the network is connected.
-     *
-     * @param context The application context.
-     * @param domains The set of domains of the requests.
-     * @param eventType The eventType of the requests.
-     */
-    public static void checkNetworkAndPublishGetFeaturesMessage(
-            Context context, Set domains, String eventType) {
-        try {
-            JSONStringer requestStringer = new JSONStringer();
-            requestStringer.array();
-            for (String domain : domains) {
-                requestStringer.object()
-                        .key(FeatureDiscoveryConstants.DOMAIN)
-                        .value(domain)
-                        .key(FeatureDiscoveryConstants.EVENT_TYPE)
-                        .value(eventType)
-                        .key(FeatureDiscoveryConstants.LIMIT)
-                        .value(DEFAULT_LIMIT)
-                        .endObject();
-            }
-            requestStringer.endArray();
-            checkNetworkAndPublishGetFeaturesMessage(context, requestStringer.toString());
-        } catch (JSONException e) {
-            Log.e(TAG, "Fail to generate discoveryRequests.");
-        }
-    }
-
-    /**
-     * Construct and publish the GetFeatures message to the engine if the network is connected.
-     *
-     * @param context The application context.
-     * @param domain The domain of the single request.
-     * @param eventType The eventType of the single request.
-     */
-    public static void checkNetworkAndPublishGetFeaturesMessage(Context context, String domain, String eventType) {
-        checkNetworkAndPublishGetFeaturesMessage(context, new HashSet<>(Arrays.asList(domain)), eventType);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/FileUtil.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/FileUtil.java
deleted file mode 100644
index 90062799c..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/FileUtil.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import static com.amazon.alexa.auto.apps.common.Constants.MODELS;
-
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-
-import io.reactivex.rxjava3.core.Single;
-
-/**
- * Alexa auto app file util class.
- */
-public class FileUtil {
-    private static final String TAG = FileUtil.class.getSimpleName();
-
-    private static final String CONFIG_DIR = "config";
-    private static final String AACS_CONFIG_FILE = "aacs_config.json";
-    private static final String LOCALES_FILE = "locales.json";
-
-    /**
-     * Read content of configuration file asynchronously
-     *
-     * @param context Android Context.
-     * @return {@link Single} of {@link String} that is resolved when file
-     *          contents are available.
-     */
-    public static Single readAACSConfigurationAsync(@NonNull Context context) {
-        return readAACSConfigurationAsync(context, new Handler(Looper.getMainLooper()));
-    }
-
-    /**
-     * Read content of configuration file asynchronously
-     *
-     * @param context Android Context.
-     * @param resultHandler Handler thread where result would be dispatched.
-     * @return {@link Single} of {@link String} that is resolved when file
-     *          contents are available.
-     */
-    public static Single readAACSConfigurationAsync(@NonNull Context context, @NonNull Handler resultHandler) {
-        return readAACSConfigurationAsync(
-                context, resultHandler, Environment.getExternalStorageDirectory().getAbsolutePath());
-    }
-
-    /**
-     * Read content of configuration file asynchronously
-     *
-     * @param context Android Context.
-     * @param resultHandler Handler thread where result would be dispatched.
-     * @param externalStorageDir Path to external storage directory.
-     * @return {@link Single} of {@link String} that is resolved when file
-     *          contents are available.
-     */
-    public static Single readAACSConfigurationAsync(
-            @NonNull Context context, @NonNull Handler resultHandler, @NonNull String externalStorageDir) {
-        return Single.create(emitter -> {
-            Thread readThread = new Thread(() -> {
-                try {
-                    Preconditions.checkNotNull(context);
-
-                    String config = FileUtil.readAACSConfiguration(context, externalStorageDir);
-
-                    resultHandler.post(() -> emitter.onSuccess(config));
-                } catch (IOException e) {
-                    Log.e(TAG, "Failed to read AACS configuration. Error: " + e);
-                    emitter.onError(e);
-                }
-            });
-
-            readThread.setDaemon(true);
-            readThread.start();
-        });
-    }
-
-    /**
-     * Reads the content of Alexa locales file.
-     *
-     * @param context Android Context.
-     * @return File contents
-     */
-    @NonNull
-    public static String readLocales(@NonNull Context context) {
-        AssetManager assetManager = context.getAssets();
-        try {
-            return readStream(assetManager.open(LOCALES_FILE));
-        } catch (IOException e) {
-            Log.e(TAG, "Failed to fetch locales from locales asset file.");
-            return "";
-        }
-    }
-
-    /**
-     * Copy wake word models to files directory
-     * @param context Android context.
-     */
-    public static void copyModelsToFilesDir(Context context) {
-        Log.i(TAG, "copyModelsToFilesDir");
-        File modelsDir = new File(context.getFilesDir(), MODELS);
-        if (!modelsDir.exists()) {
-            if (!modelsDir.mkdir()) {
-                Log.e(TAG, "Error creating models directory.");
-                return;
-            }
-            try {
-                AssetManager assetManager = context.getAssets();
-                String[] modelAssets = assetManager.list(MODELS);
-                if (modelAssets != null) {
-                    for (String next : modelAssets) {
-                        if (copyFileFromAssetPath(MODELS + "/" + next, new File(modelsDir, next), false, assetManager))
-                            continue;
-                        return;
-                    }
-                }
-            } catch (IOException e) {
-                Log.e(TAG,
-                        String.format(
-                                "Error while copying models from assets into filesDir. Error: %s", e.getMessage()));
-            }
-        } else {
-            Log.i(TAG, "Models directory already exists");
-        }
-    }
-
-    /**
-     * Copy file to destination path
-     * @param assetPath The file path to the asset.
-     * @param destFile The destination file.
-     * @param force True if coping even if the file already exists. False otherwise.
-     * @param assetManager The Android Asset Manager.
-     * @return True if the operation succeeds. False otherwise.
-     */
-    private static boolean copyFileFromAssetPath(
-            String assetPath, File destFile, boolean force, AssetManager assetManager) {
-        if (!destFile.exists() || force) {
-            if (destFile.getParentFile().exists() || destFile.getParentFile().mkdirs()) {
-                // Copy the asset to the dest path
-                try (InputStream is = assetManager.open(assetPath); OutputStream os = new FileOutputStream(destFile)) {
-                    byte[] buf = new byte[1024];
-                    int len;
-                    while ((len = is.read(buf)) > 0) {
-                        os.write(buf, 0, len);
-                    }
-                } catch (IOException e) {
-                    Log.e(TAG, "Could not copy file " + assetPath);
-                    return false;
-                }
-            } else {
-                Log.e(TAG, "Could not create directory: " + destFile.getParentFile());
-                return false;
-            }
-        } else {
-            Log.w(TAG, String.format("Skipping existing file in : %s to: %s", assetPath, destFile));
-        }
-        return true;
-    }
-
-    /**
-     * Reads the content of AACS configuration file. We will firstly read the config
-     * file from external storage, if the config file is not found, we will read the
-     * config from default file in assets.
-     *
-     * @param context Android Context.
-     * @return File contents
-     */
-    @NonNull
-    private static String readAACSConfiguration(@NonNull Context context, @NonNull String externalStorageDir)
-            throws IOException {
-        String configFilePath = "";
-
-        Log.d(TAG,
-                "MODEL = " + android.os.Build.MODEL + "HARDWARE" + android.os.Build.HARDWARE + "PRODUCT"
-                        + android.os.Build.PRODUCT);
-
-        if (BuildConfig.DEBUG) {
-            if (android.os.Build.PRODUCT.contains("car")) {
-                // for AAOS 10 and 12 across all devices unable to access
-                // scoped and legacy storage so picking up from /sdcard directly
-                Log.d(TAG, "Reading from  /sdcard");
-                configFilePath = "/sdcard"
-                        + "/" + AACS_CONFIG_FILE;
-            } else if (android.os.Build.VERSION.SDK_INT >= 30) {
-                // Check if current build is Debug build and runtime Android API level is 30 or above so the application
-                // can read aacs_config.json from the scoped storage location
-                Log.d(TAG, "Reading from scoped storage");
-                configFilePath = context.getExternalFilesDir(null) + "/" + AACS_CONFIG_FILE;
-            } else {
-                // Check if current build is Debug build and installed at runtime Android API level below 30
-                // so that AACS Sample Application can still maintain the legacy storage for aacs_config.json from
-                // /sdcard/
-                Log.d(TAG, "Reading from legacy storage");
-                configFilePath = externalStorageDir + "/" + AACS_CONFIG_FILE;
-            }
-        }
-
-        try {
-            File fullPath = new File(configFilePath);
-            Log.d(TAG, String.format("Reading %s from external storage.", configFilePath));
-            return readStream(new FileInputStream(fullPath));
-        } catch (Exception e) {
-            Log.w(TAG,
-                    String.format("Cannot read %s from external storage. Error: %s", AACS_CONFIG_FILE, e.getMessage()));
-        }
-
-        // Fallback to use built-in AACS Configuration
-        Log.d(TAG, "Fallback to use built-in AACS configuration");
-        AssetManager assetManager = context.getAssets();
-        return readStream(assetManager.open(CONFIG_DIR + "/" + AACS_CONFIG_FILE));
-    }
-
-    /**
-     * Read the content of stream as text string.
-     *
-     * @param inputStream Input stream.
-     * @return Content of input stream as text string.
-     */
-    private static String readStream(@NonNull InputStream inputStream) throws IOException {
-        byte[] buffer = new byte[inputStream.available()];
-        inputStream.read(buffer);
-        return new String(buffer, StandardCharsets.UTF_8);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/LocaleUtil.kt b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/LocaleUtil.kt
deleted file mode 100644
index 110d6ae55..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/LocaleUtil.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util
-
-import androidx.core.os.LocaleListCompat
-
-/**
- * Class for Locale related utilities
- */
-object LocaleUtil {
-    private val TAG = LocaleUtil::class.java.simpleName
-
-    fun parseAlexaLocaleStringToAndroidLocaleList(alexaLocaleString: String): LocaleListCompat {
-        return LocaleListCompat.forLanguageTags(
-            alexaLocaleString.split("/".toRegex())[0]
-        )
-    }
-
-    fun parseAndroidLocaleListToAlexaLocaleString(androidLocaleList: LocaleListCompat): String {
-        return androidLocaleList[0].toString().replace("_", "-")
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/ModuleProvider.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/ModuleProvider.java
deleted file mode 100644
index 63eb10bc9..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/ModuleProvider.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-
-import androidx.annotation.MainThread;
-import androidx.annotation.NonNull;
-
-import com.amazon.alexa.auto.apis.module.ModuleInterface;
-
-import org.json.JSONObject;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import io.reactivex.rxjava3.core.Single;
-
-/**
- * Provider class for Alexa Auto extra modules.
- */
-public class ModuleProvider {
-    public static final String TAG = ModuleProvider.class.getSimpleName();
-    public static final String MODULES = "modules";
-
-    public enum ModuleName { PREVIEW_MODE, ALEXA_CUSTOM_ASSISTANT, GEOLOCATION, LVC }
-
-    public static void addModule(@NonNull Context context, String module) {
-        SharedPreferences.Editor editor = context.getSharedPreferences(MODULES, 0).edit();
-        String modules = context.getSharedPreferences(MODULES, 0).getString(MODULES, "");
-        Preconditions.checkNotNull(modules);
-
-        if (modules.isEmpty()) {
-            editor.putString(MODULES, module);
-        } else if (!modules.contains(module)) {
-            modules = modules + "," + module;
-            editor.putString(MODULES, modules);
-        }
-
-        editor.commit();
-    }
-
-    public static void removeModule(@NonNull Context context, String module) {
-        SharedPreferences.Editor editor = context.getSharedPreferences(MODULES, 0).edit();
-        String modules = context.getSharedPreferences(MODULES, 0).getString(MODULES, "");
-        Preconditions.checkNotNull(modules);
-
-        if (modules.contains(module)) {
-            modules = modules.replace(module, "");
-            // Remove leading comma
-            modules = modules.replaceAll("^,+", "");
-            // Remove trailing comma
-            modules = modules.replaceAll(",+$", "");
-            editor.putString(MODULES, modules);
-        }
-
-        editor.commit();
-    }
-
-    public static String getModules(@NonNull Context context) {
-        SharedPreferences sharedPreferences = context.getSharedPreferences(MODULES, 0);
-        if (sharedPreferences != null) {
-            return sharedPreferences.getString(MODULES, "");
-        } else {
-            return "";
-        }
-    }
-
-    public static boolean isPreviewModeEnabled(@NonNull Context context) {
-        String extraModules = getModules(context);
-        return extraModules.contains(ModuleName.PREVIEW_MODE.name());
-    }
-
-    public static boolean isAlexaCustomAssistantEnabled(@NonNull Context context) {
-        String extraModules = getModules(context);
-        return extraModules.contains(ModuleName.ALEXA_CUSTOM_ASSISTANT.name());
-    }
-
-    public static boolean containsModule(@NonNull Context context, @NonNull ModuleName moduleName) {
-        String extraModules = getModules(context);
-        return extraModules.contains(moduleName.name());
-    }
-
-    public static Optional> getModuleSync(@NonNull Context context) {
-        Log.i(TAG, "getModuleSync: Start scanning moduleInterface from extensions..");
-        List modules = new ArrayList<>();
-        try {
-            String folderName = "aacs-sample-app";
-            String moduleKey = "module";
-            String category = "name";
-            String[] fileList = context.getAssets().list(folderName);
-            for (String f : fileList) {
-                InputStream is = context.getAssets().open(folderName + "/" + f);
-                byte[] buffer = new byte[is.available()];
-                is.read(buffer);
-                String json = new String(buffer, "UTF-8");
-                JSONObject obj = new JSONObject(json);
-                if (obj != null) {
-                    JSONObject moduleKeyObj = obj.optJSONObject(moduleKey);
-                    if (moduleKeyObj == null) {
-                        Log.w(TAG, "module key is missing");
-                        continue;
-                    }
-                    String moduleName = moduleKeyObj.getString(category);
-                    ModuleInterface instance = (ModuleInterface) Class.forName(moduleName).newInstance();
-                    modules.add(instance);
-                    Log.i(TAG, "getModuleSync: load extra module:" + moduleName);
-                }
-                is.close();
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "getModule: " + e.getMessage());
-            return Optional.empty();
-        }
-        return Optional.of(modules);
-    }
-
-    public static Single>> getModuleAsync(
-            @NonNull Context context, @NonNull Handler handler) {
-        return Single.create(emitter -> {
-            handler.post(() -> {
-                Optional> handlerModuleOptional = getModuleSync(context);
-                new Handler(Looper.getMainLooper()).post(() -> emitter.onSuccess(handlerModuleOptional));
-            });
-        });
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/NaviFavoritesSettingsProvider.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/NaviFavoritesSettingsProvider.java
deleted file mode 100644
index 1cff37fba..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/NaviFavoritesSettingsProvider.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-
-import androidx.annotation.NonNull;
-
-import com.amazon.aacsconstants.NaviProviderConstants;
-
-import org.jetbrains.annotations.NotNull;
-
-public class NaviFavoritesSettingsProvider {
-    public static final String NAVI_FAVORITES_SETTINGS = "navi-favorites-settings";
-    public static final String NAVI_FAVORITES_SETTING_ENABLED = "navi-favorites-setting-enabled";
-    public static final boolean DEFAULT_NAVI_FAVORITES_PREFERENCE = false;
-
-    public static boolean updateNavFavoritesSetting(@NonNull Context context, boolean value) {
-        saveNavFavoritesConsent(context, value);
-        sendNavFavoritesIntent(context, value);
-        return true;
-    }
-
-    private static void sendNavFavoritesIntent(Context context, boolean value) {
-        Intent intent = new Intent();
-        intent.addCategory(NaviProviderConstants.CATEGORY_NAVI_FAVORITES);
-        intent.setAction(value ? NaviProviderConstants.ACTION_UPLOAD_NAVI_FAVORITES
-                               : NaviProviderConstants.ACTION_REMOVE_NAVI_FAVORITES);
-        context.sendBroadcast(intent);
-    }
-
-    public static void saveNavFavoritesConsent(@NotNull Context context, boolean value) {
-        SharedPreferences.Editor editor = context.getSharedPreferences(NAVI_FAVORITES_SETTINGS, 0).edit();
-        editor.putBoolean(NAVI_FAVORITES_SETTING_ENABLED, value);
-        editor.apply();
-    }
-
-    public static boolean isNavFavoritesEnabled(@NonNull Context context) {
-        SharedPreferences sharedPreferences = context.getSharedPreferences(NAVI_FAVORITES_SETTINGS, 0);
-        return sharedPreferences.getBoolean(NAVI_FAVORITES_SETTING_ENABLED, DEFAULT_NAVI_FAVORITES_PREFERENCE);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/NetworkUtil.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/NetworkUtil.java
deleted file mode 100644
index f4d6475f2..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/NetworkUtil.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-
-/**
- * Util class for get network connectivity status.
- */
-public class NetworkUtil {
-    public static final int TYPE_WIFI = 1;
-    public static final int TYPE_MOBILE = 2;
-    public static final int TYPE_NOT_CONNECTED = 0;
-    public static final int NETWORK_STATUS_NOT_CONNECTED = 0;
-    public static final int NETWORK_STATUS_WIFI = 1;
-    public static final int NETWORK_STATUS_MOBILE = 2;
-
-    public static int getConnectivityStatus(Context context) {
-        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
-        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
-        if (null != activeNetwork) {
-            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
-                return TYPE_WIFI;
-
-            if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
-                return TYPE_MOBILE;
-        }
-        return TYPE_NOT_CONNECTED;
-    }
-
-    public static int getConnectivityStatusString(Context context) {
-        int conn = NetworkUtil.getConnectivityStatus(context);
-        int status = 0;
-        if (conn == NetworkUtil.TYPE_WIFI) {
-            status = NETWORK_STATUS_WIFI;
-        } else if (conn == NetworkUtil.TYPE_MOBILE) {
-            status = NETWORK_STATUS_MOBILE;
-        } else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
-            status = NETWORK_STATUS_NOT_CONNECTED;
-        }
-        return status;
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/Preconditions.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/Preconditions.java
deleted file mode 100644
index bdcbe7dc8..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/Preconditions.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.os.Looper;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Preconditions checker.
- */
-public class Preconditions {
-    /**
-     * Ensure that expression evaluates to true.
-     *
-     * @param expression expression to evaluate.
-     */
-    public static void checkArgument(boolean expression) {
-        if (!expression) {
-            throw new IllegalArgumentException();
-        }
-    }
-
-    /**
-     * Ensure that expression evaluates to true.
-     *
-     * @param expression expression to evaluate.
-     * @param errorMessage Error message to accompany.
-     */
-    public static void checkArgument(boolean expression, @NonNull Object errorMessage) {
-        if (!expression) {
-            throw new IllegalArgumentException(String.valueOf(errorMessage));
-        }
-    }
-
-    /**
-     * Ensures the object passed to the function is not null.
-     *
-     * @param object Object to check
-     */
-    public static void checkNotNull(@Nullable Object object) {
-        if (object == null) {
-            throw new NullPointerException();
-        }
-    }
-
-    /**
-     * Ensure that function is called from main thread.
-     */
-    public static void checkMainThread() {
-        checkArgument(Looper.myLooper() == Looper.getMainLooper());
-    }
-
-    /**
-     * Ensure that function is not called from main thread.
-     */
-    public static void checkNotMainThread() {
-        checkArgument(Looper.myLooper() != Looper.getMainLooper());
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/UiThemeManager.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/UiThemeManager.java
deleted file mode 100644
index 96c913a74..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/UiThemeManager.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.amazon.aacsconstants.Action;
-import com.amazon.aacsconstants.Topic;
-import com.amazon.alexa.auto.aacs.common.AACSMessageSender;
-import com.amazon.alexa.auto.apis.apl.APLTheme;
-import com.amazon.alexa.auto.apps.common.Constants;
-
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.json.JSONException;
-import org.json.JSONStringer;
-
-import io.reactivex.rxjava3.core.Observable;
-import io.reactivex.rxjava3.subjects.BehaviorSubject;
-
-/**
- * Manager class to handle ambient light sensor and Alexa Auto theme update.
- */
-public class UiThemeManager {
-    private static final String TAG = UiThemeManager.class.getSimpleName();
-    public static final String UI_MODE = "com.amazon.alexa.auto.uiMode";
-    public static final String UI_LIGHT_THEME = "com.amazon.alexa.auto.ui.lightTheme";
-    public static final String UI_DARK_THEME = "com.amazon.alexa.auto.ui.darkTheme";
-
-    // AACS Intent
-    public static final String AACS_INTENT_PAYLOAD_NAME = "name";
-    public static final String AACS_INTENT_PAYLOAD_VALUE = "value";
-
-    // UI Modes
-    public static final String UI_MODE_KEY = "uiMode";
-    public static final String UI_MODE_VALUE_DAY = "day";
-    public static final String UI_MODE_VALUE_NIGHT = "night";
-
-    public static final String THEME_NAME = "theme";
-    public static final String THEME_ID = "themeId";
-    public static final String UI_MODE_VALUE_DARK = "dark";
-    public static final String UI_MODE_VALUE_LIGHT = "light";
-    public static final String THEME_VALUE_BLACK = "black";
-    public static final String THEME_VALUE_GRAY = "gray";
-    public static final String THEME_VALUE_GRAY_ONE = "gray1";
-    public static final String THEME_VALUE_GRAY_TWO = "gray2";
-
-    APLThemeDirectiveReceiver mAPLThemeDirectiveReceiver;
-
-    /**
-     * UI mode type.
-     */
-    public enum UiModeType {
-        LIGHT(1),
-        DARK(2);
-
-        private final int value;
-
-        /**
-         * Enum constructor.
-         *
-         * @param newValue new enum value.
-         */
-        UiModeType(final int newValue) {
-            value = newValue;
-        }
-
-        /**
-         * Get enum value.
-         *
-         * @return integer value.
-         */
-        public int getValue() {
-            return value;
-        }
-
-        /**
-         * String value as lower case.
-         */
-        @Override
-        public String toString() {
-            return name().toLowerCase();
-        }
-    }
-
-    private final Context mContext;
-    private final BehaviorSubject mUiModeUpdated;
-
-    private SensorEventListener mSensorEventListener;
-    private UiModeType mCurrentAlsBasedMode;
-
-    SensorManager mSensorManager;
-    AACSMessageSender mAACSMessageSender;
-
-    private float mCurrentALSValue = -1;
-
-    private static final float ALS_THRESHOLD_VALUE = 10.0f;
-
-    public UiThemeManager(Context context, AACSMessageSender aacsMessageSender) {
-        mContext = context;
-        mUiModeUpdated = BehaviorSubject.createDefault(UiModeType.DARK);
-        mAACSMessageSender = aacsMessageSender;
-    }
-
-    public void init() {
-        Log.i(TAG, "init");
-        mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
-        mAPLThemeDirectiveReceiver = new APLThemeDirectiveReceiver();
-
-        EventBus.getDefault().register(mAPLThemeDirectiveReceiver);
-
-        initAmbientLightSensor();
-    }
-
-    @VisibleForTesting
-    void init(SensorManager sensorManager) {
-        mSensorManager = sensorManager;
-        initAmbientLightSensor();
-    }
-
-    public void destroy() {
-        Log.i(TAG, "destroy");
-        mSensorManager.unregisterListener(mSensorEventListener);
-        EventBus.getDefault().unregister(mAPLThemeDirectiveReceiver);
-    }
-
-    public Observable getUiModeUpdatedObservable() {
-        return mUiModeUpdated;
-    }
-
-    /**
-     * Init ambient light sensor.
-     */
-    private void initAmbientLightSensor() {
-        Log.i(TAG, "initAmbientLightSensor");
-        initSensorListener();
-
-        if (mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) != null) {
-            Log.i(TAG, "Device has ALS");
-            Sensor ambientLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
-            mSensorManager.registerListener(mSensorEventListener, ambientLightSensor, SensorManager.SENSOR_DELAY_UI);
-        } else {
-            Log.e(TAG, "Device has no ALS");
-        }
-    }
-
-    /**
-     * Init sensor listener.
-     */
-    private void initSensorListener() {
-        mSensorEventListener = new SensorEventListener() {
-            @Override
-            public void onSensorChanged(SensorEvent sensorEvent) {
-                float value = sensorEvent.values[0];
-                if (sensorEvent.sensor.getType() == Sensor.TYPE_LIGHT) {
-                    if (value > ALS_THRESHOLD_VALUE) {
-                        if (mCurrentALSValue <= ALS_THRESHOLD_VALUE) {
-                            Log.i(TAG, "setting day theme");
-                            mCurrentALSValue = value;
-                            handleAlsUpdate(UiModeType.LIGHT);
-                        }
-                    } else {
-                        if (mCurrentALSValue > ALS_THRESHOLD_VALUE || mCurrentALSValue == -1) {
-                            Log.i(TAG, "setting night theme");
-                            mCurrentALSValue = value;
-                            handleAlsUpdate(UiModeType.DARK);
-                        }
-                    }
-                }
-            }
-
-            @Override
-            public void onAccuracyChanged(Sensor sensor, int i) {}
-        };
-    }
-
-    /**
-     * Handle ambient light sensor update.
-     *
-     * @param uiModeType @c ThemeType instance.
-     */
-    void handleAlsUpdate(UiModeType uiModeType) {
-        Log.i(TAG, "handleAlsUpdate");
-        if (uiModeType != getCurrentUIMode()) {
-            mCurrentAlsBasedMode = uiModeType;
-            mUiModeUpdated.onNext(uiModeType);
-
-            saveCurrentUIMode(uiModeType);
-            saveAPLThemeProperties(uiModeType);
-            sendUiModeUpdate(uiModeType);
-
-            sendThemeUpdate(uiModeType);
-        }
-    }
-
-    /**
-     * Get current UI mode.
-     *
-     * @return UiModeType UI mode type.
-     */
-    UiModeType getCurrentUIMode() {
-        if (mCurrentAlsBasedMode != null) {
-            return mCurrentAlsBasedMode;
-        }
-
-        return UiModeType.DARK;
-    }
-
-    private void saveCurrentUIMode(UiModeType uiMode) {
-        SharedPreferences.Editor editor = mContext.getSharedPreferences(UI_MODE, 0).edit();
-        editor.putString(UI_MODE, uiMode.toString());
-        editor.apply();
-    }
-
-    /**
-     * Update APL runtime property.
-     */
-    private void sendUiModeUpdate(UiModeType uiMode) {
-        String payload;
-        try {
-            if (uiMode.equals(UiModeType.LIGHT)) {
-                payload = new JSONStringer()
-                                  .object()
-                                  .key(AACS_INTENT_PAYLOAD_NAME)
-                                  .value(UI_MODE_KEY)
-                                  .key(AACS_INTENT_PAYLOAD_VALUE)
-                                  .value(UI_MODE_VALUE_DAY)
-                                  .endObject()
-                                  .toString();
-            } else if (uiMode.equals(UiModeType.DARK)) {
-                payload = new JSONStringer()
-                                  .object()
-                                  .key(AACS_INTENT_PAYLOAD_NAME)
-                                  .value(UI_MODE_KEY)
-                                  .key(AACS_INTENT_PAYLOAD_VALUE)
-                                  .value(UI_MODE_VALUE_NIGHT)
-                                  .endObject()
-                                  .toString();
-            } else {
-                payload = null;
-                Log.e(TAG, "UI mode is invalid.");
-            }
-
-            if (payload != null) {
-                mAACSMessageSender.sendMessage(Topic.APL, Action.APL.SET_PLATFORM_PROPERTY, payload);
-            }
-        } catch (JSONException e) {
-            Log.e(TAG, "Failed to parse UI mode payload.");
-        }
-    }
-
-    private void sendThemeUpdate(UiModeType uiMode) {
-        String themeId = getSavedThemeId(uiMode);
-        try {
-            String payload = new JSONStringer()
-                                     .object()
-                                     .key(AACS_INTENT_PAYLOAD_NAME)
-                                     .value(THEME_ID)
-                                     .key(AACS_INTENT_PAYLOAD_VALUE)
-                                     .value(themeId)
-                                     .endObject()
-                                     .toString();
-            mAACSMessageSender.sendMessage(Topic.APL, Action.APL.SET_PLATFORM_PROPERTY, payload);
-        } catch (JSONException e) {
-            Log.e(TAG, "Failed to parse UI theme payload.");
-        }
-    }
-
-    String getSavedThemeId(UiModeType uiMode) {
-        SharedPreferences sharedPreferences = null;
-        if (uiMode.equals(UiModeType.LIGHT)) {
-            sharedPreferences = mContext.getSharedPreferences(UI_LIGHT_THEME, 0);
-        } else if (uiMode.equals(UiModeType.DARK)) {
-            sharedPreferences = mContext.getSharedPreferences(UI_DARK_THEME, 0);
-        }
-
-        if (sharedPreferences != null) {
-            return sharedPreferences.getString(THEME_ID, "");
-        } else {
-            return "";
-        }
-    }
-
-    /**
-     * Saving APL theme properties for rendering APL template with the updated APL theme.
-     * @param uiMode day/night mode
-     */
-    private void saveAPLThemeProperties(UiModeType uiMode) {
-        String themeId = getSavedThemeId(uiMode);
-        SharedPreferences.Editor editor = mContext.getSharedPreferences(Constants.APL_RUNTIME_PROPERTIES, 0).edit();
-        if (themeId.isEmpty()) {
-            editor.putString(THEME_NAME, uiMode.toString());
-        } else {
-            editor.putString(THEME_NAME, uiMode + "-" + getSavedThemeId(uiMode));
-        }
-        editor.apply();
-    }
-
-    /**
-     * Subscribe APL theme change and update APL runtime property.
-     */
-    @VisibleForTesting
-    class APLThemeDirectiveReceiver {
-        @Subscribe
-        public void OnReceive(APLTheme theme) {
-            mAACSMessageSender.sendMessage(Topic.APL, Action.APL.SET_PLATFORM_PROPERTY, theme.getThemePayload());
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/config/AlexaLocalesProvider.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/config/AlexaLocalesProvider.java
deleted file mode 100644
index 941d31edb..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/config/AlexaLocalesProvider.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util.config;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.annotation.NonNull;
-
-import com.amazon.alexa.auto.apps.common.util.FileUtil;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ExecutorService;
-
-import io.reactivex.rxjava3.core.Single;
-
-/**
- * A helper object to provide Alexa supported locale values.
- */
-public class AlexaLocalesProvider {
-    private static final String TAG = AlexaLocalesProvider.class.getSimpleName();
-
-    @NonNull
-    private final WeakReference mContextWk;
-    @NonNull
-    private final ExecutorService mExecutorService;
-    @NonNull
-    private final Handler mMainThreadHandler;
-
-    public AlexaLocalesProvider(@NonNull WeakReference contextWk, @NonNull ExecutorService executorService) {
-        mContextWk = contextWk;
-        mExecutorService = executorService;
-        mMainThreadHandler = new Handler(Looper.getMainLooper());
-    }
-
-    /**
-     * Fetch Alexa locale's country and language based on locale id.
-     * @param localeId locale id.
-     * @return Locale's {language, country} pair.
-     */
-    public Single>> fetchAlexaSupportedLocaleWithId(String localeId) {
-        return fetchAlexaSupportedLocales().map(localeMap -> {
-            Pair languageCountryPair = localeMap.get(localeId);
-            if (languageCountryPair == null)
-                return Optional.empty();
-            return Optional.of(languageCountryPair);
-        });
-    }
-
-    /**
-     * Fetch all Alexa locale's {country and language}.
-     *
-     * @return Map of Locale's id <-> pair {language and country}.
-     */
-    public Single>> fetchAlexaSupportedLocales() {
-        return Single.create(emitter -> {
-            mExecutorService.submit(() -> {
-                Log.v(TAG, "Fetching alexa supported locales");
-                String locales = FileUtil.readLocales(mContextWk.get());
-
-                Map> localeMap = new HashMap<>();
-                try {
-                    JSONObject jsonObject = new JSONObject(locales);
-                    JSONArray array = jsonObject.getJSONArray("locales");
-
-                    for (int i = 0; i < array.length(); i++) {
-                        JSONObject objectInArray = array.getJSONObject(i);
-                        String localeId = objectInArray.getString("id");
-                        JSONObject locale = objectInArray.getJSONObject("locale");
-                        String language = locale.getString("language");
-                        String country = locale.getString("country");
-                        localeMap.put(localeId, new Pair<>(language, country));
-                    }
-                } catch (JSONException e) {
-                    Log.e(TAG, "Failed to parse locale values from locales json file " + e);
-                    mMainThreadHandler.post(() -> emitter.onError(e));
-                    return;
-                }
-
-                mMainThreadHandler.post(() -> emitter.onSuccess(localeMap));
-            });
-        });
-    }
-
-    /**
-     * Helper method to identify if current device locale is supported by Alexa or not.
-     * @param currentLocale current device locale.
-     * @return true if it is supported by Alexa, otherwise return false.
-     */
-    public Single isCurrentLocaleSupportedByAlexa(String currentLocale) {
-        return fetchAlexaSupportedLocaleList().map(supportedLocaleList -> {
-            for (String supportedLocale : supportedLocaleList) {
-                if (currentLocale.equals(supportedLocale)) {
-                    return true;
-                }
-            }
-
-            return false;
-        });
-    }
-
-    public Single isCurrentLanguageSupportedByAlexa(String currentLanguage) {
-        return fetchAlexaSupportedLocales().map(supportedLocaleList -> {
-            for ( Map.Entry> entry : supportedLocaleList.entrySet()) {
-                if (currentLanguage.equals(entry.getValue().second.split("/")[0])) {
-                    Log.d(TAG, currentLanguage + " is supported by Alexa");
-                    return true;
-                }
-            }
-            return false;
-        });
-    }
-
-    /**
-     * Fetch all Alexa supported locales and put into locale list.
-     */
-    private Single> fetchAlexaSupportedLocaleList() {
-        return Single.create(emitter -> {
-            mExecutorService.submit(() -> {
-                List supportedLocaleList = new ArrayList<>();
-                String locales = FileUtil.readLocales(mContextWk.get());
-
-                if (!locales.equals("")) {
-                    try {
-                        JSONObject jsonObject = new JSONObject(locales);
-                        JSONArray array = jsonObject.getJSONArray("locales");
-                        for (int i = 0; i < array.length(); i++) {
-                            JSONObject objectInArray = array.getJSONObject(i);
-                            supportedLocaleList.add(objectInArray.getString("id"));
-                        }
-                    } catch (JSONException e) {
-                        Log.e(TAG, "Failed to parse locale values from locales json file " + e);
-                        mMainThreadHandler.post(() -> emitter.onError(e));
-                        return;
-                    }
-                }
-
-                mMainThreadHandler.post(() -> emitter.onSuccess(supportedLocaleList));
-            });
-        });
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/config/AlexaPropertyManager.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/config/AlexaPropertyManager.java
deleted file mode 100644
index 68c0cb21d..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/main/java/com/amazon/alexa/auto/apps/common/util/config/AlexaPropertyManager.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.apps.common.util.config;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.amazon.aacsconstants.AACSConstants;
-import com.amazon.aacsconstants.AACSPropertyConstants;
-import com.amazon.aacsconstants.FeatureDiscoveryConstants;
-import com.amazon.alexa.auto.apps.common.util.FeatureDiscoveryUtil;
-import com.amazon.alexa.auto.apps.common.util.LocaleUtil;
-import com.amazon.alexa.auto.apps.common.util.Preconditions;
-
-import java.lang.ref.WeakReference;
-import java.util.Optional;
-import java.util.concurrent.ExecutorService;
-
-import io.reactivex.rxjava3.core.Single;
-
-/**
- * A helper object to provide Alexa property support.
- */
-public class AlexaPropertyManager {
-    private static final String TAG = AlexaPropertyManager.class.getSimpleName();
-
-    private final Uri mUri = Uri.parse("content://" + AACSConstants.AACS_PROPERTY_URI);
-
-    @NonNull
-    private final WeakReference mContextWk;
-    @NonNull
-    private final ExecutorService mExecutorService;
-    @NonNull
-    private final Handler mMainThreadHandler;
-
-    public AlexaPropertyManager(@NonNull WeakReference contextWk, @NonNull ExecutorService executorService) {
-        mContextWk = contextWk;
-        mExecutorService = executorService;
-        mMainThreadHandler = new Handler(Looper.getMainLooper());
-    }
-
-    /**
-     * Query Alexa property with property name.
-     * @param propName property name.
-     * @return future for property value.
-     */
-    public Single> getAlexaProperty(String propName) {
-        return Single.create(emitter -> {
-            mExecutorService.submit(() -> {
-                Optional propValue = getAlexaPropertySync(propName);
-                mMainThreadHandler.post(() -> emitter.onSuccess(propValue));
-            });
-        });
-    }
-
-    /**
-     * Query Alexa property with property name.
-     * @param propName property name.
-     * @return future for property value.
-     */
-    public Single> getAlexaPropertyBoolean(String propName) {
-        return getAlexaProperty(propName).map(propValue -> propValue.map(Boolean::parseBoolean));
-    }
-
-    /**
-     * Update Alexa property with name and value.
-     * @param propName property name.
-     * @param value property value.
-     * @return future success/failure status.
-     */
-    public Single updateAlexaProperty(String propName, String value) {
-        return Single.create(emitter -> {
-            mExecutorService.submit(() -> {
-                boolean updateSucceeded = updateAlexaPropertySync(propName, value);
-                mMainThreadHandler.post(() -> emitter.onSuccess(updateSucceeded));
-            });
-        });
-    }
-
-    /**
-     * Update Alexa property with name and value.
-     * @param propName property name.
-     * @param value property value.
-     * @return future success/failure status.
-     */
-    public Single updateAlexaPropertyBoolean(String propName, boolean value) {
-        return updateAlexaProperty(propName, String.valueOf(value));
-    }
-
-    private Optional getAlexaPropertySync(String name) {
-        try (Cursor cursor = mContextWk.get().getContentResolver().query(mUri, null, name, null, null)) {
-            if (cursor != null) {
-                cursor.moveToFirst();
-                return Optional.of(cursor.getString(1));
-            }
-        }
-
-        return Optional.empty();
-    }
-
-    private boolean updateAlexaPropertySync(String name, String value) {
-        ContentValues values = new ContentValues();
-        values.put(name, value);
-
-        Context context = mContextWk.get();
-        Preconditions.checkNotNull(context);
-
-        // If one row is updated, we are through with update.
-        return context.getContentResolver().update(mUri, values, name, null) == 1;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/aacs/AACSServiceControllerTest.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/aacs/AACSServiceControllerTest.java
deleted file mode 100644
index c3c712ac0..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/aacs/AACSServiceControllerTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.amazon.alexa.auto.apps.common.aacs;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import android.app.Application;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import com.amazon.aacsconstants.AACSConstants;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.Shadows;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(sdk = Build.VERSION_CODES.P)
-public class AACSServiceControllerTest {
-    @Test
-    public void testAACSServiceIsStartedWithWaitForConfig() {
-        testStartAACSService(true);
-    }
-
-    @Test
-    public void testAACSServiceIsStartedWithoutWaitForConfig() {
-        testStartAACSService(false);
-    }
-
-    @Test
-    public void testAACSServiceIsStopped() {
-        Application application = ApplicationProvider.getApplicationContext();
-        AACSServiceController.stopAACS(application);
-
-        Intent stopSvcIntent = Shadows.shadowOf(application).getNextStoppedService();
-        assertEquals(AACSConstants.AACS_CLASS_NAME, stopSvcIntent.getComponent().getClassName());
-        assertEquals(AACSConstants.AACS_PACKAGE_NAME, stopSvcIntent.getComponent().getPackageName());
-    }
-
-    private void testStartAACSService(boolean waitForConfig) {
-        Application application = ApplicationProvider.getApplicationContext();
-        AACSServiceController.startAACS(application, waitForConfig);
-
-        Intent startSvcIntent = Shadows.shadowOf(application).getNextStartedService();
-        assertNotNull(startSvcIntent);
-        assertEquals(AACSConstants.AACS_CLASS_NAME, startSvcIntent.getComponent().getClassName());
-        assertEquals(AACSConstants.AACS_PACKAGE_NAME, startSvcIntent.getComponent().getPackageName());
-        assertEquals(waitForConfig, startSvcIntent.getBooleanExtra(AACSConstants.NEW_CONFIG, !waitForConfig));
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/util/FileUtilTest.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/util/FileUtilTest.java
deleted file mode 100644
index 68f04820f..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/util/FileUtilTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.amazon.alexa.auto.apps.common.util;
-
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.os.Handler;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.junit.MockitoJUnitRunner;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import io.reactivex.rxjava3.observers.TestObserver;
-
-@RunWith(MockitoJUnitRunner.class)
-public class FileUtilTest {
-    private static final String CONFIG_DIR = "config";
-    private static final String DEVICE_CONFIG_FILE = "aacs_config.json";
-    private static final String TEST_AACS_CONFIG_FILE_PATH = "src/test/resources";
-
-    @Mock
-    private Context mMockContext;
-    @Mock
-    private AssetManager mMockAssetManager;
-    @Mock
-    private Handler mMockSameThreadHandler;
-
-    @Before
-    public void setup() throws IOException {
-        MockitoAnnotations.openMocks(this);
-
-        Mockito.when(mMockSameThreadHandler.post(ArgumentMatchers.any(Runnable.class))).thenAnswer(invocation -> {
-            ((Runnable) invocation.getArgument(0)).run();
-            return null;
-        });
-        Mockito.when(mMockContext.getAssets()).thenReturn(mMockAssetManager);
-        InputStream stream = new ByteArrayInputStream("this is a sample stream".getBytes());
-        Mockito.when(mMockAssetManager.open(CONFIG_DIR + "/" + DEVICE_CONFIG_FILE)).thenReturn(stream);
-    }
-
-    @Test
-    public void test_use_config_from_external_path() throws IOException {
-        TestObserver readObserver =
-                FileUtil.readAACSConfigurationAsync(mMockContext, mMockSameThreadHandler, TEST_AACS_CONFIG_FILE_PATH)
-                        .test();
-        readObserver.awaitCount(1);
-        readObserver.assertValue(config -> { return config != null && !config.isEmpty(); });
-
-        Mockito.verify(mMockAssetManager, Mockito.times(0)).open(CONFIG_DIR + "/" + DEVICE_CONFIG_FILE);
-    }
-
-    @Test
-    public void test_use_default_config_in_asset_if_external_path_is_invalid() throws IOException {
-        TestObserver readObserver =
-                FileUtil.readAACSConfigurationAsync(mMockContext, mMockSameThreadHandler, "invalidPath").test();
-        readObserver.awaitCount(1);
-        readObserver.assertValue(config -> config != null && !config.isEmpty());
-
-        Mockito.verify(mMockAssetManager, Mockito.times(1)).open(CONFIG_DIR + "/" + DEVICE_CONFIG_FILE);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/util/UiThemeManagerTest.java b/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/util/UiThemeManagerTest.java
deleted file mode 100644
index 59d750ca0..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/test/java/com/amazon/alexa/auto/apps/common/util/UiThemeManagerTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package com.amazon.alexa.auto.apps.common.util;
-
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_ID;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_VALUE_BLACK;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.THEME_VALUE_GRAY_ONE;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.UI_DARK_THEME;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.UI_LIGHT_THEME;
-import static com.amazon.alexa.auto.apps.common.util.UiThemeManager.UI_MODE;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.hardware.SensorManager;
-
-import com.amazon.alexa.auto.aacs.common.AACSMessageSender;
-
-import org.greenrobot.eventbus.EventBus;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.robolectric.RobolectricTestRunner;
-
-import io.reactivex.rxjava3.core.Observable;
-import io.reactivex.rxjava3.observers.TestObserver;
-
-@RunWith(RobolectricTestRunner.class)
-public class UiThemeManagerTest {
-    private Context mockContext;
-    private SensorManager mockSensorManager;
-    private AACSMessageSender mockAACSMessageSender;
-    private UiThemeManager uiThemeManager;
-    private SharedPreferences mLightModeSharedPrefs;
-    private SharedPreferences mDarkModeModeSharedPrefs;
-    private SharedPreferences mUIModeSharedPrefs;
-    private SharedPreferences.Editor mEditor;
-    private EventBus eventBus;
-    private UiThemeManager.APLThemeDirectiveReceiver mAPLThemeDirectiveReceiver;
-
-    @Before
-    public void setup() {
-        mockContext = Mockito.mock(Context.class);
-        mockSensorManager = Mockito.mock(SensorManager.class);
-        mockAACSMessageSender = Mockito.mock(AACSMessageSender.class);
-        uiThemeManager = new UiThemeManager(mockContext, mockAACSMessageSender);
-        mAPLThemeDirectiveReceiver = Mockito.mock(UiThemeManager.APLThemeDirectiveReceiver.class);
-        mLightModeSharedPrefs = Mockito.mock(SharedPreferences.class);
-        mDarkModeModeSharedPrefs = Mockito.mock(SharedPreferences.class);
-        mUIModeSharedPrefs = Mockito.mock(SharedPreferences.class);
-        mEditor = Mockito.mock(SharedPreferences.Editor.class);
-        Mockito.when(mockContext.getSharedPreferences(eq(UI_MODE), anyInt())).thenReturn(mUIModeSharedPrefs);
-        Mockito.when(mockContext.getSharedPreferences(eq(UI_LIGHT_THEME), anyInt())).thenReturn(mLightModeSharedPrefs);
-        Mockito.when(mockContext.getSharedPreferences(eq(UI_DARK_THEME), anyInt()))
-                .thenReturn(mDarkModeModeSharedPrefs);
-        Mockito.when(mLightModeSharedPrefs.edit()).thenReturn(mEditor);
-        Mockito.when(mDarkModeModeSharedPrefs.edit()).thenReturn(mEditor);
-        Mockito.when(mUIModeSharedPrefs.edit()).thenReturn(mEditor);
-        EventBus.getDefault().register(mAPLThemeDirectiveReceiver);
-        eventBus = spy(EventBus.getDefault());
-    }
-
-    @Test
-    public void test_handle_ui_mode_light() {
-        uiThemeManager.init(mockSensorManager);
-
-        // Act
-        uiThemeManager.handleAlsUpdate(UiThemeManager.UiModeType.LIGHT);
-
-        // Verify
-        Assert.assertEquals(UiThemeManager.UiModeType.LIGHT, uiThemeManager.getCurrentUIMode());
-    }
-
-    @Test
-    public void test_handle_ui_mode_dark() {
-        uiThemeManager.init(mockSensorManager);
-
-        // Act
-        uiThemeManager.handleAlsUpdate(UiThemeManager.UiModeType.DARK);
-
-        // Verify
-        Assert.assertEquals(UiThemeManager.UiModeType.DARK, uiThemeManager.getCurrentUIMode());
-    }
-
-    @Test
-    public void test_handle_ui_theme_in_dark_mode() {
-        uiThemeManager.init(mockSensorManager);
-        Mockito.when(mDarkModeModeSharedPrefs.getString(THEME_ID, "")).thenReturn(THEME_VALUE_BLACK);
-
-        // Act
-        uiThemeManager.handleAlsUpdate(UiThemeManager.UiModeType.DARK);
-
-        // Verify
-        Assert.assertEquals(THEME_VALUE_BLACK, uiThemeManager.getSavedThemeId(UiThemeManager.UiModeType.DARK));
-    }
-
-    @Test
-    public void test_handle_ui_theme_in_light_mode() {
-        uiThemeManager.init(mockSensorManager);
-        Mockito.when(mLightModeSharedPrefs.getString(THEME_ID, "")).thenReturn(THEME_VALUE_GRAY_ONE);
-
-        // Act
-        uiThemeManager.handleAlsUpdate(UiThemeManager.UiModeType.LIGHT);
-
-        // Verify
-        Assert.assertEquals(THEME_VALUE_GRAY_ONE, uiThemeManager.getSavedThemeId(UiThemeManager.UiModeType.LIGHT));
-    }
-
-    @Test
-    public void test_get_ui_mode_update_observable() {
-        uiThemeManager.init(mockSensorManager);
-
-        Observable uiModeUpdatedObservable = uiThemeManager.getUiModeUpdatedObservable();
-        TestObserver testObserver = TestObserver.create();
-        uiModeUpdatedObservable.subscribe(testObserver);
-        testObserver.assertValue(UiThemeManager.UiModeType.DARK);
-
-        // Act
-        uiThemeManager.handleAlsUpdate(UiThemeManager.UiModeType.LIGHT);
-
-        // Verify
-        testObserver = TestObserver.create();
-        uiModeUpdatedObservable.subscribe(testObserver);
-        testObserver.assertValue(UiThemeManager.UiModeType.LIGHT);
-        Assert.assertEquals(UiThemeManager.UiModeType.LIGHT, uiThemeManager.getCurrentUIMode());
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-apps-common-util/src/test/resources/aacs_config.json b/aacs/android/app-components/alexa-auto-apps-common-util/src/test/resources/aacs_config.json
deleted file mode 100644
index fe1b060e8..000000000
--- a/aacs/android/app-components/alexa-auto-apps-common-util/src/test/resources/aacs_config.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "aacs.alexa": {
-    "deviceInfo": {
-      "clientId": "testClientId",
-      "productId" : "testProductId",
-      "deviceSerialNumber": "testDeviceSerialNumber",
-      "manufacturerName": "na",
-      "description": "na"
-    },
-    "localMediaSource": {
-      "types": []
-    }
-  }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/.gitignore b/aacs/android/app-components/alexa-auto-carcontrol/.gitignore
deleted file mode 100644
index 426a199cc..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-*.iml
-.gradle
-/local.properties
-/.idea/caches
-/.idea/libraries
-/.idea/modules.xml
-/.idea/workspace.xml
-/.idea/navEditor.xml
-/.idea/assetWizardSettings.xml
-.DS_Store
-/build
-/captures
-.externalNativeBuild
-.cxx
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/README.md b/aacs/android/app-components/alexa-auto-carcontrol/README.md
deleted file mode 100644
index ab54033cc..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/README.md
+++ /dev/null
@@ -1,177 +0,0 @@
-# Alexa Auto Car Control 
-
-The Alexa Auto Car Control library is an Android library for the Alexa Auto App to run car control commands in cars that are based on Android Automotive OS. A car control command is run by the AACS Core Service each time the user tries to voice-control a vehicle component.
-
-
-## Table of Contents
-- [Overview](#overview)
-- [Understanding Library Components](#understanding-library-components)
-- [Before Using the Alexa Auto Car Control Library](#before-using-the-alexa-auto-car-control-library)
-  - [Including Alexa Auto Car Control Library in a System Application](#including-alexa-auto-car-control-library-in-a-system-application)
-  - [Providing Permission in Android Manifest](#providing-permission-in-android-manifest)
-  - [Ensuring Intent Target Specified in the Library is Used](#ensuring-intent-target-specified-in-the-library-is-used)
-- [Sequence Diagrams](#sequence-diagrams)
-- [How the Alexa Auto Car Control Library Works](#how-the-alexa-auto-car-control-library-works)
-  
-## Overview
-The Alexa Auto Car Control Library allows user utterances to be directly applied to Android Automotive OS car control APIs and then to the Hardware Abstraction Layer to complete the car control workflow. The library translates  between Auto SDK Car Control events and Android Automotive `CarPropertyManager` API calls, which controls various car features, such as air conditioning and fan settings. For information about `CarPropertyManager`, see the [Android documentation on CarPropertyManager](https://developer.android.com/reference/android/car/hardware/property/CarPropertyManager).
-
-The library works with Android [Car API](https://developer.android.com/reference/android/car/Car) and [CarPropertyManager API](https://developer.android.com/reference/android/car/hardware/property/CarPropertyManager). These APIs are only available at Android API level 29 and up.
-
-## Understanding Library Components
-
-The following list describes the purposes of the major components of the library: 
-
-* The AACS Car Control Broadcast Receiver:
-    * Receiving AASB `AdjustControllerValue` or `SetControllerValue` messages from the AACS Core Service.
-    * Instantiating the Car Control Handler to call specific controller operations. The exact operations supported depend on the controller type, which can be Power, Toggle, Mode, or Range.
-
-* The AACS Car Control platform implementation (`CarControlHandler`):
-    * Instantiating the Android Car object to be called in the set and adjust methods for each controller type.
-    * Defining the get and set methods for each controller type.
-    * Defining the adjust methods for the Range or Power Controller.
-
-* The AACS Car Control Helper/Util:
-    * Providing translation between [endpointID, controllerType, controllerID, value] in the AASB Car Control message from the Auto SDK Engine to [propertyId, areaId, value] used in the Android Automotive API call.
-    * Getting or saving the current Mode setting for the Mode Controller.
-    * Enabling you to parse an external configuration file if you want to use a customized `CarControlEndpointMapping.json` file.
-
-* Car Control Endpoint Mapping configuration file maps [endpointID, controllerType, controllerID, value] from the Auto SDK Car Control Asset to [propertyId, areaId, value] used in the Android Automotive API call. 
-
-    A default `CarControlEndpointMapping.json` file is provided in the assets directory. Be sure to review `CarControlEndpointMapping.json` to verify that it contains values consistent with the ones specified in the [CarControlConfig.json file in the Car Control module](https://github.com/alexa/alexa-auto-sdk/blob/4.0/modules/car-control/assets/CarControlConfig.json). For example, if you have changed an `endpointId` in `CarControlConfig.json` from `"default.light"` to `"default.roof.light"`, the `CarControlEndpointMapping.json` file must contain the same endpoint mapping information.
-
-## Before Using the Alexa Auto Car Control Library
-Before using the library, follow these major steps:
-
-1. Install your application as a system privileged app on Android Automotive OS.
-2. Provide permission in your app's Android Manifest.
-3. Ensure that the intent target specified in the library is used.
-
-### Including Alexa Auto Car Control Library in a System Application
-For the Alexa Auto App to enable the permission namespace `android.car.permission`, it must run in a system privileged app. To install your application as a system privileged app, place it in the `/system/priv-app/` directory. 
-
-### Providing Permission in Android Manifest
-For security reasons, for your application to send intents to or receive intents from the Alexa Auto Car Control Library, follow these steps:
-
-1) In `privapp-permissions-com.amazon.alexaautoclientservice.xml`, specify `android.car.permission`. The following example file shows how to specify permissions for using intents for various car control operations.
-
-```xml
-    
-    
-	    
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
-           
-        
-        
-        
-    
-```
-
-2) Include `privapp-permissions-com.amazon.alexaautoclientservice.xml` in the `/etc/permissions/` directory. 
-
-### Ensuring Intent Target Specified in the Library is Used
-The AACS Car Control Broadcast Receiver listens to intents from the AACS Core Service with the `CarControl` topic. The intent filter in the Alexa Auto App Car Control Library already defines the intent target for `CarControl`. For the intent filter in the library to take effect, be sure to clear the intent target defined for `CarControl` in the Alexa Auto App configuration as follows. Otherwise, the target specification in the Alexa Auto App configuration overrides the intent filter in the library.
-
-```json
-    "CarControl" : {
-        "type": [],
-        "package": [],   
-        "class": []
-    }
-``` 
-
-## Sequence Diagrams
-The following diagram illustrates the flow when an utterance asks Alexa to set fan speed to 3.
-![Set Fan Speed](./docs/diagrams/set-fan-speed-to-3.png)
-
-The following diagram illustrates the flow after the set value is finished at the hardware layer.
-![Set Reply](./docs/diagrams/set-reply-to-engine.png)
-
-## How the Alexa Auto Car Control Library Works
-When the user issues an utterance, the Engine receives a car control event from Alexa, which the Engine passes to the Alexa Auto App through an AASB message.
-
-The AASB message received by the Alexa Auto App has the following attributes: 
-
-* Action is `com.amazon.aacs.aasb.AdjustControllerValue` or `com.amazon.aacs.aasb.SetControllerValue`. 
-* Category is `com.amazon.aacs.aasb.CarControl`.
-* Extras is `payload`.
-  
-    The `payload` object includes detailed information about the action, which is  specified in the `messageDescription` field of the AASB message. The following list describes the `payload` for each action:
-    
-    * For `SetControllerValue`, the payload has the following schema:
-      ```
-      "payload" : {
-          "controllerType" : "POWER",
-          "endpointId" : "{{String}}",
-          "turnOn" : {{Boolean}}
-      }
-      ```
-    * For `AdjustControllerValue`, the payload has the following schema:
-      ```
-      "payload" : {
-          "controllerType" : "TOGGLE",
-          "endpointId" : "{{String}}",
-          "controllerId" : "{{String}}",
-          "turnOn" : {{Boolean}}
-      }
-      ```
-    * For `SetModeController`, the payload has the following schema:
-      ```
-      "payload" : {
-          "controllerType" : "MODE",
-          "endpointId" : "{{String}}",
-          "controllerId" : "{{String}}",
-          "value" : "{{String}}"
-      }
-      ```
-    * For `SetRangeController`, the payload has the following schema:
-      ```
-      "payload" : {
-          "controllerType" : "RANGE",
-          "endpointId" : "{{String}}",
-          "controllerId" : "{{String}}",
-          "value" : {{Double}}
-      }
-      ```
-    * For `AdjustModeController`, the payload has the following schema:
-      ```
-      "payload" : {
-          "controllerType" : "MODE",
-          "endpointId" : "{{String}}",
-          "controllerId" : "{{String}}",
-          "delta" : {{Integer}}
-      }
-      ```
-    * For `AdjustRangeController`, the payload has the following schema:
-      ```
-      "payload" : {
-          "controllerType" : "RANGE",
-          "endpointId" : "{{String}}",
-          "controllerId" : "{{String}}",
-          "delta" : {{Double}}
-      }
-      ```
-
-After receiving the intent, the AACS Car Control Broadcast Receiver parses the payload and calls for the Car Control Handler to perform specific car control operations.
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/.gitignore b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/.gitignore
deleted file mode 100644
index 42afabfd2..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/build.gradle b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/build.gradle
deleted file mode 100644
index e83f015a3..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/build.gradle
+++ /dev/null
@@ -1,59 +0,0 @@
-plugins {
-    id 'com.android.library'
-}
-
-android {
-    compileSdkVersion 33
-    defaultConfig {
-        minSdkVersion 27
-        targetSdkVersion 27
-        versionCode Integer.parseInt(new Date().format("yyyyMMdd"))
-        versionName "4.2"
-
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
-        consumerProguardFiles 'consumer-rules.pro'
-        useLibrary 'android.car'
-    }
-
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
-        }
-    }
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
-    }
-
-    testOptions {
-        unitTests {
-            includeAndroidResources = true
-        }
-    }
-}
-
-dependencies {
-    implementation fileTree(dir: 'libs', include: ['*.aar'])
-    implementation project(':aacsconstants')
-    implementation project(':aacscommonutils')
-    implementation project(':aacsipc')
-
-    implementation 'androidx.appcompat:appcompat:1.2.0'
-    implementation 'com.google.android.material:material:1.3.0'
-    testImplementation 'junit:junit:4.12'
-    testImplementation 'androidx.test:runner:1.1.0'
-    testImplementation 'androidx.test:core:1.1.0'
-    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-    androidTestImplementation 'androidx.test:rules:1.1.0'
-    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
-    androidTestImplementation 'androidx.test:monitor:1.1.1'
-    androidTestImplementation 'org.mockito:mockito-android:2.22.0'
-    testImplementation 'org.mockito:mockito-core:1.10.19'
-    testImplementation 'org.powermock:powermock-api-mockito:1.6.2'
-    testImplementation 'org.powermock:powermock-module-junit4-rule-agent:1.6.2'
-    testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.2'
-    testImplementation 'org.powermock:powermock-module-junit4:1.6.2'
-    testImplementation 'org.powermock:powermock-api-easymock:2.0.9'
-    testImplementation 'org.robolectric:annotations:4.3'
-}
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/proguard-rules.pro b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/proguard-rules.pro
deleted file mode 100644
index 481bb4348..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/AndroidManifest.xml b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/AndroidManifest.xml
deleted file mode 100644
index 5318270e0..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-
-    
-    
-
-        
-            
-                
-                
-                
-            
-        
-    
-
-
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/assets/CarControlEndpointMapping.json b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/assets/CarControlEndpointMapping.json
deleted file mode 100644
index 303735621..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/assets/CarControlEndpointMapping.json
+++ /dev/null
@@ -1,1073 +0,0 @@
-{
-    "AACSCarControl":[
-        {
-            "endpointId": "car",
-            "areaId": "0x75",
-            "capabilities": [
-                {
-                    "interface": "ModeController",
-                    "instance": "recirculatemode",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "INSIDE",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_AUTO_RECIRC_ON",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    },
-                                    {
-                                        "propertyId": "HVAC_RECIRC_ON",
-                                        "dataType": "boolean",
-                                        "value": "true"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "OUTSIDE",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_AUTO_RECIRC_ON",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    },
-                                    {
-                                        "propertyId": "HVAC_RECIRC_ON",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "AUTO",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_AUTO_RECIRC_ON",
-                                        "dataType": "boolean",
-                                        "value": "true"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "recirculate",
-                    "configuration": {
-                        "propertyId": "HVAC_RECIRC_ON",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "climate.sync",
-                    "configuration": {
-                        "propertyId": "HVAC_DUAL_ON",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "windowLock",
-                    "configuration": {
-                        "propertyId": "WINDOW_LOCK",
-                        "areaId": "0x540",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "chargedoor",
-            "areaId": "0x0",
-            "capabilities": [
-                {
-                    "interface": "ModeController",
-                    "instance": "position",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "OPEN",
-                                "settings": [
-                                    {
-                                        "propertyId": "EV_CHARGE_PORT_OPEN",
-                                        "dataType": "boolean",
-                                        "value": "true"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "CLOSED",
-                                "settings": [
-                                    {
-                                        "propertyId": "EV_CHARGE_PORT_OPEN",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "default.vent",
-            "areaId": "0x75",
-            "capabilities": [
-                {
-                    "interface": "ModeController",
-                    "instance": "position",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "BODY",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_FAN_DIRECTION",
-                                        "dataType": "int",
-                                        "value": "1"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "FLOOR",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_FAN_DIRECTION",
-                                        "dataType": "int",
-                                        "value": "2"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "MIX",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_FAN_DIRECTION",
-                                        "dataType": "int",
-                                        "value": "0"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "WINDSHIELD",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_FAN_DIRECTION",
-                                        "dataType": "int",
-                                        "value": "4"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "default.ac",
-            "areaId": "0x75",
-            "capabilities": [
-                {
-                    "interface": "ModeController",
-                    "instance": "intensity",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "LOW",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_MAX_AC_ON",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    },
-                                    {
-                                        "propertyId": "HVAC_FAN_SPEED",
-                                        "dataType": "int",
-                                        "value": "2"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "MEDIUM",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_MAX_AC_ON",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    },
-                                    {
-                                        "propertyId": "HVAC_FAN_SPEED",
-                                        "dataType": "int",
-                                        "value": "4"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "HIGH",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_MAX_AC_ON",
-                                        "dataType": "boolean",
-                                        "value": "true"
-                                    },
-                                    {
-                                        "propertyId": "HVAC_FAN_SPEED",
-                                        "dataType": "int",
-                                        "value": "6"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                },
-                {
-                    "interface": "ModeController",
-                    "instance": "mode",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "ECONOMY",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_AUTO_ON",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    },
-                                    {
-                                        "propertyId": "HVAC_AC_ON",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "AUTOMATIC",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_AUTO_ON",
-                                        "dataType": "boolean",
-                                        "value": "true"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "MANUAL",
-                                "settings": [
-                                    {
-                                        "propertyId": "HVAC_AUTO_ON",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                },
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "HVAC_AC_ON",
-                        "dataType": "boolean"
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "driver.seat",
-            "areaId": "0x01",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "heaterintensity",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "heater",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "vent",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_VENTILATION",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ModeController",
-                    "instance": "position",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "ONE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "1"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "TWO",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "2"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "THREE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "3"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "front.seat",
-            "areaId": "0x01",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "heaterintensity",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "heater",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "vent",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_VENTILATION",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ModeController",
-                    "instance": "position",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "ONE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "1"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "TWO",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "2"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "THREE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "3"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "passenger.seat",
-            "areaId": "0x04",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "heaterintensity",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "heater",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "vent",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_VENTILATION",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ModeController",
-                    "instance": "position",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "ONE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "1"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "TWO",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "2"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "THREE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "3"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.driver.seat",
-            "areaId": "0x10",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "heaterintensity",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "heater",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "vent",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_VENTILATION",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ModeController",
-                    "instance": "position",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "ONE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "1"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "TWO",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "2"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "THREE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "3"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.passenger.seat",
-            "areaId": "0x40",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "heaterintensity",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "heater",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_TEMPERATURE",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ToggleController",
-                    "instance": "vent",
-                    "configuration": {
-                        "propertyId": "HVAC_SEAT_VENTILATION",
-                        "dataType": "int"
-                    }
-                },
-                {
-                    "interface": "ModeController",
-                    "instance": "position",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "ONE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "1"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "TWO",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "2"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "THREE",
-                                "settings": [
-                                    {
-                                        "propertyId": "SEAT_MEMORY_SELECT",
-                                        "dataType": "int",
-                                        "value": "3"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "climatecontrol",
-            "areaId": "0x75",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "HVAC_AC_ON",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "default.fan",
-            "areaId": "0x75",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "HVAC_POWER_ON",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                },
-                {
-                    "interface": "RangeController",
-                    "instance": "speed",
-                    "configuration": {
-                        "propertyId": "HVAC_FAN_SPEED",
-                        "dataType": "int",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "default.heater",
-            "areaId": "0x31",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "temperature",
-                    "configuration": {
-                        "propertyId": "HVAC_TEMPERATURE_SET",
-                        "dataType": "float",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "default.reading.light",
-            "areaId": "0x01",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "READING_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "driver.heater",
-            "areaId": "0x01",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "temperature",
-                    "configuration": {
-                        "propertyId": "HVAC_TEMPERATURE_SET",
-                        "dataType": "float",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "driver.reading.light",
-            "areaId": "0x01",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "READING_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "driver.window",
-            "areaId": "0x10",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "height",
-                    "configuration": {
-                        "propertyId": "WINDOW_POS",
-                        "dataType": "int",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "front.foglight",
-            "areaId": "0x01000000",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "FOG_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "front.reading.light",
-            "areaId": "0x05",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "READING_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "front.windshield",
-            "areaId": "0x0001",
-            "capabilities": [
-                {
-                    "interface": "ToggleController",
-                    "instance": "defroster",
-                    "configuration": {
-                        "propertyId": "HVAC_DEFROSTER",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "hazardlight",
-            "areaId": "0x01000000",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "HAZARD_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "ivi",
-            "areaId": "0x01000000",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "brightness",
-                    "configuration": {
-                        "propertyId": "DISPLAY_BRIGHTNESS",
-                        "dataType": "int",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "left.heater",
-            "areaId": "0x31",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "temperature",
-                    "configuration": {
-                        "propertyId": "HVAC_TEMPERATURE_SET",
-                        "dataType": "float",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "passenger.heater",
-            "areaId": "0x04",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "temperature",
-                    "configuration": {
-                        "propertyId": "HVAC_TEMPERATURE_SET",
-                        "dataType": "float",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "passenger.reading.light",
-            "areaId": "0x04",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "READING_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "passenger.window",
-            "areaId": "0x04",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "height",
-                    "configuration": {
-                        "propertyId": "WINDOW_POS",
-                        "dataType": "int",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.driver.reading.light",
-            "areaId": "0x10",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "READING_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.driver.window",
-            "areaId": "0x100",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "height",
-                    "configuration": {
-                        "propertyId": "WINDOW_POS",
-                        "dataType": "int",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.foglight",
-            "areaId": "0x01000000",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "FOG_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.passenger.reading.light",
-            "areaId": "0x40",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "READING_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.passenger.window",
-            "areaId": "0x400",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "height",
-                    "configuration": {
-                        "propertyId": "WINDOW_POS",
-                        "dataType": "int",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.reading.light",
-            "areaId": "0x75",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "READING_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "rear.windshield",
-            "areaId": "0x0002",
-            "capabilities": [
-                {
-                    "interface": "ToggleController",
-                    "instance": "defroster",
-                    "configuration": {
-                        "propertyId": "HVAC_DEFROSTER",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "right.heater",
-            "areaId": "0x44",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "temperature",
-                    "configuration": {
-                        "propertyId": "HVAC_TEMPERATURE_SET",
-                        "dataType": "float",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "secondRow.heater",
-            "areaId": "0x75",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "temperature",
-                    "configuration": {
-                        "propertyId": "HVAC_TEMPERATURE_SET",
-                        "dataType": "float",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "secondRow.reading.light",
-            "areaId": "0x75",
-            "capabilities": [
-                {
-                    "interface": "PowerController",
-                    "configuration": {
-                        "propertyId": "READING_LIGHTS_SWITCH",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "steeringWheel",
-            "areaId": "0x01000000",
-            "capabilities": [
-                {
-                    "interface": "ToggleController",
-                    "instance": "heater",
-                    "configuration": {
-                        "propertyId": "HVAC_STEERING_WHEEL_HEAT",
-                        "dataType": "boolean",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "sunroof",
-            "areaId": "0x10000",
-            "capabilities": [
-                {
-                    "interface": "RangeController",
-                    "instance": "sunroof.position",
-                    "configuration": {
-                        "propertyId": "WINDOW_POS",
-                        "dataType": "int",
-                        "supportedModes": []
-                    }
-                }
-            ]
-        },
-        {
-            "endpointId": "gasdoor",
-            "areaId": "0x01000000",
-            "capabilities": [
-                {
-                    "interface": "ModeController",
-                    "instance": "position",
-                    "configuration": {
-                        "supportedModes": [
-                            {
-                                "value": "OPEN",
-                                "settings": [
-                                    {
-                                        "propertyId": "FUEL_DOOR_OPEN",
-                                        "dataType": "boolean",
-                                        "value": "true"
-                                    }
-                                ]
-                            },
-                            {
-                                "value": "CLOSED",
-                                "settings": [
-                                    {
-                                        "propertyId": "FUEL_DOOR_OPEN",
-                                        "dataType": "boolean",
-                                        "value": "false"
-                                    }
-                                ]
-                            }
-                        ]
-                    }
-                }
-            ]
-        }
-    ]
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/AACSCarControlReceiver.java b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/AACSCarControlReceiver.java
deleted file mode 100644
index 5ee52e844..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/AACSCarControlReceiver.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.aacscarcontrol;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.util.Log;
-import android.util.NoSuchPropertyException;
-
-import com.amazon.aacsconstants.Action;
-import com.amazon.aacsconstants.Topic;
-import com.amazon.aacsipc.AACSSender;
-import com.amazon.alexa.auto.aacs.common.AACSMessage;
-import com.amazon.alexa.auto.aacs.common.AACSMessageBuilder;
-import com.amazon.alexa.auto.aacs.common.AACSMessageSender;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.lang.ref.WeakReference;
-import java.util.Optional;
-
-public class AACSCarControlReceiver extends BroadcastReceiver {
-    private static final String TAG = AACSCarControlReceiver.class.getCanonicalName();
-    private static AACSMessageSender mAACSMessageSender;
-    private static Context mContext;
-    private static CarControlHandler mCarControlHandler;
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (intent.hasFileDescriptors()) {
-            Uri fileUri = intent.getData();
-            CarControlUtil.copyExternalFileToCarControl(context, fileUri);
-            return;
-        }
-
-        Optional messageOptional = AACSMessageBuilder.parseEmbeddedIntent(intent);
-        if (messageOptional.isPresent()) {
-            mContext = context;
-            mAACSMessageSender = new AACSMessageSender(new WeakReference<>(context), new AACSSender());
-            final PendingResult result = goAsync();
-            Task asyncTask = new Task(result, intent);
-            asyncTask.execute();
-        } else {
-            Log.e(TAG, "AACS Car Control Intent Message cannot be parsed");
-        }
-    }
-
-    /**
-     * This method parses the CarControl.SetControllerValue message payload, extracts the endpointId, the
-     * controllerType (as known as capability), the controllerId (as known as instance), the new value and notifies
-     * the {@link CarControlHandler} to set the setting of the controller accordingly. Note that there is no
-     * controllerId present in the payload if the controllerType is "POWER"
-     *
-     * @param context
-     * @param payload
-     * @param messageId
-     *
-     * Capability - ControllerType
-     * Instance - ControllerId
-     */
-    private static void setControllerValue(Context context, String payload, String messageId) {
-        if (mCarControlHandler == null) {
-            mCarControlHandler = new CarControlHandler(context);
-        }
-        JSONObject reply = new JSONObject();
-        boolean isSuccessful = false;
-        String endpointId = "";
-        String capability = "";
-        String instance = "";
-        String value = "";
-        boolean turnOn = false;
-        try {
-            JSONObject payloadJSON = new JSONObject(payload);
-            endpointId = payloadJSON.getString(CarControlConstants.ENDPOINT_ID);
-            capability = payloadJSON.getString(CarControlConstants.CONTROLLER_TYPE);
-
-            if (payloadJSON.has(CarControlConstants.CONTROLLER_ID)) {
-                instance = payloadJSON.getString(CarControlConstants.CONTROLLER_ID);
-            }
-            if (payloadJSON.has(CarControlConstants.VALUE)) {
-                value = payloadJSON.getString(CarControlConstants.VALUE);
-            }
-            if (payloadJSON.has(CarControlConstants.TURNON)) {
-                turnOn = payloadJSON.getBoolean(CarControlConstants.TURNON);
-            }
-
-            switch (capability) {
-                case CarControlConstants.POWER:
-                    isSuccessful = mCarControlHandler.changePowerController(endpointId, turnOn);
-                    break;
-                case CarControlConstants.MODE:
-                    isSuccessful = mCarControlHandler.setModeControllerValue(endpointId, instance, value);
-                    break;
-                case CarControlConstants.RANGE:
-                    isSuccessful =
-                            mCarControlHandler.setRangeControllerValue(endpointId, instance, Double.parseDouble(value));
-                    break;
-                case CarControlConstants.TOGGLE:
-                    isSuccessful = mCarControlHandler.changeToggleController(endpointId, instance, turnOn);
-                    break;
-                default:
-                    Log.e(TAG, "Unsupported ControllerType/Capability caught in setControllerValue: " + capability);
-                    break;
-            }
-        } catch (JSONException e) {
-            Log.e(TAG, String.format("Error occurred when parsing Car Control message payload JSON: %s", payload));
-        } catch (NoSuchPropertyException e) {
-            Log.i(TAG, "Controller endpoint property not found, ignoring reply. Error: " + e.getMessage());
-            return;
-        } catch (RuntimeException e) {
-            Log.e(TAG, String.format("Unable to perform set value for %s, %s due to %s", endpointId, instance, e));
-        }
-
-        try {
-            reply.put("success", isSuccessful);
-        } catch (JSONException e) {
-            Log.e(TAG, "Error creating Car Control reply message payload JSON " + e);
-            return;
-        }
-
-        mAACSMessageSender.sendReplyMessage(
-                messageId, Topic.CAR_CONTROL, Action.CarControl.SET_CONTROLLER_VALUE, reply.toString());
-    }
-
-    /**
-     * This method parses the CarControl.AdjustControllerValue message payload, extracts the endpointId, the
-     * controllerType (as known as capability), the controllerId (as known as instance), the new value and
-     * notifies the {@link CarControlHandler} to adjust the setting of the controller accordingly. Note that
-     * there is no controllerId present in the payload if the controllerType is "POWER".
-     *
-     * @param context
-     * @param payload
-     * @param messageId
-     *
-     * Capability - ControllerType
-     * Instance - ControllerId
-     */
-    private static void adjustControllerValue(Context context, String payload, String messageId) {
-        // Initialize Car Control Handler for making call to AAOS Car API
-        if (mCarControlHandler == null) {
-            mCarControlHandler = new CarControlHandler(context);
-        }
-        boolean isSuccessful = false;
-        String endpointId = "";
-        String capability = "";
-        String instance = "";
-        String delta = "";
-        try {
-            JSONObject payloadJSON = new JSONObject(payload);
-            endpointId = payloadJSON.getString(CarControlConstants.ENDPOINT_ID);
-            capability = payloadJSON.getString(CarControlConstants.CONTROLLER_TYPE);
-            if (payloadJSON.has(CarControlConstants.CONTROLLER_ID)) {
-                instance = payloadJSON.getString(CarControlConstants.CONTROLLER_ID);
-            }
-            if (payloadJSON.has(CarControlConstants.DELTA)) {
-                delta = payloadJSON.getString(CarControlConstants.DELTA);
-            }
-        } catch (JSONException e) {
-            Log.e(TAG, String.format("Error occurred when parsing Car Control message payload JSON: %s", payload));
-        }
-
-        try {
-            switch (capability) {
-                case CarControlConstants.MODE:
-                    isSuccessful =
-                            mCarControlHandler.adjustModeControllerValue(endpointId, instance, Integer.parseInt(delta));
-                    break;
-                case CarControlConstants.RANGE:
-                    isSuccessful = mCarControlHandler.adjustRangeControllerValue(
-                            endpointId, instance, Double.parseDouble(delta));
-                    break;
-                default:
-                    Log.e(TAG, "Unsupported ControllerType/Capability caught in adjustControllerValue: " + capability);
-                    break;
-            }
-        } catch (NoSuchPropertyException e) {
-            Log.i(TAG, "Controller endpoint property not found, ignoring reply. Error: " + e.getMessage());
-            return;
-        } catch (RuntimeException e) {
-            Log.e(TAG, String.format("Unable to perform adjust value for %s, %s due to %s", endpointId, instance, e));
-        }
-
-        JSONObject reply = new JSONObject();
-        try {
-            reply.put("success", isSuccessful);
-        } catch (JSONException e) {
-            Log.e(TAG, "Error creating Car Control reply message payload JSON: " + e);
-            return;
-        }
-
-        mAACSMessageSender.sendReplyMessage(
-                messageId, Topic.CAR_CONTROL, Action.CarControl.ADJUST_CONTROLLER_VALUE, reply.toString());
-    }
-
-    private static class Task extends AsyncTask {
-        private final PendingResult pendingResult;
-        private final Intent intent;
-
-        private Task(PendingResult pendingResult, Intent intent) {
-            this.pendingResult = pendingResult;
-            this.intent = intent;
-        }
-
-        @Override
-        protected String doInBackground(String... strings) {
-            Optional messageOptional = AACSMessageBuilder.parseEmbeddedIntent(intent);
-            AACSMessage message = messageOptional.get();
-            if (Topic.CAR_CONTROL.equals(message.topic)) {
-                switch (message.action) {
-                    case Action.CarControl.SET_CONTROLLER_VALUE:
-                        setControllerValue(mContext, message.payload, message.messageId);
-                        break;
-                    case Action.CarControl.ADJUST_CONTROLLER_VALUE:
-                        adjustControllerValue(mContext, message.payload, message.messageId);
-                        break;
-                }
-            }
-            StringBuilder sb = new StringBuilder();
-            sb.append("Action: " + intent.getAction() + "\n");
-            String log = sb.toString();
-            Log.d(TAG, log);
-            return log;
-        }
-
-        @Override
-        protected void onPostExecute(String s) {
-            super.onPostExecute(s);
-            pendingResult.finish();
-        }
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlConstants.java b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlConstants.java
deleted file mode 100644
index f41bcb791..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlConstants.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.aacscarcontrol;
-
-public class CarControlConstants {
-    public static final String AACS_CARCONTROL = "AACSCarControl";
-    public static final String AACS_CC_ConfigMapping = "CarControlEndpointMapping.json";
-    public static final String ENDPOINT_ID = "endpointId";
-    public static final String CAPABILITIES = "capabilities";
-    public static final String CONFIGURATION = "configuration";
-    public static final String SUPPORTED_MODE = "supportedModes";
-    public static final String INTERFACE = "interface";
-    public static final String INSTANCE = "instance";
-    public static final String DATA_TYPE = "dataType";
-    public static final String AREA_ID = "areaId";
-    public static final int AREA_GLOBAL = 0x0;
-    public static final String PROPERTY_ID = "propertyId";
-    public static final String POWER_CONTROLLER = "PowerController";
-    public static final String RANGE_CONTROLLER = "RangeController";
-    public static final String TOGGLE_CONTROLLER = "ToggleController";
-    public static final String MODE_CONTROLLER = "ModeController";
-    public static final String POWER = "POWER";
-    public static final String TOGGLE = "TOGGLE";
-    public static final String RANGE = "RANGE";
-    public static final String MODE = "MODE";
-    public static final String CONTROLLER_TYPE = "controllerType";
-    public static final String CONTROLLER_ID = "controllerId";
-    public static final String VALUE = "value";
-    public static final String MODE_SETTINGS = "settings";
-    public static final String DELTA = "delta";
-    public static final String TURNON = "turnOn";
-    public static final int CELSIUS_UNIT = 48;
-    public static final int FAHRENHEIT_UNIT = 49;
-
-    public enum DataType { INT, BOOLEAN, FLOAT, UNKNOWN }
-    ;
-}
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlHandler.java b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlHandler.java
deleted file mode 100644
index dbe199d2b..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlHandler.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.aacscarcontrol;
-
-import android.car.Car;
-import android.car.VehiclePropertyIds;
-import android.car.hardware.property.CarPropertyManager;
-import android.content.Context;
-import android.util.Log;
-import android.util.NoSuchPropertyException;
-
-import com.amazon.aacsconstants.AACSConstants;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-
-import java.util.List;
-
-public class CarControlHandler {
-    private static final String TAG = AACSConstants.AACS + "-" + CarControlHandler.class.getCanonicalName();
-    private Context mContext;
-    private CarPropertyManager mCarManager;
-    private CarControlHelper mHelper;
-
-    public CarControlHandler(Context context) {
-        mContext = context;
-        Car car = Car.createCar(context);
-        if (car == null) {
-            Log.e(TAG, "Car Service is not available, Car object is null");
-            mCarManager = null;
-        } else {
-            mCarManager = (CarPropertyManager) car.getCarManager(Car.PROPERTY_SERVICE);
-            if (mHelper == null) {
-                mHelper = new CarControlHelper(context);
-            }
-        }
-    }
-
-    CarControlHandler(Context context, CarPropertyManager carPropertyManager, CarControlHelper helper) {
-        mContext = context;
-        mCarManager = carPropertyManager;
-        mHelper = helper;
-    }
-
-    public boolean changePowerController(String endpointId, boolean turnOn) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return false;
-        }
-        CarControlHelper.PropertySetting setting =
-                mHelper.getPropertySetting(endpointId, CarControlConstants.POWER_CONTROLLER, "");
-        validateSetting(setting, endpointId, "");
-        try {
-            mCarManager.setBooleanProperty(setting.propertyId, setting.areaId, turnOn);
-            Log.d(TAG,
-                    String.format("Turn Power Controller for PropertyID: %s at AreaID: %s to %s", setting.propertyId,
-                            setting.areaId, turnOn));
-            return true;
-        } catch (SecurityException | IllegalArgumentException e) {
-            Log.e(TAG, String.format("Error when change Power controller %s with exception %s", endpointId, e));
-            return false;
-        }
-    }
-
-    public boolean isPowerControllerOn(String endpointId) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return false;
-        }
-        CarControlHelper.PropertySetting setting =
-                mHelper.getPropertySetting(endpointId, CarControlConstants.POWER_CONTROLLER, "");
-        validateSetting(setting, endpointId, "");
-        try {
-            return mCarManager.getBooleanProperty(setting.propertyId, setting.areaId);
-        } catch (SecurityException | IllegalArgumentException e) {
-            Log.e(TAG, String.format("Error when get Power controller value for %s with exception %s", endpointId, e));
-            return false;
-        }
-    }
-
-    public boolean changeToggleController(String endpointId, String instance, boolean turnOn) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return false;
-        }
-        CarControlHelper.PropertySetting setting =
-                mHelper.getPropertySetting(endpointId, CarControlConstants.TOGGLE_CONTROLLER, instance);
-        validateSetting(setting, endpointId, instance);
-        try {
-            switch (setting.dataType) {
-                case INT:
-                    if (turnOn) {
-                        mCarManager.setIntProperty(setting.propertyId, setting.areaId, 1);
-                    } else {
-                        mCarManager.setIntProperty(setting.propertyId, setting.areaId, 0);
-                    }
-                    Log.d(TAG,
-                            String.format("Turn Toggle Controller for PropertyID: %s at AreaID: %s to %s",
-                                    setting.propertyId, setting.areaId, turnOn));
-                    return true;
-                case BOOLEAN:
-                    mCarManager.setBooleanProperty(setting.propertyId, setting.areaId, turnOn);
-                    Log.d(TAG,
-                            String.format("Turn Toggle Controller for PropertyID: %s at AreaID: %s to %s",
-                                    setting.propertyId, setting.areaId, turnOn));
-                    return true;
-                default:
-                    Log.e(TAG, "Configuration Setting Type not correct when changeToggleController");
-                    return false;
-            }
-        } catch (SecurityException | IllegalArgumentException e) {
-            Log.e(TAG, String.format("Error when change Toggle controller %s with exception %s", endpointId, e));
-            return false;
-        }
-    }
-
-    public boolean isToggleControllerOn(String endpointId, String instance) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return false;
-        }
-        CarControlHelper.PropertySetting setting =
-                mHelper.getPropertySetting(endpointId, CarControlConstants.TOGGLE_CONTROLLER, instance);
-        validateSetting(setting, endpointId, instance);
-        try {
-            return mCarManager.getBooleanProperty(setting.propertyId, setting.areaId);
-        } catch (SecurityException | IllegalArgumentException e) {
-            Log.e(TAG,
-                    String.format("Error when change Toggle controller %s for instance %s with exception %s",
-                            endpointId, instance, e));
-            return false;
-        }
-    }
-
-    public boolean setRangeControllerValue(String endpointId, String instance, double value) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return false;
-        }
-        CarControlHelper.PropertySetting setting =
-                mHelper.getPropertySetting(endpointId, CarControlConstants.RANGE_CONTROLLER, instance);
-        validateSetting(setting, endpointId, instance);
-        try {
-            switch (setting.dataType) {
-                case INT:
-                    mCarManager.setIntProperty(setting.propertyId, setting.areaId, (int) value);
-                    Log.d(TAG,
-                            String.format("Set Range Controller for PropertyID: %s at AreaID: %s to %s",
-                                    setting.propertyId, setting.areaId, value));
-                    return true;
-                case FLOAT:
-                    if (mCarManager.getIntProperty(
-                                VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, CarControlConstants.AREA_GLOBAL)
-                            == CarControlConstants.CELSIUS_UNIT) {
-                        mCarManager.setFloatProperty(setting.propertyId, setting.areaId, (float) value);
-                    } else if (mCarManager.getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS,
-                                       CarControlConstants.AREA_GLOBAL)
-                            == CarControlConstants.FAHRENHEIT_UNIT) {
-                        // Need to do conversion here since Android internally uses Celsius
-                        mCarManager.setFloatProperty(
-                                setting.propertyId, setting.areaId, CarControlUtil.celcius((float) value));
-                    }
-                    Log.d(TAG,
-                            String.format("Set Range Controller for PropertyID: %s at AreaID: %s to %f",
-                                    setting.propertyId, setting.areaId, value));
-                    return true;
-                default:
-                    Log.e(TAG, "Configuration Setting Type not correct when setRangeControllerValue");
-                    return false;
-            }
-        } catch (SecurityException | IllegalArgumentException e) {
-            Log.e(TAG, String.format("Error set Range controller %s value %s with exception %s", endpointId, value, e));
-            return false;
-        }
-    }
-
-    public boolean adjustRangeControllerValue(String endpointId, String instance, double delta) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return false;
-        }
-        double currentRangeControllerValue = getRangeControllerValue(endpointId, instance);
-        if (currentRangeControllerValue < 0.0) {
-            Log.e(TAG, "Invalid Current Range Value");
-            return false;
-        }
-        CarControlHelper.PropertySetting setting =
-                mHelper.getPropertySetting(endpointId, CarControlConstants.RANGE_CONTROLLER, instance);
-        validateSetting(setting, endpointId, instance);
-        try {
-            switch (setting.dataType) {
-                case INT:
-                    mCarManager.setIntProperty(
-                            setting.propertyId, setting.areaId, (int) (currentRangeControllerValue + delta));
-                    Log.d(TAG,
-                            String.format("Adjust Range Controller for PropertyID: %s at AreaID: %s by %s",
-                                    setting.propertyId, setting.areaId, delta));
-                    return true;
-                case FLOAT:
-                    if (mCarManager.getIntProperty(
-                                VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, CarControlConstants.AREA_GLOBAL)
-                            == CarControlConstants.CELSIUS_UNIT) {
-                        mCarManager.setFloatProperty(setting.propertyId, setting.areaId,
-                                ((float) currentRangeControllerValue + (float) delta));
-                    } else if (mCarManager.getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS,
-                                       CarControlConstants.AREA_GLOBAL)
-                            == CarControlConstants.FAHRENHEIT_UNIT) {
-                        // Need to do conversion here since Android internally uses Celsius
-                        mCarManager.setFloatProperty(setting.propertyId, setting.areaId,
-                                CarControlUtil.celcius(CarControlUtil.fahrenheit((float) currentRangeControllerValue)
-                                        + (float) delta));
-                    }
-                    Log.d(TAG,
-                            String.format("Adjust Range Controller for PropertyID: %s at AreaID: %s by %s",
-                                    setting.propertyId, setting.areaId, delta));
-                    return true;
-                default:
-                    Log.e(TAG, "Configuration Setting Type not correct when adjustRangeControllerValue");
-                    return false;
-            }
-        } catch (SecurityException | IllegalArgumentException e) {
-            Log.e(TAG,
-                    String.format(
-                            "Error when adjust Range controller %s by %f with exception %s", endpointId, delta, e));
-            return false;
-        }
-    }
-
-    public double getRangeControllerValue(String endpointId, String instance) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return -1.0;
-        }
-        CarControlHelper.PropertySetting setting =
-                mHelper.getPropertySetting(endpointId, CarControlConstants.RANGE_CONTROLLER, instance);
-        if (setting == null) {
-            Log.e(TAG,
-                    String.format("Property setting combination %s, %s cannot be found from Car Control configuration",
-                            endpointId, instance));
-            return -1.0;
-        }
-        try {
-            switch (setting.dataType) {
-                case INT:
-                    return (double) mCarManager.getIntProperty(setting.propertyId, setting.areaId);
-                case FLOAT:
-                    return (double) mCarManager.getFloatProperty(setting.propertyId, setting.areaId);
-                default:
-                    Log.e(TAG, "Configuration Setting Type not correct when getRangeControllerValue");
-                    return -1.0;
-            }
-        } catch (SecurityException | IllegalArgumentException e) {
-            Log.e(TAG,
-                    String.format("Error when getting value for Range controller %s with exception %s", endpointId, e));
-            return -1.0;
-        }
-    }
-
-    public boolean setModeControllerValue(String endpointId, String instance, String value) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return false;
-        }
-        List settings =
-                mHelper.getPropertySettings(endpointId, CarControlConstants.MODE_CONTROLLER, instance, value);
-        validateSetting(settings, endpointId, instance, value);
-        try {
-            for (CarControlHelper.PropertySetting setting : settings) {
-                switch (setting.dataType) {
-                    case INT:
-                        mCarManager.setIntProperty(setting.propertyId, setting.areaId, Integer.parseInt(setting.value));
-                        Log.d(TAG,
-                                String.format("Set Mode Controller for PropertyID: %s at AreaID: %s to %s",
-                                        setting.propertyId, setting.areaId, setting.value));
-                        continue;
-                    case BOOLEAN:
-                        mCarManager.setBooleanProperty(
-                                setting.propertyId, setting.areaId, Boolean.parseBoolean(setting.value));
-                        Log.d(TAG,
-                                String.format("Set Mode Controller for PropertyID: %s at AreaID: %s to %s",
-                                        setting.propertyId, setting.areaId, setting.value));
-                        continue;
-                    case FLOAT:
-                        if (mCarManager.getIntProperty(
-                                    VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, CarControlConstants.AREA_GLOBAL)
-                                == CarControlConstants.CELSIUS_UNIT) {
-                            mCarManager.setFloatProperty(
-                                    setting.propertyId, setting.areaId, Float.parseFloat(setting.value));
-                        } else if (mCarManager.getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS,
-                                           CarControlConstants.AREA_GLOBAL)
-                                == CarControlConstants.FAHRENHEIT_UNIT) {
-                            // Need to do conversion here since Android internally uses Celsius
-                            mCarManager.setFloatProperty(setting.propertyId, setting.areaId,
-                                    CarControlUtil.celcius(Float.parseFloat(setting.value)));
-                        }
-                        Log.d(TAG,
-                                String.format("Set Mode Controller for PropertyID: %s at AreaID: %s to %s",
-                                        setting.propertyId, setting.areaId, setting.value));
-                        continue;
-                    default:
-                        Log.e(TAG, "Configuration Setting Type not correct when setModeControllerValue");
-                        return false;
-                }
-            }
-        } catch (SecurityException | IllegalArgumentException e) {
-            Log.e(TAG,
-                    String.format(
-                            "Error when set mode controller %s value %s with exception %s", endpointId, value, e));
-            return false;
-        }
-        mHelper.saveModeSettings(endpointId, instance, value);
-        return true;
-    }
-
-    public boolean adjustModeControllerValue(String endpointId, String instance, int delta) {
-        if (mCarManager == null) {
-            Log.e(TAG, "Car Property Manager is null");
-            return false;
-        }
-        String curMode = getModeControllerValue(endpointId, instance);
-        if (curMode.isEmpty()) {
-            Log.e(TAG, "current ModeController mode value is empty");
-            return false;
-        }
-        JSONArray supportedModes = mHelper.getSupportedMode(endpointId, CarControlConstants.MODE_CONTROLLER, instance);
-        try {
-            for (int i = 0; i < supportedModes.length(); i++) {
-                if (supportedModes.getJSONObject(i).getString(CarControlConstants.VALUE).equals(curMode)) {
-                    if (i + delta > supportedModes.length() - 1) {
-                        setModeControllerValue(endpointId, instance,
-                                supportedModes.getJSONObject(supportedModes.length() - 1)
-                                        .getString(CarControlConstants.VALUE));
-                        break;
-                    } else if (i + delta < 0) {
-                        setModeControllerValue(endpointId, instance,
-                                supportedModes.getJSONObject(0).getString(CarControlConstants.VALUE));
-                        break;
-                    } else {
-                        setModeControllerValue(endpointId, instance,
-                                supportedModes.getJSONObject(i + delta).getString(CarControlConstants.VALUE));
-                        break;
-                    }
-                }
-            }
-        } catch (SecurityException | JSONException e) {
-            Log.e(TAG,
-                    String.format(
-                            "Error when adjust mode controller %s by %d with exception %s", endpointId, delta, e));
-            return false;
-        }
-        return true;
-    }
-
-    public String getModeControllerValue(String endpointId, String instance) {
-        String value = mHelper.getModeSettings(endpointId, instance);
-        if (value.isEmpty()) {
-            Log.e(TAG, endpointId + " has not set to any value for " + instance);
-        }
-        return value;
-    }
-
-    private void validateSetting(CarControlHelper.PropertySetting setting, String endpointId, String instance) {
-        if (setting == null) {
-            String errorMsg = String.format("Property setting %s cannot be found from Car Control configuration. instance: %s", endpointId, instance);
-            Log.w(TAG, errorMsg);
-            throw new NoSuchPropertyException(errorMsg);
-        }
-    }
-
-    private void validateSetting(List settings, String endpointId, String instance, String value){
-        if (settings == null || settings.size() == 0) {
-            String errorMsg = String.format("Property setting %s cannot be found from Car Control configuration. instance: %s value: %s", endpointId, instance, value);
-            Log.w(TAG, errorMsg);
-            throw new NoSuchPropertyException(errorMsg);
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlHelper.java b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlHelper.java
deleted file mode 100644
index f2682effa..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlHelper.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.aacscarcontrol;
-
-import android.car.VehiclePropertyIds;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Log;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-public class CarControlHelper {
-    public static final String TAG = CarControlHelper.class.getCanonicalName();
-    private static final String AACS_CC_CAPABILITY_MAPPING_URI =
-            "com.amazon.aacscarcontrolmapping.CarControlHelper.capability";
-    private static final String AACS_CC_AREA_MAPPING_URI = "com.amazon.aacscarcontrolmapping.CarControlHelper.area";
-    private static final String AACS_CC_MODE_MAPPING_URI = "com.amazon.aacscarcontrolmapping.CarControlHelper.mode";
-    private static final String AACS_CC_MAPPING = "aacs-cc-mapping";
-    private Context mContext;
-    private SharedPreferences mCapabilityPref;
-    private SharedPreferences mAreaPref;
-    private SharedPreferences mModePref;
-
-    public CarControlHelper(Context context) {
-        mContext = context;
-        mCapabilityPref = mContext.getSharedPreferences(AACS_CC_CAPABILITY_MAPPING_URI, mContext.MODE_PRIVATE);
-        mAreaPref = mContext.getSharedPreferences(AACS_CC_AREA_MAPPING_URI, mContext.MODE_PRIVATE);
-        mModePref = mContext.getSharedPreferences(AACS_CC_MODE_MAPPING_URI, mContext.MODE_PRIVATE);
-        File customConfigFile = context.getFileStreamPath(CarControlConstants.AACS_CC_ConfigMapping);
-
-        if (mCapabilityPref.getBoolean(AACS_CC_MAPPING, false) && mAreaPref.getBoolean(AACS_CC_MAPPING, false)) {
-            Log.i(TAG, "Car Control Mapping Previously Exists in SharedPreference");
-        } else {
-            try {
-                JSONObject carControlJSON;
-                if (customConfigFile.exists()) {
-                    carControlJSON = CarControlUtil.readConfig(new FileInputStream(customConfigFile));
-                    Log.i(TAG, "Custom endpoint mapping created");
-                } else {
-                    carControlJSON = CarControlUtil.readConfig(
-                            mContext.getAssets().open(CarControlConstants.AACS_CC_ConfigMapping));
-                    Log.i(TAG, "Default endpoint mapping created");
-                }
-
-                SharedPreferences.Editor capabilityMapping =
-                        mContext.getSharedPreferences(AACS_CC_CAPABILITY_MAPPING_URI, mContext.MODE_PRIVATE).edit();
-                SharedPreferences.Editor areaMapping =
-                        mContext.getSharedPreferences(AACS_CC_AREA_MAPPING_URI, mContext.MODE_PRIVATE).edit();
-                if (carControlJSON.has(CarControlConstants.AACS_CARCONTROL)) {
-                    JSONArray ccMap = carControlJSON.getJSONArray(CarControlConstants.AACS_CARCONTROL);
-                    for (int i = 0; i < ccMap.length(); i++) {
-                        capabilityMapping
-                                .putString(ccMap.getJSONObject(i).getString(CarControlConstants.ENDPOINT_ID),
-                                        ccMap.getJSONObject(i)
-                                                .getJSONArray(CarControlConstants.CAPABILITIES)
-                                                .toString())
-                                .apply();
-                        areaMapping
-                                .putString(ccMap.getJSONObject(i).getString(CarControlConstants.ENDPOINT_ID),
-                                        ccMap.getJSONObject(i).getString(CarControlConstants.AREA_ID))
-                                .apply();
-                    }
-                    // Flag storing mapping to SharedPreference is finished
-                    capabilityMapping.putBoolean(AACS_CC_MAPPING, true).apply();
-                    areaMapping.putBoolean(AACS_CC_MAPPING, true).apply();
-                }
-            } catch (Exception e) {
-                Log.e(TAG, "Error open Car Control mapping asset file " + e);
-            }
-        }
-    }
-
-    /**
-     * This method retrieves Android PropertyID, AreaID and Property DataType information from SharedPreference
-     * and assemble into PropertySetting object then return to {@link CarControlHandler} to be used by Set/Adjust
-     * Controller methods for POWER, TOGGLE and RANGE controller.
-     * Note that there is no controllerId present in the payload if the controllerType is "POWER".
-     *
-     * @param endpointId
-     * @param capability
-     * @param instance
-     *
-     * Capability - ControllerType
-     * Instance - ControllerId
-     */
-    protected PropertySetting getPropertySetting(String endpointId, String capability, String instance) {
-        PropertySetting propertySetting = null;
-        if (mCapabilityPref.getBoolean(AACS_CC_MAPPING, false)) {
-            try {
-                JSONArray capabilitiesArray = new JSONArray(mCapabilityPref.getString(endpointId, ""));
-                for (int i = 0; i < capabilitiesArray.length(); i++) {
-                    if (capability.equals(capabilitiesArray.getJSONObject(i).getString(CarControlConstants.INTERFACE))
-                            && (!capabilitiesArray.getJSONObject(i).has(CarControlConstants.INSTANCE)
-                                    || instance.equals(capabilitiesArray.getJSONObject(i).getString(
-                                            CarControlConstants.INSTANCE)))) {
-                        int areaId = getAreaId(endpointId);
-                        if (capabilitiesArray.getJSONObject(i)
-                                        .getJSONObject(CarControlConstants.CONFIGURATION)
-                                        .has(CarControlConstants.AREA_ID)) {
-                            areaId = Integer.decode(capabilitiesArray.getJSONObject(i)
-                                                            .getJSONObject(CarControlConstants.CONFIGURATION)
-                                                            .getString(CarControlConstants.AREA_ID));
-                        }
-                        int propertyId = (int) VehiclePropertyIds.class
-                                                 .getField(capabilitiesArray.getJSONObject(i)
-                                                                   .getJSONObject(CarControlConstants.CONFIGURATION)
-                                                                   .getString(CarControlConstants.PROPERTY_ID))
-                                                 .get(null);
-                        CarControlConstants.DataType dataType =
-                                CarControlUtil.getDataType(capabilitiesArray.getJSONObject(i)
-                                                                   .getJSONObject(CarControlConstants.CONFIGURATION)
-                                                                   .getString(CarControlConstants.DATA_TYPE));
-                        propertySetting = new PropertySetting(propertyId, areaId, dataType, "");
-                    }
-                }
-            } catch (JSONException | NoSuchFieldException | IllegalAccessException e) {
-                Log.e(TAG, "Could not find Property Setting from AACS CarControl Config " + e);
-            }
-        }
-        return propertySetting;
-    }
-
-    /**
-     * This method retrieves Android PropertyID, AreaID, Property DataType and Setting Value information from
-     * SharedPreference and assemble into PropertySetting list then return to {@link CarControlHandler} to be
-     * used by Set/Adjust Controller methods for MODE controller.
-     *
-     * @param endpointId
-     * @param capability
-     * @param instance
-     * @param value
-     *
-     * Capability - ControllerType
-     * Instance - ControllerId
-     */
-    protected List getPropertySettings(
-            String endpointId, String capability, String instance, String value) {
-        List propertySettings = new ArrayList<>();
-        if (mCapabilityPref.getBoolean(AACS_CC_MAPPING, false)) {
-            try {
-                JSONArray supportedModes = getSupportedMode(endpointId, capability, instance);
-                for (int i = 0; i < supportedModes.length(); i++) {
-                    if (value.equals(supportedModes.getJSONObject(i).getString(CarControlConstants.VALUE))) {
-                        JSONArray propertySettingsJson =
-                                supportedModes.getJSONObject(i).getJSONArray(CarControlConstants.MODE_SETTINGS);
-                        for (int j = 0; j < propertySettingsJson.length(); j++) {
-                            int propertyId = (int) VehiclePropertyIds.class
-                                                     .getField(propertySettingsJson.getJSONObject(j).getString(
-                                                             CarControlConstants.PROPERTY_ID))
-                                                     .get(null);
-                            int areaId = getAreaId(endpointId);
-                            if (propertySettingsJson.getJSONObject(j).has(CarControlConstants.AREA_ID)) {
-                                areaId = Integer.decode(
-                                        propertySettingsJson.getJSONObject(j).getString(CarControlConstants.AREA_ID));
-                            }
-                            CarControlConstants.DataType dataType = CarControlUtil.getDataType(
-                                    propertySettingsJson.getJSONObject(j).getString(CarControlConstants.DATA_TYPE));
-                            String setValue =
-                                    propertySettingsJson.getJSONObject(j).getString(CarControlConstants.VALUE);
-                            propertySettings.add(new PropertySetting(propertyId, areaId, dataType, setValue));
-                        }
-                    }
-                }
-            } catch (JSONException | NoSuchFieldException | IllegalAccessException e) {
-                Log.e(TAG, "Could not find Property Settings for Mode Controller from AACS CarControl Config " + e);
-            }
-        }
-        return propertySettings;
-    }
-
-    protected JSONArray getSupportedMode(String endpointId, String capability, String instance) {
-        if (mCapabilityPref.getBoolean(AACS_CC_MAPPING, false)) {
-            try {
-                JSONArray capabilitiesArray = new JSONArray(mCapabilityPref.getString(endpointId, ""));
-                for (int i = 0; i < capabilitiesArray.length(); i++) {
-                    if (capability.equals(capabilitiesArray.getJSONObject(i).getString(CarControlConstants.INTERFACE))
-                            && instance.equals(
-                                    capabilitiesArray.getJSONObject(i).getString(CarControlConstants.INSTANCE))) {
-                        return capabilitiesArray.getJSONObject(i)
-                                .getJSONObject(CarControlConstants.CONFIGURATION)
-                                .getJSONArray(CarControlConstants.SUPPORTED_MODE);
-                    }
-                }
-            } catch (JSONException e) {
-                Log.e(TAG, "Could not find PropertyID from AACS CarControl Config " + e);
-            }
-        }
-        return new JSONArray();
-    }
-
-    protected void saveModeSettings(String endpointId, String instance, String value) {
-        String key = endpointId + "|" + instance;
-        SharedPreferences.Editor modeSettingMapping =
-                mContext.getSharedPreferences(AACS_CC_MODE_MAPPING_URI, mContext.MODE_PRIVATE).edit();
-        if (mModePref.contains(key)) {
-            modeSettingMapping.remove(key);
-        }
-        modeSettingMapping.putString(key, value).apply();
-    }
-
-    protected String getModeSettings(String endpointId, String instance) {
-        String key = endpointId + "|" + instance;
-        if (mModePref.contains(key)) {
-            return mModePref.getString(key, "");
-        }
-        return "";
-    }
-
-    protected int getAreaId(String endpointId) {
-        if (mAreaPref.getBoolean(AACS_CC_MAPPING, false) && mAreaPref.contains(endpointId)) {
-            int areaId = Integer.decode(mAreaPref.getString(endpointId, ""));
-            return areaId;
-        }
-        return -1;
-    }
-
-    protected static class PropertySetting {
-        public int propertyId;
-        public int areaId;
-        public CarControlConstants.DataType dataType;
-        public String value;
-
-        public PropertySetting(int propertyId, int areaId, CarControlConstants.DataType dataType, String value) {
-            this.propertyId = propertyId;
-            this.areaId = areaId;
-            this.dataType = dataType;
-            this.value = value;
-        }
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlUtil.java b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlUtil.java
deleted file mode 100644
index b22dd161b..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/main/java/com/amazon/aacscarcontrol/CarControlUtil.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.aacscarcontrol;
-
-import android.content.Context;
-import android.net.Uri;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Objects;
-
-public class CarControlUtil {
-    public static final String TAG = CarControlUtil.class.getCanonicalName();
-
-    public static CarControlConstants.DataType getDataType(String dataType) {
-        switch (dataType) {
-            case "int":
-                return CarControlConstants.DataType.INT;
-            case "boolean":
-                return CarControlConstants.DataType.BOOLEAN;
-            case "float":
-                return CarControlConstants.DataType.FLOAT;
-            default:
-                return CarControlConstants.DataType.UNKNOWN;
-        }
-    }
-
-    public static JSONObject readConfig(InputStream source) {
-        JSONObject obj = null;
-        InputStream inputStream = source;
-
-        try {
-            byte[] buffer = new byte[inputStream.available()];
-            inputStream.read(buffer);
-            String json = new String(buffer, "UTF-8");
-            obj = new JSONObject(json);
-
-            if (inputStream != null)
-                inputStream.close();
-        } catch (JSONException | IOException e) {
-            Log.e(TAG, "Error while reading external Car Control Endpoint Configuration: " + e);
-        }
-        return obj;
-    }
-
-    public static void copyExternalFileToCarControl(@NonNull Context context, @NonNull Uri fileUri) {
-        // Create copy file in externalFiles directory
-        File externalFilesDir = new File(context.getFilesDir(), "externalFiles");
-        if (!externalFilesDir.exists())
-            externalFilesDir.mkdir();
-
-        File externalFileCopy = new File(externalFilesDir, CarControlConstants.AACS_CC_ConfigMapping);
-        if (externalFileCopy.exists())
-            externalFileCopy.delete();
-
-        if (!externalFilesDir.exists() || externalFileCopy.exists()) {
-            Log.e(TAG, "Error while setting up externalFiles directory.");
-            return;
-        }
-
-        try {
-            if (!externalFileCopy.createNewFile()) {
-                Log.e(TAG, "Failed to create new file.");
-                return;
-            }
-        } catch (IOException e) {
-            Log.e(TAG, String.format("Error while creating new file. Error: %s", e.getMessage()));
-        }
-
-        // Copy contents of file descriptor to copy file
-        try {
-            FileDescriptor fd = Objects.requireNonNull(context.getContentResolver().openFileDescriptor(fileUri, "r"))
-                                        .getFileDescriptor();
-            InputStream inputStream = new FileInputStream(fd);
-            OutputStream outputStream = new FileOutputStream(externalFileCopy);
-            byte[] buf = new byte[1024];
-            int len;
-            while ((len = inputStream.read(buf)) > 0) {
-                outputStream.write(buf, 0, len);
-            }
-        } catch (FileNotFoundException e) {
-            Log.w(TAG,
-                    String.format("File associated with URI (%s) provided not found. Error: %s", fileUri.toString(),
-                            e.getMessage()));
-        } catch (IOException e) {
-            Log.e(TAG,
-                    String.format("Error while copying files locally for URI: %s. Error: %s", fileUri.toString(),
-                            e.getMessage()));
-        } catch (SecurityException e) {
-            Log.e(TAG,
-                    String.format("AACS does not have permissions to access URI (%s). Error: %s", fileUri.toString(),
-                            e.getMessage()));
-        }
-    }
-
-    public static float celcius(float f) {
-        return (float) ((f - 32) / 1.8);
-    }
-
-    public static float fahrenheit(float f) {
-        return (float) ((f * 1.8) + 32);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/test/java/com/amazon/aacscarcontrol/CarControlHandlerTests.java b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/test/java/com/amazon/aacscarcontrol/CarControlHandlerTests.java
deleted file mode 100644
index ccfdc30ad..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/test/java/com/amazon/aacscarcontrol/CarControlHandlerTests.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.aacscarcontrol;
-
-import android.car.Car;
-import android.car.hardware.property.CarPropertyManager;
-import android.content.Context;
-import android.util.Log;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Unit tests for {@link CarControlHandler}
- */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({Car.class, Log.class})
-public class CarControlHandlerTests {
-    private final String DEFAULT_AC_ENDPOINT = "default.ac";
-    private final String DEFAULT_FAN_ENDPOINT = "default.fan";
-    private final String INVALID_DEFAULT_FAN_ENDPOINT = "default.fan1";
-    private final String CAR_ENDPOINT = "car";
-    private final String INVALID_CAR_ENDPOINT = "vehicle";
-    private final String RECIR_INSTANCE = "recirculate";
-    private final String INTENSITY_INSTANCE = "intensity";
-    private final String INVALID_INTENSITY_INSTANCE = "intense";
-    private final String SPEED_INSTANCE = "speed";
-    private final String INVALID_SPEED_INSTANCE = "speedo";
-    private final String HIGH_VALUE = "HIGH";
-    private final String SUPERHIGH_VALUE = "SUPERHIGH";
-    private final int PROPERTY_ID_HVAC_MAX_AC_ON = 354419974;
-    private final int PROPERTY_ID_HVAC_FAN_SPEED = 356517120;
-    private final int PROPERTY_ID_HVAC_TEMPERATURE_SET = 358614275;
-    private final int PROPERTY_ID_HVAC_POWER_ON = 354419984;
-    private final int PROPERTY_ID_HVAC_RECIRC_ON = 354419976;
-    private final int AREA_ID_FULL = 117;
-    private final int AREA_ID_LEFT = 49;
-    private final int AREA_ID_RIGHT = 68;
-
-    private CarControlHandler mCarControlHandler;
-    private List mModeList;
-
-    @Mock
-    private Context mMockedContext;
-
-    @Mock
-    private CarPropertyManager mMockedCarManager;
-
-    @Mock
-    private CarControlHelper mMockedHelper;
-
-    @Before
-    public void setUp() {
-        PowerMockito.mockStatic(Log.class);
-        mMockedCarManager = PowerMockito.mock(CarPropertyManager.class);
-        mMockedHelper = PowerMockito.mock(CarControlHelper.class);
-        mCarControlHandler = new CarControlHandler(mMockedContext, mMockedCarManager, mMockedHelper);
-
-        PowerMockito.doNothing()
-                .when(mMockedCarManager)
-                .setBooleanProperty(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyBoolean());
-        PowerMockito.doNothing()
-                .when(mMockedCarManager)
-                .setIntProperty(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyInt());
-        PowerMockito.doNothing()
-                .when(mMockedCarManager)
-                .setFloatProperty(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyFloat());
-
-        mModeList = new ArrayList<>();
-        mModeList.add(new CarControlHelper.PropertySetting(
-                PROPERTY_ID_HVAC_MAX_AC_ON, AREA_ID_FULL, CarControlConstants.DataType.BOOLEAN, "true"));
-        mModeList.add(new CarControlHelper.PropertySetting(
-                PROPERTY_ID_HVAC_FAN_SPEED, AREA_ID_FULL, CarControlConstants.DataType.INT, "6"));
-        mModeList.add(new CarControlHelper.PropertySetting(
-                PROPERTY_ID_HVAC_TEMPERATURE_SET, AREA_ID_LEFT, CarControlConstants.DataType.FLOAT, "60.0"));
-        mModeList.add(new CarControlHelper.PropertySetting(
-                PROPERTY_ID_HVAC_TEMPERATURE_SET, AREA_ID_RIGHT, CarControlConstants.DataType.FLOAT, "60.0"));
-    }
-
-    @Test
-    public void setPowerControllerWithValidParam() {
-        PowerMockito
-                .when(mMockedHelper.getPropertySetting(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
-                .thenReturn(new CarControlHelper.PropertySetting(
-                        PROPERTY_ID_HVAC_POWER_ON, AREA_ID_FULL, CarControlConstants.DataType.BOOLEAN, ""));
-
-        // Test Set Power Controller
-        Assert.assertTrue(mCarControlHandler.changePowerController(DEFAULT_FAN_ENDPOINT, true));
-        Mockito.verify(mMockedCarManager, Mockito.times(1))
-                .setBooleanProperty(PROPERTY_ID_HVAC_POWER_ON, AREA_ID_FULL, true);
-        Assert.assertTrue(mCarControlHandler.changePowerController(DEFAULT_FAN_ENDPOINT, false));
-        Mockito.verify(mMockedCarManager, Mockito.times(1))
-                .setBooleanProperty(PROPERTY_ID_HVAC_POWER_ON, AREA_ID_FULL, false);
-    }
-    @Test
-    public void setToggleControllerWithValidParam() {
-        PowerMockito
-                .when(mMockedHelper.getPropertySetting(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
-                .thenReturn(new CarControlHelper.PropertySetting(
-                        PROPERTY_ID_HVAC_RECIRC_ON, AREA_ID_FULL, CarControlConstants.DataType.BOOLEAN, ""));
-        // Test Set Toggle Controller
-        Assert.assertTrue(mCarControlHandler.changeToggleController(CAR_ENDPOINT, RECIR_INSTANCE, true));
-        Mockito.verify(mMockedCarManager, Mockito.times(1))
-                .setBooleanProperty(PROPERTY_ID_HVAC_RECIRC_ON, AREA_ID_FULL, true);
-        Assert.assertTrue(mCarControlHandler.changeToggleController(CAR_ENDPOINT, RECIR_INSTANCE, false));
-        Mockito.verify(mMockedCarManager, Mockito.times(1))
-                .setBooleanProperty(PROPERTY_ID_HVAC_RECIRC_ON, AREA_ID_FULL, false);
-    }
-
-    @Test
-    public void setModeControllerWithValidParam() {
-        PowerMockito
-                .when(mMockedHelper.getPropertySettings(
-                        Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
-                .thenReturn(mModeList);
-        // Test Set Mode Controller
-        Assert.assertTrue(
-                mCarControlHandler.setModeControllerValue(DEFAULT_AC_ENDPOINT, INTENSITY_INSTANCE, HIGH_VALUE));
-        Mockito.verify(mMockedCarManager, Mockito.times(1))
-                .setBooleanProperty(PROPERTY_ID_HVAC_MAX_AC_ON, AREA_ID_FULL, true);
-        Mockito.verify(mMockedCarManager, Mockito.times(1)).setIntProperty(PROPERTY_ID_HVAC_FAN_SPEED, AREA_ID_FULL, 6);
-    }
-
-    @Test
-    public void setRangeControllerWithValidParam() {
-        PowerMockito
-                .when(mMockedHelper.getPropertySetting(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
-                .thenReturn(new CarControlHelper.PropertySetting(
-                        PROPERTY_ID_HVAC_FAN_SPEED, AREA_ID_FULL, CarControlConstants.DataType.INT, ""));
-        // Test Set Range Controller
-        Assert.assertTrue(mCarControlHandler.setRangeControllerValue(DEFAULT_FAN_ENDPOINT, SPEED_INSTANCE, 3.0));
-        Mockito.verify(mMockedCarManager, Mockito.times(1)).setIntProperty(PROPERTY_ID_HVAC_FAN_SPEED, AREA_ID_FULL, 3);
-    }
-
-    public void adjustRangeControllerWithValidParam() {
-        // Test Adjust Range Controller
-        PowerMockito
-                .when(mMockedHelper.getPropertySetting(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
-                .thenReturn(new CarControlHelper.PropertySetting(
-                        PROPERTY_ID_HVAC_FAN_SPEED, AREA_ID_FULL, CarControlConstants.DataType.INT, ""));
-        Assert.assertTrue(mCarControlHandler.adjustRangeControllerValue(DEFAULT_FAN_ENDPOINT, SPEED_INSTANCE, 1.0));
-        Mockito.verify(mMockedCarManager, Mockito.times(1)).setIntProperty(PROPERTY_ID_HVAC_FAN_SPEED, AREA_ID_FULL, 4);
-        Assert.assertTrue(mCarControlHandler.adjustRangeControllerValue(DEFAULT_FAN_ENDPOINT, SPEED_INSTANCE, -1.0));
-        Mockito.verify(mMockedCarManager, Mockito.times(1)).setIntProperty(PROPERTY_ID_HVAC_FAN_SPEED, AREA_ID_FULL, 3);
-    }
-
-    @Test
-    public void setControllerWithInvalidParam() {
-        // Test Set Power Controller
-        Assert.assertFalse(mCarControlHandler.changePowerController(INVALID_DEFAULT_FAN_ENDPOINT, true));
-        Assert.assertFalse(mCarControlHandler.changePowerController(INVALID_DEFAULT_FAN_ENDPOINT, false));
-
-        // Test Set Toggle Controller
-        Assert.assertFalse(mCarControlHandler.changeToggleController(INVALID_CAR_ENDPOINT, RECIR_INSTANCE, true));
-        Assert.assertFalse(mCarControlHandler.changeToggleController(INVALID_CAR_ENDPOINT, RECIR_INSTANCE, false));
-
-        // Test Set Range Controller
-        Assert.assertFalse(
-                mCarControlHandler.setRangeControllerValue(DEFAULT_FAN_ENDPOINT, INVALID_SPEED_INSTANCE, 3.0));
-        Assert.assertFalse(
-                mCarControlHandler.setRangeControllerValue(DEFAULT_FAN_ENDPOINT, INVALID_SPEED_INSTANCE, 6.0));
-
-        // Test Set Mode Controller
-        Assert.assertFalse(
-                mCarControlHandler.setModeControllerValue(DEFAULT_AC_ENDPOINT, INTENSITY_INSTANCE, SUPERHIGH_VALUE));
-    }
-
-    @Test
-    public void adjustControllerWithInvalidParam() {
-        // Test Adjust Range Controller
-        Assert.assertFalse(
-                mCarControlHandler.adjustRangeControllerValue(DEFAULT_FAN_ENDPOINT, INVALID_SPEED_INSTANCE, 3.0));
-        Assert.assertFalse(
-                mCarControlHandler.adjustRangeControllerValue(DEFAULT_FAN_ENDPOINT, INVALID_SPEED_INSTANCE, 6.0));
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/test/java/com/amazon/aacscarcontrol/CarControlHelperTests.java b/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/test/java/com/amazon/aacscarcontrol/CarControlHelperTests.java
deleted file mode 100644
index 13ac3a833..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/aacscarcontrol/src/test/java/com/amazon/aacscarcontrol/CarControlHelperTests.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.amazon.aacscarcontrol;
-
-import android.content.Context;
-import android.os.Build;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@Config(sdk = {Build.VERSION_CODES.O_MR1})
-public class CarControlHelperTests {
-    private final String DEFAULT_AC_ENDPOINT = "default.ac";
-    private final String DEFAULT_FAN_ENDPOINT = "default.fan";
-    private final String INVALID_DEFAULT_FAN_ENDPOINT = "default.fan1";
-    private final String CAR_ENDPOINT = "car";
-    private final String INVALID_CAR_ENDPOINT = "vehicle";
-    private final String RECIR_INSTANCE = "recirculate";
-    private final String INTENSITY_INSTANCE = "intensity";
-    private final String INVALID_INTENSITY_INSTANCE = "intense";
-    private final String SPEED_INSTANCE = "speed";
-    private final String INVALID_SPEED_INSTANCE = "speedo";
-    private final String HIGH_VALUE = "HIGH";
-    private final String SUPERHIGH_VALUE = "SUPERHIGH";
-    private final int PROPERTY_ID_HVAC_MAX_AC_ON = 354419974;
-    private final int PROPERTY_ID_HVAC_FAN_SPEED = 356517120;
-    private final int PROPERTY_ID_HVAC_TEMPERATURE_SET = 358614275;
-    private final int PROPERTY_ID_HVAC_POWER_ON = 354419984;
-    private final int PROPERTY_ID_HVAC_RECIRC_ON = 354419976;
-    private final int AREA_ID_FULL = 117;
-    private final int AREA_ID_LEFT = 49;
-    private final int AREA_ID_RIGHT = 68;
-
-    Context mContext;
-    CarControlHelper mHelper;
-
-    @Before
-    public void setup() {
-        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        mHelper = new CarControlHelper(mContext);
-    }
-
-    @Test
-    public void testGetPropertySettingWithValidParam() {
-        // Power Controller Type
-        CarControlHelper.PropertySetting setting1 =
-                mHelper.getPropertySetting(DEFAULT_FAN_ENDPOINT, CarControlConstants.POWER_CONTROLLER, "");
-        Assert.assertEquals(setting1.propertyId, PROPERTY_ID_HVAC_POWER_ON);
-        Assert.assertEquals(setting1.areaId, AREA_ID_FULL);
-        Assert.assertEquals(setting1.dataType, CarControlConstants.DataType.BOOLEAN);
-
-        // Range Controller Type
-        CarControlHelper.PropertySetting setting2 =
-                mHelper.getPropertySetting(DEFAULT_FAN_ENDPOINT, CarControlConstants.RANGE_CONTROLLER, SPEED_INSTANCE);
-        Assert.assertEquals(setting2.propertyId, PROPERTY_ID_HVAC_FAN_SPEED);
-        Assert.assertEquals(setting2.areaId, AREA_ID_FULL);
-        Assert.assertEquals(setting2.dataType, CarControlConstants.DataType.INT);
-
-        // Toggle Controller Type
-        CarControlHelper.PropertySetting setting3 =
-                mHelper.getPropertySetting(CAR_ENDPOINT, CarControlConstants.TOGGLE_CONTROLLER, RECIR_INSTANCE);
-        Assert.assertEquals(setting3.propertyId, PROPERTY_ID_HVAC_RECIRC_ON);
-        Assert.assertEquals(setting3.areaId, AREA_ID_FULL);
-        Assert.assertEquals(setting3.dataType, CarControlConstants.DataType.BOOLEAN);
-    }
-
-    @Test
-    public void testGetPropertySettingsWithValidParam() {
-        // Mode Controller Type
-        List settingList = mHelper.getPropertySettings(
-                DEFAULT_AC_ENDPOINT, CarControlConstants.MODE_CONTROLLER, INTENSITY_INSTANCE, HIGH_VALUE);
-        Assert.assertEquals(settingList.get(0).propertyId, PROPERTY_ID_HVAC_MAX_AC_ON);
-        Assert.assertEquals(settingList.get(0).areaId, AREA_ID_FULL);
-        Assert.assertEquals(settingList.get(0).dataType, CarControlConstants.DataType.BOOLEAN);
-        Assert.assertEquals(settingList.get(0).value, "true");
-
-        Assert.assertEquals(settingList.get(1).propertyId, PROPERTY_ID_HVAC_FAN_SPEED);
-        Assert.assertEquals(settingList.get(1).areaId, AREA_ID_FULL);
-        Assert.assertEquals(settingList.get(1).dataType, CarControlConstants.DataType.INT);
-        Assert.assertEquals(settingList.get(1).value, "6");
-
-        Assert.assertEquals(settingList.get(2).propertyId, PROPERTY_ID_HVAC_TEMPERATURE_SET);
-        Assert.assertEquals(settingList.get(2).areaId, AREA_ID_LEFT);
-        Assert.assertEquals(settingList.get(2).dataType, CarControlConstants.DataType.FLOAT);
-        Assert.assertEquals(settingList.get(2).value, "61.0");
-
-        Assert.assertEquals(settingList.get(3).propertyId, PROPERTY_ID_HVAC_TEMPERATURE_SET);
-        Assert.assertEquals(settingList.get(3).areaId, AREA_ID_RIGHT);
-        Assert.assertEquals(settingList.get(2).dataType, CarControlConstants.DataType.FLOAT);
-        Assert.assertEquals(settingList.get(2).value, "61.0");
-    }
-
-    @Test
-    public void testGetPropertySettingWithInvalidParam() {
-        // Power Controller Type
-        Assert.assertNull(
-                mHelper.getPropertySetting(INVALID_DEFAULT_FAN_ENDPOINT, CarControlConstants.POWER_CONTROLLER, ""));
-
-        // Toggle Controller Type
-        Assert.assertNull(mHelper.getPropertySetting(
-                DEFAULT_FAN_ENDPOINT, CarControlConstants.TOGGLE_CONTROLLER, INVALID_SPEED_INSTANCE));
-
-        // Range Controller Type
-        Assert.assertNull(mHelper.getPropertySetting(
-                INVALID_CAR_ENDPOINT, CarControlConstants.RANGE_CONTROLLER, INVALID_INTENSITY_INSTANCE));
-    }
-
-    @Test
-    public void testGetPropertySettingsWithInvalidParam() {
-        // Mode Controller Type
-        List settingList = mHelper.getPropertySettings(
-                DEFAULT_AC_ENDPOINT, CarControlConstants.MODE_CONTROLLER, INTENSITY_INSTANCE, SUPERHIGH_VALUE);
-        Assert.assertEquals(settingList.size(), 0);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/build.gradle b/aacs/android/app-components/alexa-auto-carcontrol/build.gradle
deleted file mode 100644
index bac673f1e..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/build.gradle
+++ /dev/null
@@ -1,46 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
-    ext.versions = [
-            'kotlin': '1.6.21',
-            'moshi': '1.13.0',
-
-            // Test Dependencies
-            'mockito': '3.4.0',
-    ]
-
-    ext.deps = [
-            'kotlin_stdlib': "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}",
-            'junit': 'junit:junit:4.12',
-            'androidx_test_core': 'androidx.test:core:1.1.0',
-            'androidx_test_monitor': "androidx.test:monitor:1.1.1",
-            'androidx_annotation': "androidx.annotation:annotation:1.1.0",
-            'moshi': "com.squareup.moshi:moshi:${versions.moshi}",
-            'moshi_codegen': "com.squareup.moshi:moshi-kotlin-codegen:${versions.moshi}",
-            'mockito': "org.mockito:mockito-core:${versions.mockito}",
-            'roboelectric': 'org.robolectric:robolectric:4.3'
-    ]
-
-    repositories {
-        google()
-        mavenCentral()
-
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:3.6.2'
-        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
-allprojects {
-    repositories {
-        google()
-        mavenCentral()
-    }
-}
-
-task clean(type: Delete) {
-    delete rootProject.buildDir
-}
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/set-fan-speed-to-3.png b/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/set-fan-speed-to-3.png
deleted file mode 100644
index c686c56a7..000000000
Binary files a/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/set-fan-speed-to-3.png and /dev/null differ
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/set-reply-to-engine.png b/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/set-reply-to-engine.png
deleted file mode 100644
index 333bce4e3..000000000
Binary files a/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/set-reply-to-engine.png and /dev/null differ
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/src/set-fan-speed-to-3.puml b/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/src/set-fan-speed-to-3.puml
deleted file mode 100644
index d0a15ed1e..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/src/set-fan-speed-to-3.puml
+++ /dev/null
@@ -1,27 +0,0 @@
-@startuml
-
-skinparam participant {
-	BackgroundColor White
-	ArrowColor Black
-	BorderColor DarkGray
-    BackgroundColor Wheat
-}
-
-participant Driver order 20
-participant AAOSHAL <> order 30
-participant AAOSCarAPI <> order 40
-participant AACS_CarControlHandler order 50
-participant AACS_CarControlBroadcastReceiver order 60
-participant AACS_CoreService order 70
-participant AutoSDK order 80
-participant Alexa order 90
-
-Driver -> Alexa: Say "Set Fan Speed to 3"
-Alexa -> AutoSDK: Car Control (Directive)
-AutoSDK -> AACS_CoreService: SetRangeControllerValue (AASB Message)
-AACS_CoreService -> AACS_CarControlBroadcastReceiver: SetRangeControllerValue (AASB Intent)
-AACS_CarControlBroadcastReceiver -> AACS_CarControlHandler: setControllerValue(payload)
-AACS_CarControlHandler -> AAOSCarAPI: setIntProperty(HVAC_FAN_SPEED, SEAT_ROW_1_CENTER, 3)
-AAOSCarAPI -> AAOSHAL: HVAC_FAN_SPEED = (0x0500|SYSTEM|3|SEAT)
-
-@enduml
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/src/set-reply-to-engine.puml b/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/src/set-reply-to-engine.puml
deleted file mode 100644
index ef9ed6e92..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/docs/diagrams/src/set-reply-to-engine.puml
+++ /dev/null
@@ -1,23 +0,0 @@
-@startuml
-
-skinparam participant {
-	BackgroundColor White
-	ArrowColor Black
-	BorderColor DarkGray
-    BackgroundColor Wheat
-}
-
-participant AAOSHAL <> order 30
-participant AAOSCarAPI <> order 40
-participant AACS_CarControlHandler order 50
-participant AACS_CarControlBroadcastReceiver order 60
-participant AACS_CoreService order 70
-participant AutoSDK order 80
-
-AAOSHAL -> AAOSCarAPI : HVAC_FAN_SPEED = (0x0500|SYSTEM|3|SEAT)
-AAOSCarAPI -> AACS_CarControlHandler : True/Throw Exception
-AACS_CarControlHandler -> AACS_CarControlBroadcastReceiver : True/False 
-AACS_CarControlBroadcastReceiver -> AACS_CoreService : Success/Failure (Intent)
-AACS_CoreService -> AutoSDK : SetRangeControllerValue Reply (AASB Message)
-
-@enduml
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/gradle.properties b/aacs/android/app-components/alexa-auto-carcontrol/gradle.properties
deleted file mode 100644
index 199d16ede..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/gradle.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-# Project-wide Gradle settings.
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx1536m
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
-# AndroidX package structure to make it clearer which packages are bundled with the
-# Android operating system, and which are packaged with your app's APK
-# https://developer.android.com/topic/libraries/support-library/androidx-rn
-android.useAndroidX=true
-# Automatically convert third-party libraries to use AndroidX
-android.enableJetifier=true
-
diff --git a/aacs/android/app-components/alexa-auto-carcontrol/settings.gradle b/aacs/android/app-components/alexa-auto-carcontrol/settings.gradle
deleted file mode 100644
index 8a684f7b8..000000000
--- a/aacs/android/app-components/alexa-auto-carcontrol/settings.gradle
+++ /dev/null
@@ -1,9 +0,0 @@
-rootProject.name='alexa-auto-carcontrol'
-include ':aacscarcontrol'
-gradle.ext.aacsRoot = '../..'
-include ':aacsconstants'
-project(':aacsconstants').projectDir = new File(gradle.ext.aacsRoot, '/common/constants/aacsconstants')
-include ':aacsipc'
-project(':aacsipc').projectDir = new File(gradle.ext.aacsRoot, '/common/ipc/aacsipc')
-include ':aacscommonutils'
-project(':aacscommonutils').projectDir = new File(gradle.ext.aacsRoot, '/common/commonutils/aacscommonutils')
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/.gitignore b/aacs/android/app-components/alexa-auto-comms-ui/.gitignore
deleted file mode 100644
index ae66af5e5..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-.gradle/
-.idea/
-build/
-gradle/
-gradlew
-gradlew.bat
-local.properties
-.DS_Store
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/README.md b/aacs/android/app-components/alexa-auto-comms-ui/README.md
deleted file mode 100644
index 5e6aeaa27..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/README.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Alexa Auto Comms UI
-
-This library serves the following purposes:
-
-* It handles Bluetooth-related directives. 
-   When a Bluetooth device is connected or disconnected, the `BluetoothReceiver` class receives the intent with the device's connection status, MAC address, and display name. When a device is paired, the class receives the intent for a device pairing, with the device's bond state, MAC address, and display name. The `BluetoothReceiver` class calls  the `BluetoothDirectiveHandler` class to update the Bluetooth device database based on the change. 
-
-* It handles contacts upload or removal requests to Alexa.
-   This library starts the AACS Contacts Service intents to handle contacts upload or removal requests.
-
-On the Android Automotive OS, the last connected phone is considered the primary device. Only one device can upload the address book to the cloud at a time. If the primary phone changes, the old address book is removed and the new address book is scheduled to upload after 30 seconds. If you want to change this default behavior, implement your own system UI for users to select the primary phone and call the Android system API `setUserSelectedOutgoingPhoneAccount` to set the user-selected outgoing phone account. Send a `com.amazon.alexa.auto.comms.primaryPhoneChanged` intent to Alexa Auto Comms UI to inform the change of the primary phone.
-```
-ComponentName c = new ComponentName("com.amazon.alexa.auto.app", "com.amazon.alexa.auto.comms.ui.receiver.BluetoothReceiver");
-intent.setComponent(c);
-intent.addCategory("com.amazon.alexa.auto.comms");
-intent.setAction("com.amazon.alexa.auto.comms.primaryPhoneChanged");
-sendBroadcast(intent);
-```
-
-* A contacts consent screen is displayed during Alexa setup on the primary phone if the device does not have contacts upload permission. The contacts consent screen is also shown if a phone is paired after setup and does not have contacts upload permission. 
-
-* The Alexa communication settings screen displays a list of paired devices, both connected and disconnected, with contacts upload permission status. The user can enable or disable the contacts upload permission for each device. If the contacts permission for the primary phone is enabled, the contacts in that device will be uploaded. If the contacts permission for a non-primary phone is enabled, the contacts in that phone will not be uploaded until the phone is selected as the primary. The permission is retained until logout when it is reset.
-
-## Databases
-There are two databases where devices are stored:
-
-* `BTDeviceRepository` stores device information for every device that is paired. The devices are never removed from this database. 
-* `ConnectedBTDeviceRepository` stores device information for currently connected devices only. If a phone is disconnected, it will be removed and will only be found in the `BTDeviceRepository`. If a phone is disconnected and a user enables/disables contacts for the device in the communications screen, the permission is stored in the BTDeviceRepository device and the ConnectedBTDevice is updated with the BTDevice permission on the next connection. 
-
-## Prerequisites
-The following list describes the prerequisites for this library:
-
-* Telephony and Contacts libraries must be built.
-* Your Android device must meet the prerequisites for using the [Telephony library](../alexa-auto-telephony/README.md#prerequisites).
-
-## Known Issues
-* On a reboot, Android automatically connects any phone that is paired which could cause the primary phone to change and contacts sync issues.
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/build.gradle b/aacs/android/app-components/alexa-auto-comms-ui/build.gradle
deleted file mode 100644
index f35f1f3d9..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/build.gradle
+++ /dev/null
@@ -1,84 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 32
-    defaultConfig {
-        minSdkVersion 27
-        targetSdkVersion 27
-        versionCode Integer.parseInt(new Date().format("yyyyMMdd"))
-        versionName "4.2"
-        testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-        debug {
-            testCoverageEnabled true
-            debuggable true
-        }
-    }
-
-    testOptions {
-        // Unit Test: Make all android methods return true by default
-        unitTests.returnDefaultValues = true
-        unitTests.includeAndroidResources = true
-    }
-
-    compileOptions {
-        targetCompatibility 1.8
-        sourceCompatibility 1.8
-    }
-
-    libraryVariants.all { variant ->
-        variant.outputs.all {
-            def project = "alexa-auto-comms-ui"
-            def separator = "_"
-            def buildType = variant.buildType.name
-            def apkName = project + separator + buildType + ".aar"
-            outputFileName = new File(apkName)
-        }
-    }
-
-}
-
-dependencies {
-    implementation project(':aacscommonutils')
-    implementation project(':aacsconstants')
-    implementation project(':alexa-auto-apis')
-    implementation project(':alexa-auto-setup')
-    implementation project(':alexa-auto-apps-common-util')
-    implementation project(':alexa-auto-telephony')
-
-    implementation deps.androidx_appcompat
-    implementation deps.androidx_preference
-    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
-
-    // RX
-    implementation deps.rxjava3
-
-    // Dagger
-    implementation deps.dagger
-    implementation project(path: ':aacsipc')
-    annotationProcessor 'com.google.dagger:dagger-compiler:2.22'
-
-    //Eventbus
-    implementation deps.eventbus
-
-    // Database
-    implementation "androidx.room:room-runtime:2.4.2"
-    annotationProcessor "androidx.room:room-compiler:2.4.2"
-
-    // Navigation between UI components.
-    implementation deps.androidx_navigation_fragment
-    implementation deps.androidx_navigation_ui
-
-    testImplementation deps.junit
-    testImplementation deps.mockito
-    testImplementation deps.mockito_inline
-    testImplementation deps.androidx_test_core
-    testImplementation deps.androidx_arch_core_testing
-    testImplementation deps.androidx_fragment_testing
-    testImplementation deps.roboelectric
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/proguard-rules.pro b/aacs/android/app-components/alexa-auto-comms-ui/proguard-rules.pro
deleted file mode 100644
index f1b424510..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/AndroidManifest.xml b/aacs/android/app-components/alexa-auto-comms-ui/src/main/AndroidManifest.xml
deleted file mode 100644
index bc2bde2a2..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-    
-    
-    
-    
-    
-    
-    
-
-    
-        
-        
-            
-                
-
-                
-                
-                
-                
-                
-            
-            
-                
-                
-            
-        
-    
-
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/Constants.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/Constants.java
deleted file mode 100644
index 0c42500f4..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/Constants.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui;
-
-import android.bluetooth.BluetoothDevice;
-
-public class Constants {
-    // State
-    public static final String BT_CONNECTED = "CONNECTED";
-    public static final String BT_DISCONNECTED = "DISCONNECTED";
-    public static final String CONTACTS_PERMISSION_YES = "YES";
-    public static final String CONTACTS_PERMISSION_NO = "NO";
-
-    // AACS Bluetooth intents
-    public final static String AACS_BT_DEVICE_ADDRESS = "deviceAddress";
-    public final static String AACS_BT_DEVICE_NAME = "deviceName";
-    public static final String AACS_TELEPHONY_SERVICE = "com.amazon.aacstelephony";
-    public static final String AACS_BT_CONNECTED = "com.amazon.aacstelephony.bluetooth.connected";
-    public static final String AACS_BT_DISCONNECTED = "com.amazon.aacstelephony.bluetooth.disconnected";
-    public static final String AACS_BT_CONNECTION_CHECK_COMPLETED =
-            "com.amazon.aacstelephony.bluetooth.connectionCheckCompleted";
-    public static final String AACS_BT_BOND_STATE_CHANGED = "com.amazon.aacstelephony.bluetooth.bondStateChanged";
-    public static final String ACTION_PAIRED_DEVICE = "com.amazon.aacstelephony.bluetooth.pairedDevice";
-
-    // AACS Contacts intents
-    public final static String AACS_CONTACTS_SERVICE = "com.amazon.aacscontacts.AACSContactsService";
-    public static final String AACS_ACTION_UPLOAD_CONTACTS = "com.amazon.aacscontacts.upload";
-    public static final String AACS_ACTION_REMOVE_CONTACTS = "com.amazon.aacscontacts.remove";
-    public static final String AACS_EXTRA_ADDRESSBOOK_ID = "addressBookSourceId";
-    public static final String AACS_EXTRA_ADDRESSBOOK_NAME_KEY = "addressBookName";
-    public static final String AACS_EXTRA_ADDRESSBOOK_NAME_VALUE = "PhoneBook";
-
-    // Alexa Auto Comms intents
-    public final static String ALEXA_AUTO_COMMS = "com.amazon.alexa.auto.comms";
-    public final static String ALEXA_AUTO_COMMS_PRIMARY_PHONE_CHANGED =
-            "com.amazon.alexa.auto.comms.primaryPhoneChanged";
-
-    // Communication
-    public static final String COMMUNICATION_PERMISSION_ENABLED = "enabled";
-    public static final String COMMUNICATION_PERMISSION_DISABLED = "disabled";
-    public static final String COMMUNICATION_DEVICE_ADDRESS = "deviceAddress";
-
-    // Activity Constants
-    public static final String CONTACTS_ACTIVITY = RequestContactsConsentActivity.class.getSimpleName();
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/ContactsControllerImpl.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/ContactsControllerImpl.java
deleted file mode 100644
index 683b8275a..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/ContactsControllerImpl.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui;
-
-import static com.amazon.alexa.auto.comms.ui.Constants.CONTACTS_PERMISSION_NO;
-import static com.amazon.alexa.auto.comms.ui.Constants.CONTACTS_PERMISSION_YES;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
-import android.os.AsyncTask;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.amazon.aacsconstants.AACSConstants;
-import com.amazon.alexa.auto.apis.app.AlexaApp;
-import com.amazon.alexa.auto.apis.auth.AuthController;
-import com.amazon.alexa.auto.apis.communication.ContactsController;
-import com.amazon.aacstelephony.Util;
-import com.amazon.alexa.auto.comms.ui.db.BTDevice;
-import com.amazon.alexa.auto.comms.ui.db.BTDeviceRepository;
-import com.amazon.alexa.auto.comms.ui.db.ConnectedBTDevice;
-import com.amazon.alexa.auto.comms.ui.db.ConnectedBTDeviceRepository;
-
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-
-import java.lang.ref.WeakReference;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import io.reactivex.rxjava3.core.Observable;
-import io.reactivex.rxjava3.subjects.BehaviorSubject;
-
-public class ContactsControllerImpl implements ContactsController {
-    private static final String TAG = ContactsControllerImpl.class.getSimpleName();
-    private static String _AACS_CONTACTS_PACKAGE_NAME = null; // This should remain private non final
-
-    private final WeakReference mContextWk;
-    private final BTDeviceRepository mBTDeviceRepository;
-    private final ConnectedBTDeviceRepository mConnectedBTDeviceRepository;
-    private final BehaviorSubject mContactsUploadConsentSubject;
-    private String mPrimaryDeviceAddress = "";
-    private final ScheduledExecutorService mExecutor;
-
-    /**
-     * Constructs an instance of ContactsControllerImpl.
-     *
-     * @param contextWk Android Context.
-     */
-    public ContactsControllerImpl(@NonNull WeakReference contextWk) {
-        mContextWk = contextWk;
-        mBTDeviceRepository = BTDeviceRepository.getInstance(mContextWk.get());
-        mConnectedBTDeviceRepository = ConnectedBTDeviceRepository.getInstance(mContextWk.get());
-        mContactsUploadConsentSubject = BehaviorSubject.create();
-        mExecutor = Executors.newSingleThreadScheduledExecutor();
-        if (!EventBus.getDefault().isRegistered(this)) {
-            EventBus.getDefault().register(this);
-        }
-        resetPermissionsWhenLogOut();
-    }
-
-    @Override
-    public void uploadContacts(String deviceAddress) {
-        Log.d(TAG, "Uploading contacts for device " + deviceAddress);
-        String aacsContactsPackageName = getAACSContactsPackageName(mContextWk);
-        if (aacsContactsPackageName == null) {
-            Log.e(TAG, "AACS contacts service is not available, skip to upload contacts.");
-        } else if (!mPrimaryDeviceAddress.equals(deviceAddress)) {
-            Log.i(TAG,
-                    "The device provided is not set to primary, skip to upload contacts. "
-                            + "The current primary device is " + mPrimaryDeviceAddress);
-        } else {
-            Log.d(TAG, "Uploading contacts...");
-            String deviceName = Util.getBluetoothDeviceName(mContextWk.get(), deviceAddress);
-            Util.toast(mContextWk.get(), mContextWk.get().getString(R.string.comms_toast_contacts_syncing, deviceName));
-            Intent intentStartService = new Intent();
-            intentStartService.setComponent(
-                    new ComponentName(aacsContactsPackageName, Constants.AACS_CONTACTS_SERVICE));
-            intentStartService.setAction(Constants.AACS_ACTION_UPLOAD_CONTACTS);
-            intentStartService.putExtra(Constants.AACS_EXTRA_ADDRESSBOOK_ID, deviceAddress);
-            intentStartService.putExtra(
-                    Constants.AACS_EXTRA_ADDRESSBOOK_NAME_KEY, Constants.AACS_EXTRA_ADDRESSBOOK_NAME_VALUE);
-            startAACSService(mContextWk.get(), intentStartService);
-        }
-    }
-
-    @Override
-    public void removeContacts(String deviceAddress) {
-        Log.d(TAG, "Removing contacts...");
-        String aacsContactsPackageName = getAACSContactsPackageName(mContextWk);
-        if (aacsContactsPackageName != null) {
-            Util.toast(mContextWk.get(), mContextWk.get().getString(R.string.comms_toast_contacts_removing));
-            Intent intentStartService = new Intent();
-            intentStartService.setComponent(
-                    new ComponentName(aacsContactsPackageName, Constants.AACS_CONTACTS_SERVICE));
-            intentStartService.setAction(Constants.AACS_ACTION_REMOVE_CONTACTS);
-            intentStartService.putExtra(Constants.AACS_EXTRA_ADDRESSBOOK_ID, deviceAddress);
-            startAACSService(mContextWk.get(), intentStartService);
-        } else {
-            Log.e(TAG, "AACS contacts service is not available, skip to remove contacts.");
-        }
-    }
-
-    @Override
-    public void setContactsUploadPermission(String deviceAddress, String permission) {
-        mBTDeviceRepository.getBTDeviceByAddress(deviceAddress);
-        mBTDeviceRepository.updateContactsPermission(deviceAddress, permission);
-        mConnectedBTDeviceRepository.updateContactsPermission(deviceAddress, permission);
-    }
-
-    @Override
-    public void setMessagingPermission(String deviceAddress, String permission) {
-        mBTDeviceRepository.getBTDeviceByAddress(deviceAddress);
-        mBTDeviceRepository.updateMessagingPermission(deviceAddress, permission);
-        mConnectedBTDeviceRepository.updateMessagingPermission(deviceAddress, permission);
-        Util.saveMessagingConsent(
-                mContextWk.get(), CONTACTS_PERMISSION_YES.equals(permission), deviceAddress, mPrimaryDeviceAddress);
-    }
-
-    @Override
-    public Observable observeContactsConsent() {
-        mBTDeviceRepository.findPrimaryBTDeviceEntry();
-        return mContactsUploadConsentSubject;
-    }
-
-    /**
-     * This method checks if a device is currently being paired and if the contacts
-     * consent had not been previously granted, it starts a new Contacts Activity. Once the
-     * contacts screen pops up, the bondState is reset so it only is shown once per pairing.
-     * It is also called by the OOBE flow for contacts consent.
-     */
-    @Subscribe
-    public void onBTDeviceDiscoveryChange(BTDeviceRepository.BTDeviceDiscoveryMessage message) {
-        Log.d(TAG, "onBTDeviceDiscoveryChange: " + message);
-        Boolean isLoggedIn = AlexaApp.from(mContextWk.get()).getRootComponent().getAuthController().isAuthenticated();
-        if (message.getFirstPair() == true && isLoggedIn) {
-            Log.d(TAG, "Contacts consent not granted, popping up consent screen");
-            Intent intent = new Intent(mContextWk.get(), RequestContactsConsentActivity.class);
-            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-            mContextWk.get().startActivity(intent);
-        }
-        if (message.isFound()) {
-            BTDevice device = message.getBTDevice();
-            Log.d(TAG,
-                    "onBTDeviceDiscoveryChange: contacts upload permission: " + device.getContactsUploadPermission());
-            if (device.getContactsUploadPermission().equals(Constants.CONTACTS_PERMISSION_NO)) {
-                mContactsUploadConsentSubject.onNext(true);
-            } else {
-                mContactsUploadConsentSubject.onNext(false);
-                uploadContacts(device.getDeviceAddress());
-            }
-            Log.d(TAG, "onBTDeviceDiscoveryChange: messaging permission: " + device.getMessagingPermission());
-            if (device.getMessagingPermission().equals(Constants.CONTACTS_PERMISSION_YES)) {
-                Util.saveMessagingConsent(mContextWk.get(), true, device.getDeviceAddress(), mPrimaryDeviceAddress);
-            } else {
-                Util.saveMessagingConsent(mContextWk.get(), false, device.getDeviceAddress(), mPrimaryDeviceAddress);
-            }
-        } else {
-            Log.d(TAG, "Bluetooth device is not found, skipping contacts upload consent step.");
-            mContactsUploadConsentSubject.onNext(false);
-        }
-    }
-
-    @Subscribe
-    public void onConnectedBTDeviceDiscoveryChange(
-            ConnectedBTDeviceRepository.ConnectedBTDeviceDiscoveryMessage connectedDeviceDiscoveryMessage) {
-        if (connectedDeviceDiscoveryMessage.isFound()) {
-            Log.d(TAG,
-                    "Device " + connectedDeviceDiscoveryMessage.getBConnectedBTDevice().getDeviceAddress()
-                            + " is disconnected, remove it from connected device database.");
-            mConnectedBTDeviceRepository.deleteEntry(connectedDeviceDiscoveryMessage.getBConnectedBTDevice());
-            removeContacts(connectedDeviceDiscoveryMessage.getBConnectedBTDevice().getDeviceAddress());
-        }
-    }
-
-    @Subscribe
-    public void onPrimaryPhoneChange(ConnectedBTDeviceRepository.PrimaryPhoneChangeMessage primaryPhoneChangeMessage) {
-        ConnectedBTDevice connectedBTDevice = primaryPhoneChangeMessage.getConnectedBTDevice();
-
-        if (connectedBTDevice != null) {
-            String contactUploadPermission = primaryPhoneChangeMessage.getContactsPermission();
-            String messagingPermission = primaryPhoneChangeMessage.getMessagingPermission();
-            mConnectedBTDeviceRepository.updateContactsPermission(
-                    connectedBTDevice.getDeviceAddress(), contactUploadPermission);
-            mConnectedBTDeviceRepository.updateMessagingPermission(
-                    connectedBTDevice.getDeviceAddress(), messagingPermission);
-        }
-        updatePrimaryDeviceAddress(
-                primaryPhoneChangeMessage.getConnectedBTDevice(), primaryPhoneChangeMessage.getIsNewDevice());
-    }
-
-    /**
-     * Start AACS service with intent.
-     *
-     * @param context Android context.
-     * @param intent  Android intent.
-     */
-    private void startAACSService(Context context, Intent intent) {
-        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
-            context.startForegroundService(intent);
-        } else {
-            context.startService(intent);
-        }
-    }
-
-    /**
-     * This method returns the package name of AACS Contacts Service dynamically.
-     * If AACS Contacts Service is running in AACS as separate application, it returns value of AACS package name.
-     * Otherwise if AACS Contacts Service is included in the client app as an AAR, it returns the client app
-     * package name.
-     *
-     * @param contextWk Weak reference of Android context for getting a package manager
-     * @return AACS Contacts Service package name
-     */
-    private String getAACSContactsPackageName(@NonNull WeakReference contextWk) {
-        if (_AACS_CONTACTS_PACKAGE_NAME == null) {
-            PackageManager packageManager = contextWk.get().getPackageManager();
-            try {
-                _AACS_CONTACTS_PACKAGE_NAME = AACSConstants.getAACSPackageName(contextWk);
-                PackageInfo packageInfo =
-                        packageManager.getPackageInfo(contextWk.get().getPackageName(), PackageManager.GET_SERVICES);
-                for (ServiceInfo serviceInfo : packageInfo.services) {
-                    if (serviceInfo.name.equals(Constants.AACS_CONTACTS_SERVICE)) {
-                        _AACS_CONTACTS_PACKAGE_NAME = contextWk.get().getPackageName();
-                        Log.d(TAG, String.format("Setting PACKAGE_NAME %s", _AACS_CONTACTS_PACKAGE_NAME));
-                        break;
-                    }
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                Log.e(TAG, "Failed to find AACS contacts package information in package manager.");
-                return null;
-            }
-        }
-        return _AACS_CONTACTS_PACKAGE_NAME;
-    }
-
-    private void updatePrimaryDeviceAddress(ConnectedBTDevice device, boolean isNewDevice) {
-        String deviceAddress = device == null ? "" : device.getDeviceAddress();
-        String permission = device == null ? CONTACTS_PERMISSION_NO : device.getContactsUploadPermission();
-        Log.d(TAG, "Contacts upload permission:  " + permission);
-
-        if (mPrimaryDeviceAddress.equals(deviceAddress)) {
-            Log.d(TAG, "The primary phone has not changed: " + mPrimaryDeviceAddress);
-            return;
-        }
-
-        String outdatedDeviceAddress = mPrimaryDeviceAddress;
-        mPrimaryDeviceAddress = deviceAddress;
-
-        if (!outdatedDeviceAddress.isEmpty()) {
-            Log.d(TAG, "removing the previously uploaded address book from " + outdatedDeviceAddress);
-            removeContacts(outdatedDeviceAddress);
-        }
-
-        if (permission.equals(CONTACTS_PERMISSION_YES)) {
-            if (!isNewDevice) {
-                Log.d(TAG, "Upload the address book from the primary phone " + deviceAddress);
-                uploadContacts(deviceAddress);
-            } else {
-                Log.d(TAG, "Schedule uploading address book after 30s from the primary phone " + deviceAddress);
-                mExecutor.schedule(() -> {
-                    // check the permission again before uploading the contacts
-                    Log.d(TAG, "start uploading address book from the primary phone " + deviceAddress);
-                    ConnectedBTDevice primaryDevice =
-                            mConnectedBTDeviceRepository.getConnectedDeviceByAddressSync(deviceAddress);
-                    if (primaryDevice != null
-                            && CONTACTS_PERMISSION_YES.equals(primaryDevice.getContactsUploadPermission())) {
-                        Log.d(TAG, "Uploading the address book from the primary phone " + deviceAddress);
-                        uploadContacts(deviceAddress);
-                    } else {
-                        Log.d(TAG, "address book uploading cancelled.");
-                    }
-                }, 30, TimeUnit.SECONDS);
-            }
-        }
-    }
-
-    /**
-     * Reset the contact sync permissions
-     * logout event was detected.
-     */
-    private void resetPermissionsWhenLogOut() {
-        @NonNull
-        AuthController authController = AlexaApp.from(mContextWk.get()).getRootComponent().getAuthController();
-
-        authController.observeAuthChangeOrLogOut().subscribe(authStatus -> {
-            if (!authStatus.getLoggedIn()) {
-                Log.i(TAG, "Resetting contact sync permissions to " + CONTACTS_PERMISSION_NO);
-
-                new AsyncTask() {
-                    @Override
-                    protected Void doInBackground(Void... voids) {
-                        List btDeviceList = mBTDeviceRepository.getBTDevices();
-                        if (btDeviceList != null && btDeviceList.size() > 0) {
-                            for (BTDevice btDevice : btDeviceList) {
-                                String address = btDevice.getDeviceAddress();
-                                mBTDeviceRepository.updateContactsPermission(address, CONTACTS_PERMISSION_NO);
-                                mConnectedBTDeviceRepository.updateContactsPermission(address, CONTACTS_PERMISSION_NO);
-                                mBTDeviceRepository.updateMessagingPermission(address, CONTACTS_PERMISSION_NO);
-                                mConnectedBTDeviceRepository.updateMessagingPermission(address, CONTACTS_PERMISSION_NO);
-                            }
-                        }
-                        return null;
-                    }
-                }.execute();
-            }
-        });
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/PreferenceKeys.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/PreferenceKeys.java
deleted file mode 100644
index 4aab7e267..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/PreferenceKeys.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui;
-
-public class PreferenceKeys {
-    public static final String CONTACTS_CONSENT_SETTINGS = "contacts-consent-settings";
-    public static final String SMS_CONSENT_SETTINGS = "sms-consent-settings";
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/RequestContactsConsentActivity.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/RequestContactsConsentActivity.java
deleted file mode 100644
index 8aaca2858..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/RequestContactsConsentActivity.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-
-import com.amazon.alexa.auto.comms.ui.fragment.setup.CommunicationConsentFragment;
-
-/**
- * Activity for Contacts Consent Popup
- */
-public class RequestContactsConsentActivity extends AppCompatActivity {
-    private static final String TAG = RequestContactsConsentActivity.class.getCanonicalName();
-
-    public void onCreate(Bundle savedInstanceState) {
-        Log.d(TAG, "Testing Contacts onCreate");
-        super.onCreate(savedInstanceState);
-        FragmentManager fm = getSupportFragmentManager();
-        FragmentTransaction ft = fm.beginTransaction();
-        Fragment fragment = new CommunicationConsentFragment();
-
-        ft.add(android.R.id.content, fragment, "CommunicationConsentFragment");
-
-        ft.commit();
-    }
-
-    public void onStart() {
-        super.onStart();
-        Log.d(TAG, "onStart");
-    }
-
-    /**
-     * Listens for new Intent created onClick to stop activity
-     */
-    @Override
-    public void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        boolean keep = intent.getExtras().getBoolean("keep");
-        Log.d(TAG, "new intent started" + keep);
-        if (keep == false) {
-            this.finish();
-        }
-    }
-
-    protected void onStop() {
-        super.onStop();
-        Log.d(TAG, "Contacts onStop");
-        this.finish();
-    }
-
-    protected void onDestroy() {
-        super.onDestroy();
-        Log.d(TAG, "onDestroy");
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDevice.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDevice.java
deleted file mode 100644
index 6e093fe5b..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDevice.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.db;
-
-import androidx.annotation.NonNull;
-import androidx.room.Entity;
-import androidx.room.PrimaryKey;
-
-import com.amazon.alexa.auto.comms.ui.Constants;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.io.Serializable;
-
-@Entity
-public class BTDevice implements Serializable {
-    @NonNull
-    @PrimaryKey
-    public String deviceAddress;
-    private String deviceName;
-    private String contactsUploadPermission;
-    private String messagingPermission;
-    private Boolean firstPair;
-
-    public BTDevice() {
-        deviceAddress = "";
-        deviceName = "";
-        contactsUploadPermission = Constants.CONTACTS_PERMISSION_NO;
-        messagingPermission = Constants.CONTACTS_PERMISSION_NO;
-        firstPair = false;
-    }
-
-    @NotNull
-    public String getDeviceAddress() {
-        return deviceAddress;
-    }
-
-    public void setDeviceAddress(@NotNull String deviceAddress) {
-        this.deviceAddress = deviceAddress;
-    }
-
-    public Boolean getFirstPair() {
-        return firstPair;
-    }
-
-    public void setFirstPair(Boolean firstPair) {
-        this.firstPair = firstPair;
-    }
-
-    public String getDeviceName() {
-        return deviceName;
-    }
-
-    public void setDeviceName(String deviceName) {
-        this.deviceName = deviceName;
-    }
-
-    public String getContactsUploadPermission() {
-        return contactsUploadPermission;
-    }
-
-    public void setContactsUploadPermission(String contactsUploadPermission) {
-        this.contactsUploadPermission = contactsUploadPermission;
-    }
-
-    public String getMessagingPermission() {
-        return messagingPermission;
-    }
-
-    public void setMessagingPermission(String messagingPermission) {
-        this.messagingPermission = messagingPermission;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceDao.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceDao.java
deleted file mode 100644
index 6447e317c..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceDao.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.db;
-
-import androidx.lifecycle.LiveData;
-import androidx.room.Dao;
-import androidx.room.Delete;
-import androidx.room.Insert;
-import androidx.room.OnConflictStrategy;
-import androidx.room.Query;
-import androidx.room.Update;
-
-import java.util.List;
-
-@Dao
-public interface BTDeviceDao {
-    @Query("SELECT * FROM BTDevice WHERE deviceAddress = :deviceAddress")
-    LiveData getBTDeviceByAddress(String deviceAddress);
-
-    @Query("SELECT * FROM BTDevice WHERE deviceAddress = :deviceAddress")
-    BTDevice getBTDeviceByAddressSync(String deviceAddress);
-
-    @Query("SELECT * FROM BTDevice")
-    List getDevicesSync();
-
-    @Insert(onConflict = OnConflictStrategy.REPLACE)
-    void insertBTDevice(BTDevice btDevice);
-
-    @Delete
-    void deleteBTDevice(BTDevice btDevice);
-
-    @Update
-    void updateBTDevice(BTDevice btDevice);
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceDatabase.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceDatabase.java
deleted file mode 100644
index 4d2706ec5..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceDatabase.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.db;
-
-import androidx.room.Database;
-import androidx.room.RoomDatabase;
-;
-
-@Database(entities = {BTDevice.class}, version = 1, exportSchema = false)
-public abstract class BTDeviceDatabase extends RoomDatabase {
-    public abstract BTDeviceDao btDeviceDao();
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceRepository.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceRepository.java
deleted file mode 100644
index ed5699cde..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/BTDeviceRepository.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.db;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-
-import androidx.lifecycle.LiveData;
-import androidx.room.Room;
-
-import com.amazon.alexa.auto.comms.ui.Constants;
-
-import org.greenrobot.eventbus.EventBus;
-
-import java.util.List;
-
-public class BTDeviceRepository {
-    private String DB_NAME = "db_bt_device";
-    private String CONNECTED_DEVICE_DB_NAME = "db_connected_bt_device";
-    private BTDeviceDatabase btDeviceDatabase;
-    private ConnectedBTDeviceDatabase connectedBTDeviceDatabase;
-
-    private Handler mHandler = new Handler(Looper.getMainLooper());
-
-    private static BTDeviceRepository sInstance;
-    private String TAG = BTDeviceRepository.class.getSimpleName();
-
-    public static BTDeviceRepository getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = new BTDeviceRepository(context);
-        }
-        return sInstance;
-    }
-
-    public BTDeviceRepository(Context context) {
-        btDeviceDatabase = Room.databaseBuilder(context, BTDeviceDatabase.class, DB_NAME).build();
-        connectedBTDeviceDatabase =
-                Room.databaseBuilder(context, ConnectedBTDeviceDatabase.class, CONNECTED_DEVICE_DB_NAME).build();
-    }
-
-    public void insertEntry(String deviceAddress, String deviceName, String connectionState,
-            String contactUploadPermission, boolean isPrimaryDevice, String messagingPermission) {
-        BTDevice device = new BTDevice();
-        device.setDeviceAddress(deviceAddress);
-        device.setDeviceName(deviceName);
-        device.setContactsUploadPermission(contactUploadPermission);
-        device.setMessagingPermission(messagingPermission);
-        insertEntry(device);
-    }
-
-    public LiveData getBTDeviceByAddress(String deviceAddress) {
-        return btDeviceDatabase.btDeviceDao().getBTDeviceByAddress(deviceAddress);
-    }
-
-    public List getBTDevices() {
-        return btDeviceDatabase.btDeviceDao().getDevicesSync();
-    }
-
-    public void shouldRequestContactsConsent(final BTDevice entry) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                BTDevice device = btDeviceDatabase.btDeviceDao().getBTDeviceByAddressSync(entry.getDeviceAddress());
-                if (device != null) {
-                    Log.i(TAG, "Device is paired, checking contacts consent permission");
-                    String permission = device.getContactsUploadPermission();
-                    Boolean firstPair = device.getFirstPair();
-                    if (permission.equals(Constants.CONTACTS_PERMISSION_NO) && firstPair == true) {
-                        Log.d(TAG, "Contacts consent not granted, popping up contacts consent screen");
-                        mHandler.post(
-                                () -> EventBus.getDefault().post(new BTDeviceDiscoveryMessage(device, true, true)));
-                        device.setFirstPair(false);
-                        device.setDeviceName(entry.getDeviceName());
-                        btDeviceDatabase.btDeviceDao().updateBTDevice(device);
-                    }
-                } else {
-                    Log.w(TAG,
-                            String.format("BTDevice with address=%s does not exist in the database",
-                                    entry.getDeviceAddress()));
-                }
-                return null;
-            }
-        }.execute();
-    }
-
-    public void insertEntry(final BTDevice entry) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                if (btDeviceDatabase.btDeviceDao().getBTDeviceByAddressSync(entry.getDeviceAddress()) != null) {
-                    Log.i(TAG, "bt device entry already exists");
-                    BTDevice device = btDeviceDatabase.btDeviceDao().getBTDeviceByAddressSync(entry.getDeviceAddress());
-                } else {
-                    Log.i(TAG, "Inserting bt device entry: " + entry.getDeviceAddress());
-                    btDeviceDatabase.btDeviceDao().insertBTDevice(entry);
-                }
-                return null;
-            }
-        }.execute();
-    }
-
-    public void deleteEntry(final BTDevice entry) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                btDeviceDatabase.btDeviceDao().deleteBTDevice(entry);
-                return null;
-            }
-        }.execute();
-    }
-
-    public void updateEntry(final BTDevice entry) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                btDeviceDatabase.btDeviceDao().updateBTDevice(entry);
-                return null;
-            }
-        }.execute();
-    }
-
-    public void updateContactsPermission(final String deviceAddress, final String permission) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                BTDevice device = btDeviceDatabase.btDeviceDao().getBTDeviceByAddressSync(deviceAddress);
-                device.setContactsUploadPermission(permission);
-                btDeviceDatabase.btDeviceDao().updateBTDevice(device);
-                return null;
-            }
-        }.execute();
-    }
-
-    public void updateMessagingPermission(final String deviceAddress, final String permission) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                BTDevice device = btDeviceDatabase.btDeviceDao().getBTDeviceByAddressSync(deviceAddress);
-                device.setMessagingPermission(permission);
-                btDeviceDatabase.btDeviceDao().updateBTDevice(device);
-                return null;
-            }
-        }.execute();
-    }
-
-    public void updateFirstPair(final String deviceAddress, final Boolean firstPair) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                BTDevice device = btDeviceDatabase.btDeviceDao().getBTDeviceByAddressSync(deviceAddress);
-                if (device != null) {
-                    device.setFirstPair(firstPair);
-                    btDeviceDatabase.btDeviceDao().updateBTDevice(device);
-                }
-                return null;
-            }
-        }.execute();
-    }
-
-    public void findPrimaryBTDeviceEntry() {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                List connectedDeviceList =
-                        connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDevicesSync();
-                if (connectedDeviceList.size() > 0) {
-                    // Getting last connected device.
-                    BTDevice targetDevice = btDeviceDatabase.btDeviceDao().getBTDeviceByAddressSync(
-                            connectedDeviceList.get(connectedDeviceList.size() - 1).getDeviceAddress());
-                    mHandler.post(() -> {
-                        if (targetDevice != null) {
-                            EventBus.getDefault().post(new BTDeviceDiscoveryMessage(targetDevice, true, false));
-                        }
-                    });
-                } else {
-                    Log.d(TAG, "There is no connected device.");
-                    mHandler.post(() -> EventBus.getDefault().post(new BTDeviceDiscoveryMessage(null, false, false)));
-                }
-                return null;
-            }
-        }.execute();
-    }
-
-    /**
-     * Bluetooth Device Discovery Message
-     */
-    public static class BTDeviceDiscoveryMessage {
-        private BTDevice device;
-        private boolean isFound;
-        private boolean firstPair;
-
-        public BTDeviceDiscoveryMessage(BTDevice device, boolean isFound, boolean firstPair) {
-            this.device = device;
-            this.isFound = isFound;
-            this.firstPair = firstPair;
-        }
-
-        public Boolean getFirstPair() {
-            return this.firstPair;
-        }
-
-        public BTDevice getBTDevice() {
-            return this.device;
-        }
-
-        public Boolean isFound() {
-            return this.isFound;
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDevice.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDevice.java
deleted file mode 100644
index bb324415f..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDevice.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.db;
-
-import androidx.annotation.NonNull;
-import androidx.room.Entity;
-import androidx.room.PrimaryKey;
-
-import com.amazon.alexa.auto.comms.ui.Constants;
-
-import java.io.Serializable;
-
-@Entity
-public class ConnectedBTDevice implements Serializable {
-    @NonNull
-    @PrimaryKey(autoGenerate = true)
-    private int id;
-    private String deviceAddress;
-    private String deviceName;
-    private String contactsUploadPermission;
-    private String messagingPermission;
-
-    public ConnectedBTDevice() {
-        deviceAddress = "";
-        deviceName = "";
-        contactsUploadPermission = Constants.CONTACTS_PERMISSION_NO;
-        messagingPermission = Constants.CONTACTS_PERMISSION_NO;
-    }
-
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    public void setDeviceAddress(String deviceAddress) {
-        this.deviceAddress = deviceAddress;
-    }
-
-    public String getDeviceAddress() {
-        return deviceAddress;
-    }
-
-    public String getDeviceName() {
-        return deviceName;
-    }
-
-    public void setDeviceName(String deviceName) {
-        this.deviceName = deviceName;
-    }
-
-    public String getContactsUploadPermission() {
-        return contactsUploadPermission;
-    }
-
-    public void setContactsUploadPermission(String contactsUploadPermission) {
-        this.contactsUploadPermission = contactsUploadPermission;
-    }
-
-    public String getMessagingPermission() {
-        return messagingPermission;
-    }
-
-    public void setMessagingPermission(String messagingPermission) {
-        this.messagingPermission = messagingPermission;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceDao.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceDao.java
deleted file mode 100644
index 0f788e00a..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceDao.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.db;
-
-import androidx.lifecycle.LiveData;
-import androidx.room.Dao;
-import androidx.room.Delete;
-import androidx.room.Insert;
-import androidx.room.OnConflictStrategy;
-import androidx.room.Query;
-import androidx.room.Update;
-
-import java.util.List;
-
-@Dao
-public interface ConnectedBTDeviceDao {
-    @Query("SELECT * FROM ConnectedBTDevice")
-    LiveData> getConnectedDevices();
-
-    @Query("SELECT * FROM ConnectedBTDevice ORDER BY id desc")
-    LiveData> getDescConnectedDevices();
-
-    @Query("SELECT * FROM ConnectedBTDevice")
-    List getConnectedDevicesSync();
-
-    @Query("SELECT * FROM ConnectedBTDevice WHERE deviceAddress = :deviceAddress")
-    LiveData getConnectedBTDeviceByAddressLive(String deviceAddress);
-
-    @Query("SELECT * FROM ConnectedBTDevice WHERE deviceAddress = :deviceAddress")
-    ConnectedBTDevice getConnectedDeviceByAddress(String deviceAddress);
-
-    @Insert(onConflict = OnConflictStrategy.REPLACE)
-    void insertConnectedBTDevice(ConnectedBTDevice btDevice);
-
-    @Delete
-    void deleteConnectedBTDevice(ConnectedBTDevice btDevice);
-
-    @Update
-    void updateConnectedBTDevice(ConnectedBTDevice btDevice);
-
-    @Query("DELETE FROM ConnectedBTDevice")
-    void nukeTable();
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceDatabase.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceDatabase.java
deleted file mode 100755
index 32e5222a0..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceDatabase.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.db;
-
-import androidx.room.Database;
-import androidx.room.RoomDatabase;
-
-@Database(entities = {ConnectedBTDevice.class}, version = 1, exportSchema = false)
-public abstract class ConnectedBTDeviceDatabase extends RoomDatabase {
-    public abstract ConnectedBTDeviceDao connectedBTDeviceDao();
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceRepository.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceRepository.java
deleted file mode 100644
index 881c26650..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/db/ConnectedBTDeviceRepository.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.db;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-
-import androidx.lifecycle.LiveData;
-import androidx.room.Room;
-
-import com.amazon.alexa.auto.comms.ui.Constants;
-
-import org.greenrobot.eventbus.EventBus;
-
-import java.util.List;
-
-public class ConnectedBTDeviceRepository {
-    private String CONNECTED_DB_NAME = "db_connected_bt_device";
-    private String DB_NAME = "db_bt_device";
-    private ConnectedBTDeviceDatabase connectedBTDeviceDatabase;
-    private BTDeviceDatabase btDeviceDatabase;
-    private Handler mHandler;
-
-    private static ConnectedBTDeviceRepository sInstance;
-    private String TAG = ConnectedBTDeviceRepository.class.getSimpleName();
-
-    public static ConnectedBTDeviceRepository getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = new ConnectedBTDeviceRepository(context);
-        }
-        return sInstance;
-    }
-
-    private ConnectedBTDeviceRepository(Context context) {
-        connectedBTDeviceDatabase =
-                Room.databaseBuilder(context, ConnectedBTDeviceDatabase.class, CONNECTED_DB_NAME).build();
-        btDeviceDatabase = Room.databaseBuilder(context, BTDeviceDatabase.class, DB_NAME).build();
-
-        mHandler = new Handler(Looper.getMainLooper());
-    }
-
-    public LiveData> getDescConnectedDevices() {
-        return connectedBTDeviceDatabase.connectedBTDeviceDao().getDescConnectedDevices();
-    }
-
-    public LiveData> getConnectedDevices() {
-        return connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDevices();
-    }
-
-    public List getConnectedDevicesSync() {
-        return connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDevicesSync();
-    }
-
-    public ConnectedBTDevice getConnectedDeviceByAddressSync(String deviceAddress) {
-        return connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDeviceByAddress(deviceAddress);
-    }
-
-    public LiveData getConnectedBTDeviceByAddress(String deviceAddress) {
-        return connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedBTDeviceByAddressLive(deviceAddress);
-    }
-
-    public void setConnectedDeviceToPrimary(String deviceAddress) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                Log.i(TAG, "setConnectedDeviceToPrimary: " + deviceAddress);
-                ConnectedBTDevice previousRecord =
-                        connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDeviceByAddress(deviceAddress);
-                if (previousRecord != null) {
-                    connectedBTDeviceDatabase.connectedBTDeviceDao().deleteConnectedBTDevice(previousRecord);
-                    ConnectedBTDevice connectedBTDevice = new ConnectedBTDevice();
-                    connectedBTDevice.setDeviceAddress(previousRecord.getDeviceAddress());
-                    connectedBTDevice.setDeviceName(previousRecord.getDeviceName());
-                    connectedBTDevice.setContactsUploadPermission(previousRecord.getContactsUploadPermission());
-                    connectedBTDevice.setMessagingPermission(previousRecord.getMessagingPermission());
-                    String contactUploadPermission = btDeviceDatabase.btDeviceDao()
-                                                             .getBTDeviceByAddressSync(deviceAddress)
-                                                             .getContactsUploadPermission();
-                    String messagingPermission = btDeviceDatabase.btDeviceDao()
-                                                         .getBTDeviceByAddressSync(deviceAddress)
-                                                         .getMessagingPermission();
-                    Log.i(TAG, "Inserting bt connected device entry: " + connectedBTDevice.getDeviceAddress());
-                    connectedBTDeviceDatabase.connectedBTDeviceDao().insertConnectedBTDevice(connectedBTDevice);
-                    EventBus.getDefault().post(new PrimaryPhoneChangeMessage(
-                            connectedBTDevice, false, contactUploadPermission, messagingPermission));
-                }
-                return null;
-            }
-        }.execute();
-    }
-
-    public void insertEntry(final BTDevice device) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                boolean isNewDevice = true;
-                if (connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDeviceByAddress(
-                            device.getDeviceAddress())
-                        != null) {
-                    ConnectedBTDevice previousRecord =
-                            connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDeviceByAddress(
-                                    device.getDeviceAddress());
-                    connectedBTDeviceDatabase.connectedBTDeviceDao().deleteConnectedBTDevice(previousRecord);
-                    Log.i(TAG, "Deleting previous bt record: " + device.getDeviceAddress());
-                    isNewDevice = false;
-                }
-
-                String contactUploadPermission = device.getContactsUploadPermission();
-                String messagingPermission = device.getMessagingPermission();
-                ConnectedBTDevice connectedBTDevice = new ConnectedBTDevice();
-                connectedBTDevice.setDeviceAddress(device.getDeviceAddress());
-                connectedBTDevice.setDeviceName(device.getDeviceName());
-                connectedBTDevice.setContactsUploadPermission(device.getContactsUploadPermission());
-                connectedBTDevice.setMessagingPermission(device.getMessagingPermission());
-                Log.i(TAG, "Inserting bt connected device entry: " + connectedBTDevice.getDeviceAddress());
-                connectedBTDeviceDatabase.connectedBTDeviceDao().insertConnectedBTDevice(connectedBTDevice);
-                EventBus.getDefault().post(new PrimaryPhoneChangeMessage(
-                        connectedBTDevice, isNewDevice, contactUploadPermission, messagingPermission));
-                return null;
-            }
-        }.execute();
-    }
-
-    public void deleteEntry(final ConnectedBTDevice entry) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                connectedBTDeviceDatabase.connectedBTDeviceDao().deleteConnectedBTDevice(entry);
-                List listData = getConnectedDevicesSync();
-                if (listData != null && listData.size() > 0) {
-                    int index = listData.size() - 1;
-                    BTDevice btDevice = btDeviceDatabase.btDeviceDao().getBTDeviceByAddressSync(
-                            listData.get(index).getDeviceAddress());
-                    String contactUploadPermission = btDevice.getContactsUploadPermission();
-                    String messagingPermission = btDevice.getMessagingPermission();
-                    EventBus.getDefault().post(new PrimaryPhoneChangeMessage(
-                            listData.get(index), false, contactUploadPermission, messagingPermission));
-                } else {
-                    EventBus.getDefault().post(new PrimaryPhoneChangeMessage(
-                            null, false, Constants.CONTACTS_PERMISSION_NO, Constants.CONTACTS_PERMISSION_NO));
-                }
-                return null;
-            }
-        }.execute();
-    }
-
-    public void nukeTable(){
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                connectedBTDeviceDatabase.connectedBTDeviceDao().nukeTable();
-                return null;
-            }
-        }.execute();
-    }
-
-    public void updateContactsPermission(final String deviceAddress, final String permission) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                ConnectedBTDevice device =
-                        connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDeviceByAddress(deviceAddress);
-                if (device != null) {
-                    device.setContactsUploadPermission(permission);
-                    connectedBTDeviceDatabase.connectedBTDeviceDao().updateConnectedBTDevice(device);
-                } else {
-                    Log.e(TAG, "Device not found in ConnectedBTDeviceRepository");
-                }
-                return null;
-            }
-        }.execute();
-    }
-
-    public void updateMessagingPermission(final String deviceAddress, final String permission) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                ConnectedBTDevice device =
-                        connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDeviceByAddress(deviceAddress);
-                if (device != null) {
-                    device.setMessagingPermission(permission);
-                    connectedBTDeviceDatabase.connectedBTDeviceDao().updateConnectedBTDevice(device);
-                } else {
-                    Log.e(TAG, "Device not found in ConnectedBTDeviceRepository");
-                }
-                return null;
-            }
-        }.execute();
-    }
-
-    public void findConnectedBTDeviceEntry(BTDevice entry) {
-        new AsyncTask() {
-            @Override
-            protected Void doInBackground(Void... voids) {
-                ConnectedBTDevice targetDevice =
-                        connectedBTDeviceDatabase.connectedBTDeviceDao().getConnectedDeviceByAddress(
-                                entry.getDeviceAddress());
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (targetDevice != null) {
-                            EventBus.getDefault().post(new ConnectedBTDeviceDiscoveryMessage(targetDevice, true));
-                        } else {
-                            EventBus.getDefault().post(new ConnectedBTDeviceDiscoveryMessage(null, false));
-                        }
-                    }
-                });
-                return null;
-            }
-        }.execute();
-    }
-
-    /**
-     * Connected Bluetooth Device Discovery Message
-     */
-    public static class ConnectedBTDeviceDiscoveryMessage {
-        private ConnectedBTDevice device;
-        private boolean isFound;
-
-        public ConnectedBTDeviceDiscoveryMessage(ConnectedBTDevice device, boolean isFound) {
-            this.device = device;
-            this.isFound = isFound;
-        }
-
-        public ConnectedBTDevice getBConnectedBTDevice() {
-            return this.device;
-        }
-
-        public Boolean isFound() {
-            return this.isFound;
-        }
-    }
-
-    /**
-     * Primary Phone Change Discovery Message
-     */
-    public static class PrimaryPhoneChangeMessage {
-        private ConnectedBTDevice device;
-        private boolean isNewDevice;
-        private String contactsPermission;
-        private String messagingPermission;
-        public PrimaryPhoneChangeMessage(
-                ConnectedBTDevice device, boolean newDevice, String contactsPermission, String messagingPermission) {
-            this.isNewDevice = newDevice;
-            this.device = device;
-            this.contactsPermission = contactsPermission;
-            this.messagingPermission = messagingPermission;
-        }
-        public ConnectedBTDevice getConnectedBTDevice() {
-            return this.device;
-        }
-        public boolean getIsNewDevice() {
-            return this.isNewDevice;
-        }
-        public String getContactsPermission() {
-            return this.contactsPermission;
-        }
-        public String getMessagingPermission() {
-            return this.messagingPermission;
-        }
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/AndroidModule.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/AndroidModule.java
deleted file mode 100644
index 1fd6426ac..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/AndroidModule.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.dependencies;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-
-import java.lang.ref.WeakReference;
-
-import dagger.Module;
-import dagger.Provides;
-
-/**
- * Module for providing Android Objects.
- */
-@Module
-public class AndroidModule {
-    private WeakReference mContext;
-
-    /**
-     * Constructs the @c AndroidModule.
-     *
-     * @param context Android Context.
-     */
-    public AndroidModule(@NonNull Context context) {
-        this.mContext = new WeakReference<>(context);
-    }
-
-    /**
-     * Provides the Android Context.
-     *
-     * @return Android Context.
-     */
-    @Provides
-    public WeakReference provideContext() {
-        return this.mContext;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/CommunicationComponent.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/CommunicationComponent.java
deleted file mode 100644
index 206069555..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/CommunicationComponent.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.dependencies;
-
-import com.amazon.alexa.auto.comms.ui.receiver.BluetoothReceiver;
-
-import javax.inject.Singleton;
-
-import dagger.Component;
-
-/**
- * Dagger Component for injecting Communication Dependencies.
- */
-@Component(modules = {CommunicationModule.class, AndroidModule.class})
-@Singleton
-public interface CommunicationComponent {
-    /**
-     * Inject dependencies for @c BluetoothReceiver.
-     *
-     * @param receiver receiver where dependencies are injected.
-     */
-    void injectBluetoothReceiver(BluetoothReceiver receiver);
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/CommunicationModule.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/CommunicationModule.java
deleted file mode 100644
index 575fd1012..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/dependencies/CommunicationModule.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.dependencies;
-
-import android.content.Context;
-import android.telecom.TelecomManager;
-
-import com.amazon.alexa.auto.comms.ui.handler.BluetoothDirectiveHandler;
-
-import java.lang.ref.WeakReference;
-
-import javax.inject.Singleton;
-
-import dagger.Module;
-import dagger.Provides;
-
-/**
- * Module to provide objects for Alexa communication.
- */
-@Module
-public class CommunicationModule {
-    @Provides
-    @Singleton
-    public BluetoothDirectiveHandler provideCommunicationDirectiveHandler(WeakReference context) {
-        return new BluetoothDirectiveHandler(context);
-    }
-
-    @Provides
-    @Singleton
-    public TelecomManager provideTelecomManager(WeakReference context) {
-        return (TelecomManager) context.get().getSystemService(Context.TELECOM_SERVICE);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/settings/CommunicationFragment.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/settings/CommunicationFragment.java
deleted file mode 100644
index da4998f9a..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/settings/CommunicationFragment.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.fragment.settings;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-import androidx.constraintlayout.widget.ConstraintLayout;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.LiveData;
-import androidx.navigation.NavController;
-import androidx.navigation.Navigation;
-
-import com.amazon.alexa.auto.comms.ui.Constants;
-import com.amazon.alexa.auto.comms.ui.R;
-import com.amazon.alexa.auto.comms.ui.db.BTDevice;
-import com.amazon.alexa.auto.comms.ui.db.BTDeviceRepository;
-import com.amazon.alexa.auto.comms.ui.db.ConnectedBTDevice;
-import com.amazon.alexa.auto.comms.ui.db.ConnectedBTDeviceRepository;
-
-import java.util.List;
-import java.util.Set;
-
-
-/**
- * Communication fragment to manage all connected bluetooth devices in a list.
- */
-public class CommunicationFragment extends Fragment {
-    private static final String TAG = CommunicationFragment.class.getSimpleName();
-
-    private NavController mController;
-    BluetoothManager mBluetoothManager;
-    BluetoothAdapter mBluetoothAdapter;
-    Bundle newBundle;
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        newBundle = getArguments();
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-
-        if(newBundle.getString("device").equals("true")){
-            return inflater.inflate(R.layout.communication_settings_fragment, container, false);
-        }
-        return inflater.inflate(R.layout.communication_settings_fragment_no_device, container, false);
-    }
-
-    @Override
-    public void onViewCreated(View view1, Bundle bundle){
-        super.onViewCreated(view1, bundle);
-        View fragmentView = requireView();
-        mController = findNavController(fragmentView);
-        mBluetoothManager = (BluetoothManager) getContext().getSystemService(Context.BLUETOOTH_SERVICE);
-        mBluetoothAdapter = mBluetoothManager.getAdapter();
-        BTDeviceRepository BTDeviceRepo = BTDeviceRepository.getInstance(getContext());
-        ConnectedBTDeviceRepository ConnectedBTDeviceRepo = ConnectedBTDeviceRepository.getInstance(getContext());
-
-        // Dynamically observe all the paired bluetooth devices from bluetooth adapter bonded devices
-        Set pairedDevices = mBluetoothAdapter.getBondedDevices();
-        // Save last device address to know when to add primary device to top and add pair new button
-
-        ConstraintLayout rootLayout = (ConstraintLayout) fragmentView.findViewById(R.id.alexa_communication_fragment);
-
-        LiveData> listData =
-                ConnectedBTDeviceRepository.getInstance(getContext()).getConnectedDevices();
-
-                listData.observe(getViewLifecycleOwner(), listObserver -> {
-                    if (listData.getValue() != null && listData.getValue().size() > 0 && pairedDevices.size()>0) {
-                        // Per Android telephony, it uses last paired bluetooth device for calling and handle messages.
-                        ConnectedBTDevice primaryDevice = listData.getValue().get(listData.getValue().size() - 1);
-                        String lastAddress = primaryDevice.getDeviceAddress();
-                        String lastDeviceName = primaryDevice.getDeviceName();
-
-                        TextView primaryDeviceName = (TextView) rootLayout.findViewById(R.id.deviceName);
-                        String formattedString = String.format((String) primaryDeviceName.getText(), lastDeviceName);
-                        primaryDeviceName.setText( formattedString);
-                        Bundle deviceAddress = new Bundle();
-                        deviceAddress.putString(Constants.COMMUNICATION_DEVICE_ADDRESS, lastAddress);
-                        requireActivity().getSupportFragmentManager()
-                                .beginTransaction()
-                                .replace(R.id.settings, new CommunicationPreferenceFragment(deviceAddress))
-                                .commit();
-                        Button btSetting = (Button) rootLayout.findViewById(R.id.btSetting);
-                        btSetting.setOnClickListener(view -> {
-                            goToBluetoothSettings(getContext());
-                        });
-                    }else {
-                        ConstraintLayout rootLayout1 = (ConstraintLayout) fragmentView.findViewById(R.id.alexa_communication_fragment);
-                        Button btSetting = (Button) rootLayout1.findViewById(R.id.btSetting);
-                        btSetting.setOnClickListener(view -> { goToBluetoothSettings(getContext());} );
-                    }
-                });
-    }
-
-    @VisibleForTesting
-    NavController findNavController(@NonNull View view) {
-        return Navigation.findNavController(view);
-    }
-
-    /**
-     * Navigate to Android bluetooth settings.
-     * @param context Android context.
-     */
-    private void goToBluetoothSettings(Context context) {
-        Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        context.getApplicationContext().startActivity(intent);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/settings/CommunicationPreferenceFragment.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/settings/CommunicationPreferenceFragment.java
deleted file mode 100644
index 89c3acb34..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/settings/CommunicationPreferenceFragment.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.fragment.settings;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.lifecycle.LiveData;
-import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.PreferenceManager;
-import androidx.preference.SwitchPreferenceCompat;
-
-import com.amazon.alexa.auto.apis.app.AlexaApp;
-import com.amazon.alexa.auto.apis.communication.ContactsController;
-import com.amazon.alexa.auto.apps.common.util.ModuleProvider;
-import com.amazon.alexa.auto.apps.common.util.Preconditions;
-import com.amazon.alexa.auto.comms.ui.Constants;
-import com.amazon.alexa.auto.comms.ui.PreferenceKeys;
-import com.amazon.alexa.auto.comms.ui.R;
-import com.amazon.alexa.auto.comms.ui.db.BTDevice;
-import com.amazon.alexa.auto.comms.ui.db.BTDeviceRepository;
-
-/**
- * Communication preference fragment to manage all the communication consents status.
- */
-public class CommunicationPreferenceFragment extends PreferenceFragmentCompat{
-    private static final String TAG = CommunicationPreferenceFragment.class.getSimpleName();
-
-    private String mDeviceAddress;
-    private AlexaApp mApp;
-
-    public CommunicationPreferenceFragment() {}
-
-    public CommunicationPreferenceFragment(Bundle deviceAddress) {
-        Log.d(TAG, "This is device ID from bundle: " + deviceAddress.getString(Constants.COMMUNICATION_DEVICE_ADDRESS));
-        mDeviceAddress = deviceAddress.getString(Constants.COMMUNICATION_DEVICE_ADDRESS);
-    }
-
-    @Override
-    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-        setPreferencesFromResource(R.xml.communication_preferences, rootKey);
-
-        Context context = getContext();
-        if (context != null) {
-            PreferenceManager.setDefaultValues(context, R.xml.communication_preferences, false);
-        }
-    }
-
-    @Override
-    public void onRequestPermissionsResult(
-            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
-        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
-    }
-
-    @Override
-    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
-        requireView();
-
-        // Initialize switch settings for contact upload and SMS
-        setConsentPermissions();
-
-        // Monitor consent changes for contact upload and SMS
-        monitorContactUploadConsentPreferenceChanges();
-        monitorMessagingConsentPreferenceChanges();
-    }
-
-    private void monitorContactUploadConsentPreferenceChanges() {
-        SwitchPreferenceCompat contactUploadConsent = findPreference(PreferenceKeys.CONTACTS_CONSENT_SETTINGS);
-        Preconditions.checkNotNull(contactUploadConsent);
-
-        contactUploadConsent.setOnPreferenceChangeListener((preference, newValue) -> {
-            Context context = getContext();
-            Preconditions.checkNotNull(context);
-
-            mApp = AlexaApp.from(context);
-
-            Boolean consentValue = (Boolean) newValue;
-            if (consentValue) {
-                uploadContacts(mDeviceAddress);
-            } else {
-                removeContacts(mDeviceAddress);
-            }
-
-            return true;
-        });
-    }
-
-    private void setConsentPermissions() {
-        Context context = getContext();
-        Preconditions.checkNotNull(context);
-
-        LiveData device = BTDeviceRepository.getInstance(getContext()).getBTDeviceByAddress(mDeviceAddress);
-        device.observe(getViewLifecycleOwner(), observer -> {
-            if (device.getValue() != null) {
-                SwitchPreferenceCompat contactUploadConsent = findPreference(PreferenceKeys.CONTACTS_CONSENT_SETTINGS);
-
-                Preconditions.checkNotNull(contactUploadConsent);
-
-                if (ModuleProvider.isAlexaCustomAssistantEnabled(context)) {
-                    contactUploadConsent.setSummary(
-                            R.string.contacts_upload_consent_summary_with_alexa_custom_assistant);
-                }
-
-                boolean consent =
-                        device.getValue().getContactsUploadPermission().equals(Constants.CONTACTS_PERMISSION_YES);
-                contactUploadConsent.setChecked(consent);
-
-                SwitchPreferenceCompat messagingConsent = findPreference(PreferenceKeys.SMS_CONSENT_SETTINGS);
-                Preconditions.checkNotNull(messagingConsent);
-
-                consent = device.getValue().getMessagingPermission().equals(Constants.CONTACTS_PERMISSION_YES);
-                messagingConsent.setChecked(consent);
-
-            } else {
-                Log.d(TAG, "There is no device found.");
-            }
-        });
-    }
-
-    private void monitorMessagingConsentPreferenceChanges() {
-        SwitchPreferenceCompat messagingConsent = findPreference(PreferenceKeys.SMS_CONSENT_SETTINGS);
-        Preconditions.checkNotNull(messagingConsent);
-
-        messagingConsent.setOnPreferenceChangeListener((preference, newValue) -> {
-            Context context = getContext();
-            Preconditions.checkNotNull(context);
-
-            mApp = AlexaApp.from(context);
-
-            boolean newConsent = (Boolean) newValue;
-            mApp.getRootComponent().getComponent(ContactsController.class).ifPresent(contactsController -> {
-                Log.d(TAG, "Saving messaging consent permission");
-                contactsController.setMessagingPermission(mDeviceAddress,
-                        newConsent ? Constants.CONTACTS_PERMISSION_YES : Constants.CONTACTS_PERMISSION_NO);
-            });
-
-            return true;
-        });
-    }
-
-    /**
-     * Upload contacts with device address.
-     * @param deviceAddress bluetooth device address.
-     */
-    public void uploadContacts(String deviceAddress) {
-        mApp.getRootComponent().getComponent(ContactsController.class).ifPresent(contactsController -> {
-            Log.d(TAG, "Uploading contacts...");
-            contactsController.setContactsUploadPermission(deviceAddress, Constants.CONTACTS_PERMISSION_YES);
-            contactsController.uploadContacts(deviceAddress);
-        });
-    }
-
-    /**
-     * Remove contacts with device address.
-     * @param deviceAddress bluetooth device address.
-     */
-    public void removeContacts(String deviceAddress) {
-        mApp.getRootComponent().getComponent(ContactsController.class).ifPresent(contactsController -> {
-            Log.d(TAG, "Removing contacts");
-            contactsController.setContactsUploadPermission(deviceAddress, Constants.CONTACTS_PERMISSION_NO);
-            contactsController.removeContacts(deviceAddress);
-        });
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/setup/CommunicationConsentFragment.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/setup/CommunicationConsentFragment.java
deleted file mode 100644
index ef4de7294..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/setup/CommunicationConsentFragment.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.fragment.setup;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.ViewModelProvider;
-
-import com.amazon.alexa.auto.apps.common.util.ModuleProvider;
-import com.amazon.alexa.auto.comms.ui.Constants;
-import com.amazon.alexa.auto.comms.ui.R;
-import com.amazon.alexa.auto.comms.ui.RequestContactsConsentActivity;
-import com.amazon.alexa.auto.comms.ui.db.BTDevice;
-import com.amazon.alexa.auto.comms.ui.db.BTDeviceRepository;
-import com.amazon.alexa.auto.comms.ui.db.ConnectedBTDevice;
-import com.amazon.alexa.auto.comms.ui.db.ConnectedBTDeviceRepository;
-
-import java.util.List;
-
-/**
- * Fragment for displaying Communications consent screen.
- */
-public class CommunicationConsentFragment extends Fragment {
-    private static final String TAG = CommunicationConsentFragment.class.getSimpleName();
-
-    private CommunicationConsentViewModel mViewModel;
-
-    /**
-     * Constructs an instance of CommunicationsFragment.
-     */
-    public CommunicationConsentFragment() {
-    }
-
-    /**
-     * Constructs an instance of CommunicationsFragment.
-     *
-     * @param viewModel View Model for Communications consent.
-     */
-    @VisibleForTesting
-    CommunicationConsentFragment(@NonNull CommunicationConsentViewModel viewModel) {
-        this.mViewModel = viewModel;
-    }
-
-    @Override
-    public void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (mViewModel == null) { // It would be non-null for test injected dependencies.
-            mViewModel = new ViewModelProvider(this).get(CommunicationConsentViewModel.class);
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        return inflater.inflate(R.layout.communication_setup_fragment, container, false);
-    }
-
-    @Override
-    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        observePrimaryConnectedDevice();
-    }
-
-    /**
-     * Observe primary connected device, which we use for calling and handling messages.
-     */
-    private void observePrimaryConnectedDevice() {
-        LiveData> listData =
-                ConnectedBTDeviceRepository.getInstance(getContext()).getConnectedDevices();
-        listData.observe(getViewLifecycleOwner(), listObserver -> {
-            if (listData.getValue() != null && listData.getValue().size() > 0) {
-                // Per Android telephony, it uses last paired bluetooth device for calling and handle messages.
-                String deviceAddress = listData.getValue().get(listData.getValue().size() - 1).getDeviceAddress();
-                Log.d(TAG, "Primary device is found.");
-                observeContactUploadPermission(deviceAddress);
-            } else {
-                Log.i(TAG, "There is no connected device found.");
-            }
-        });
-    }
-
-    /**
-     * Observe contact upload consent, if user consents to upload contacts, we will automatically upload contacts with
-     * the synced phone book. If not, we display the consent screen again to ask for the permission.
-     *
-     * @param deviceAddress bluetooth device address.
-     */
-    private void observeContactUploadPermission(String deviceAddress) {
-        LiveData device = BTDeviceRepository.getInstance(getContext()).getBTDeviceByAddress(deviceAddress);
-        device.observe(getViewLifecycleOwner(), observer -> {
-            if (device.getValue() != null) {
-                if (device.getValue().getContactsUploadPermission().equals(Constants.CONTACTS_PERMISSION_YES)) {
-                    Log.d(TAG, "Device's contacts upload permission is YES, uploading contacts.");
-                    mViewModel.uploadContacts(deviceAddress);
-                } else {
-                    View fragmentView = requireView();
-
-                    TextView getYesButtonText = fragmentView.findViewById(R.id.contacts_upload_yes_action_button);
-                    TextView getSkipButtonText = fragmentView.findViewById(R.id.contacts_upload_skip_action_button);
-
-                    if (ModuleProvider.isAlexaCustomAssistantEnabled(fragmentView.getContext())) {
-                        // Update text content
-                        TextView consentPermissionHeading =
-                                fragmentView.findViewById(R.id.contacts_permission_consent_header);
-
-                        getYesButtonText.setText(R.string.contacts_consent_yes_with_alexa_custom_assistant);
-                        TextView alexaContactsHint = fragmentView.findViewById(R.id.alexa_contacts_hint1);
-                        alexaContactsHint.setVisibility(View.GONE);
-                        consentPermissionHeading
-                                .setText(
-                                        getResources()
-                                                .getString(
-                                                        R.string.contacts_permission_consent_body_with_alexa_custom_assistant,
-                                                        device.getValue().getDeviceName()
-                                                )
-                                );
-                    }
-                    String actName = String.valueOf(getActivity());
-                    Log.d(TAG, "Device's contacts upload permission is NO, showing contacts consent card.");
-                    getYesButtonText.setOnClickListener(view -> {
-                        mViewModel.setContactsUploadPermission(
-                                device.getValue().getDeviceAddress(), Constants.CONTACTS_PERMISSION_YES);
-                        if (actName.contains(Constants.CONTACTS_ACTIVITY)) {
-                            popupActivity();
-                        }
-                    });
-
-                    getSkipButtonText.setOnClickListener(view -> {
-                        mViewModel.setContactsUploadPermission(
-                                device.getValue().getDeviceAddress(), Constants.CONTACTS_PERMISSION_NO);
-                        if (actName.contains(Constants.CONTACTS_ACTIVITY)) {
-                            popupActivity();
-                        }
-                    });
-                }
-            } else {
-                Log.d(TAG, "Connected device is not found");
-            }
-        });
-    }
-
-    /**
-     * Starts the RequestContactsConsentActivity
-     */
-    private void popupActivity() {
-        Intent intent = new Intent(getActivity(), RequestContactsConsentActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra("keep", "false");
-        startActivity(intent);
-    }
-}
\ No newline at end of file
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/setup/CommunicationConsentViewModel.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/setup/CommunicationConsentViewModel.java
deleted file mode 100644
index d987f5c52..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/fragment/setup/CommunicationConsentViewModel.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.fragment.setup;
-
-import android.app.Application;
-import android.os.Handler;
-import android.os.Looper;
-
-import androidx.annotation.NonNull;
-import androidx.lifecycle.AndroidViewModel;
-
-import com.amazon.alexa.auto.apis.app.AlexaApp;
-import com.amazon.alexa.auto.apis.communication.ContactsController;
-import com.amazon.alexa.auto.comms.ui.Constants;
-import com.amazon.alexa.auto.setup.workflow.WorkflowMessage;
-
-import org.greenrobot.eventbus.EventBus;
-
-/**
- * ViewModel for @{link CommunicationsFragment}
- */
-public class CommunicationConsentViewModel extends AndroidViewModel {
-    private static final String TAG = CommunicationConsentViewModel.class.getSimpleName();
-
-    private final Handler mHandler;
-    private final AlexaApp mApp;
-    /**
-     * Constructor for CommunicationsViewModel
-     *
-     * @param application Application object from where the view model will
-     *                    fetch dependencies.
-     */
-    public CommunicationConsentViewModel(@NonNull Application application) {
-        super(application);
-
-        mHandler = new Handler(Looper.getMainLooper());
-        mApp = AlexaApp.from(application);
-    }
-
-    /**
-     * Set contacts upload permission, when permission is set, we send workflow event of consent step finish.
-     * @param deviceAddress bluetooth device address.
-     * @param permission contact upload permission.
-     */
-    public void setContactsUploadPermission(String deviceAddress, String permission) {
-        mApp.getRootComponent().getComponent(ContactsController.class).ifPresent(contactsController -> {
-            contactsController.setContactsUploadPermission(deviceAddress, permission);
-            if (permission.equals(Constants.CONTACTS_PERMISSION_YES)) {
-                uploadContacts(deviceAddress);
-            }
-
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    EventBus.getDefault().post(new WorkflowMessage("Contacts_Consent_Setup_Finished"));
-                }
-            });
-        });
-    }
-
-    /**
-     * Upload contacts with device address.
-     * @param deviceAddress bluetooth device address.
-     */
-    public void uploadContacts(String deviceAddress) {
-        mApp.getRootComponent().getComponent(ContactsController.class).ifPresent(contactsController -> {
-            contactsController.uploadContacts(deviceAddress);
-        });
-    }
-
-    /**
-     * Remove contacts with device id.
-     * @param deviceAddress bluetooth device address.
-     */
-    public void removeContacts(String deviceAddress) {
-        mApp.getRootComponent().getComponent(ContactsController.class).ifPresent(contactsController -> {
-            contactsController.removeContacts(deviceAddress);
-        });
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/handler/BluetoothDirectiveHandler.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/handler/BluetoothDirectiveHandler.java
deleted file mode 100644
index 921fa223c..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/handler/BluetoothDirectiveHandler.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.handler;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-
-import com.amazon.alexa.auto.apis.app.AlexaApp;
-import com.amazon.alexa.auto.apis.communication.ContactsController;
-import com.amazon.alexa.auto.comms.ui.Constants;
-import com.amazon.alexa.auto.comms.ui.ContactsControllerImpl;
-import com.amazon.alexa.auto.comms.ui.db.BTDevice;
-import com.amazon.alexa.auto.comms.ui.db.BTDeviceRepository;
-import com.amazon.alexa.auto.comms.ui.db.ConnectedBTDeviceRepository;
-
-import java.lang.ref.WeakReference;
-
-/**
- * Handler for bluetooth directives coming from AACS.
- */
-public class BluetoothDirectiveHandler {
-    private final static String TAG = BluetoothDirectiveHandler.class.getSimpleName();
-
-    Context mContext;
-    BTDeviceRepository mBTDeviceRepository;
-    ConnectedBTDeviceRepository mConnectedBTDeviceRepository;
-
-    /**
-     * Constructs the bluetooth commands handler.
-     */
-    public BluetoothDirectiveHandler(WeakReference context) {
-        mContext = context.get();
-
-        AlexaApp mApp = AlexaApp.from(mContext);
-        if (!mApp.getRootComponent().getComponent(ContactsController.class).isPresent()) {
-            mApp.getRootComponent().activateScope(new ContactsControllerImpl(context));
-        }
-
-        mBTDeviceRepository = BTDeviceRepository.getInstance(mContext);
-        mConnectedBTDeviceRepository = ConnectedBTDeviceRepository.getInstance(mContext);
-    }
-
-    /**
-     * Constructs the bluetooth commands handler.
-     * This is created for unit testing.
-     */
-    @VisibleForTesting
-    BluetoothDirectiveHandler(
-            BTDeviceRepository btDeviceRepository, ConnectedBTDeviceRepository connectedBTDeviceRepository) {
-        mBTDeviceRepository = btDeviceRepository;
-        mConnectedBTDeviceRepository = connectedBTDeviceRepository;
-    }
-
-    /**
-     * Handle bond state for BOND_BONDED (paired) to update the BTDevice. The 'firstPair' flag in
-     * the BTDevice is used to distinguish between when a device is being paired versus connected.
-     * The 'firstPair' flag in the BTDevice is set to false when the BOND_BONDED intent is received
-     * for the device. Once it is set to false, it prevents the contact consent popup from showing
-     * up in subsequent disconnect/reconnects.
-     */
-    public void handleBondStateChange(@NonNull BTDevice device, Integer bondState) {
-        String deviceAddress = device.getDeviceAddress();
-        Log.d(TAG, "BTHandler bond state: " + bondState);
-        if (bondState == BluetoothDevice.BOND_BONDED) {
-            Log.d(TAG, "Device bonded, update device on first pair");
-            mBTDeviceRepository.insertEntry(device);
-            mBTDeviceRepository.updateFirstPair(deviceAddress, true);
-        } else if (bondState == BluetoothDevice.BOND_NONE) {
-            mBTDeviceRepository.updateContactsPermission(deviceAddress, Constants.CONTACTS_PERMISSION_NO);
-            mBTDeviceRepository.updateMessagingPermission(deviceAddress, Constants.CONTACTS_PERMISSION_NO);
-        }
-    }
-    /**
-     * Handle bluetooth connection directive coming from AACS.
-     *
-     * @param device BT device.
-     */
-
-    public void handleBTConnectionCommand(@NonNull BTDevice device, String connectedState) {
-        if (connectedState.equals(Constants.BT_CONNECTED)) {
-            mBTDeviceRepository.insertEntry(device);
-            mConnectedBTDeviceRepository.insertEntry(device);
-            mBTDeviceRepository.shouldRequestContactsConsent(device);
-        } else {
-            // Device is disconnected, it needs to be removed from connected device database, when found, the remove
-            // action will be triggered.
-            mConnectedBTDeviceRepository.findConnectedBTDeviceEntry(device);
-        }
-    }
-
-    public void handlePrimaryPhoneChangedCommand(String deviceAddress) {
-        if (deviceAddress != null && !deviceAddress.isEmpty()) {
-            mConnectedBTDeviceRepository.setConnectedDeviceToPrimary(deviceAddress);
-        }
-    }
-
-    public void insertPairedDevice(@NonNull BTDevice device) {
-        mBTDeviceRepository.insertEntry(device);
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/receiver/BluetoothReceiver.java b/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/receiver/BluetoothReceiver.java
deleted file mode 100644
index 2a7979a59..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/java/com/amazon/alexa/auto/comms/ui/receiver/BluetoothReceiver.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *     http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.amazon.alexa.auto.comms.ui.receiver;
-
-import static com.amazon.alexa.auto.comms.ui.Constants.AACS_BT_CONNECTION_CHECK_COMPLETED;
-import static com.amazon.alexa.auto.comms.ui.Constants.ALEXA_AUTO_COMMS_PRIMARY_PHONE_CHANGED;
-
-import android.bluetooth.BluetoothAdapter;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.telecom.PhoneAccount;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.amazon.alexa.auto.comms.ui.Constants;
-import com.amazon.alexa.auto.comms.ui.db.BTDevice;
-import com.amazon.alexa.auto.comms.ui.dependencies.AndroidModule;
-import com.amazon.alexa.auto.comms.ui.dependencies.DaggerCommunicationComponent;
-import com.amazon.alexa.auto.comms.ui.handler.BluetoothDirectiveHandler;
-
-import javax.inject.Inject;
-
-/**
- * Receiver that gets Android telephony bluetooth directives.
- */
-public class BluetoothReceiver extends BroadcastReceiver {
-    private static final String TAG = BluetoothReceiver.class.getSimpleName();
-
-    @VisibleForTesting
-    BTDevice mBTDevice = new BTDevice();
-
-    @Inject
-    BluetoothDirectiveHandler mBluetoothDirectiveHandler;
-
-    @Inject
-    TelecomManager mTelecomManager;
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (mBluetoothDirectiveHandler == null) {
-            Log.i(TAG, this + " | first onReceive so doing injection");
-            DaggerCommunicationComponent.builder()
-                    .androidModule(new AndroidModule(context))
-                    .build()
-                    .injectBluetoothReceiver(this);
-        }
-
-        if (intent.getAction() != null && Constants.ACTION_PAIRED_DEVICE.equals(intent.getAction())) {
-            Log.d(TAG, "receiving paired device on initial connection check");
-            mBTDevice.setDeviceName(intent.getExtras().getString(Constants.AACS_BT_DEVICE_NAME, ""));
-            mBTDevice.setDeviceAddress(intent.getExtras().getString(Constants.AACS_BT_DEVICE_ADDRESS, ""));
-            mBluetoothDirectiveHandler.insertPairedDevice(mBTDevice);
-            return;
-        }
-
-        if (intent.getAction() != null && Constants.AACS_BT_BOND_STATE_CHANGED.equals(intent.getAction())) {
-            Log.d(TAG, "intent bond state: " + intent.getExtras().getInt("bondState", -1));
-            Integer bondState = intent.getExtras().getInt("bondState", -1);
-            mBTDevice.setDeviceAddress(intent.getExtras().getString(Constants.AACS_BT_DEVICE_ADDRESS, ""));
-            mBTDevice.setDeviceName(intent.getExtras().getString(Constants.AACS_BT_DEVICE_NAME, ""));
-            mBluetoothDirectiveHandler.handleBondStateChange(mBTDevice, bondState);
-            return;
-        }
-
-        if (intent.getAction() != null
-                && (intent.getAction().equals(AACS_BT_CONNECTION_CHECK_COMPLETED)
-                        || intent.getAction().equals(ALEXA_AUTO_COMMS_PRIMARY_PHONE_CHANGED))) {
-            mBluetoothDirectiveHandler.handlePrimaryPhoneChangedCommand(getPrimaryDevice());
-            return;
-        }
-
-        if (intent.getAction() != null && intent.getExtras() != null) {
-            mBTDevice.setDeviceAddress(intent.getExtras().getString(Constants.AACS_BT_DEVICE_ADDRESS, ""));
-            mBTDevice.setDeviceName(intent.getExtras().getString(Constants.AACS_BT_DEVICE_NAME, ""));
-
-            String connectionState;
-            if (intent.getAction().equals(Constants.AACS_BT_CONNECTED)) {
-                connectionState = Constants.BT_CONNECTED;
-            } else {
-                connectionState = Constants.BT_DISCONNECTED;
-            }
-            mBluetoothDirectiveHandler.handleBTConnectionCommand(mBTDevice, connectionState);
-        }
-    }
-
-    public String getPrimaryDevice() {
-        String deviceAddress = "";
-        if (mTelecomManager != null) {
-            PhoneAccountHandle handle = mTelecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
-            if (handle != null) {
-                deviceAddress = handle.getId();
-            }
-        }
-        if (deviceAddress.isEmpty() || !BluetoothAdapter.checkBluetoothAddress(deviceAddress)) {
-            Log.e(TAG, "cannot find any valid primary device.");
-            return null;
-        }
-        return deviceAddress;
-    }
-}
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/comms_illustration.png b/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/comms_illustration.png
deleted file mode 100644
index ce21750c0..000000000
Binary files a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/comms_illustration.png and /dev/null differ
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/ic_arrow_right.xml b/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/ic_arrow_right.xml
deleted file mode 100644
index d3d62595e..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/ic_arrow_right.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-  
-
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/ic_dialog_box_red.xml b/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/ic_dialog_box_red.xml
deleted file mode 100644
index 9279beaa4..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/drawable/ic_dialog_box_red.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-  
-
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_preference_layout.xml b/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_preference_layout.xml
deleted file mode 100644
index bf2a336de..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_preference_layout.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-    
-
-
-    
-
-    
-
-    
-        
-    
-
-    
-
-
-
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_preference_layout_bottom.xml b/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_preference_layout_bottom.xml
deleted file mode 100644
index 727efc0ef..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_preference_layout_bottom.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-    
-
-
-    
-
-    
-
-    
-        
-    
-
-
-
diff --git a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_settings_fragment.xml b/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_settings_fragment.xml
deleted file mode 100644
index df56b618a..000000000
--- a/aacs/android/app-components/alexa-auto-comms-ui/src/main/res/layout-port/communication_settings_fragment.xml
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
-    
-
-    
-
-
-
-    
-
-        
-
-
-            
-
-            
-
-
-            
-
-
-