Skip to content

Instantly share code, notes, and snippets.

@SayantanRC
Last active February 22, 2021 14:53
Show Gist options
  • Save SayantanRC/1ae3f93147dbfd405be79acfeeafad2e to your computer and use it in GitHub Desktop.
Save SayantanRC/1ae3f93147dbfd405be79acfeeafad2e to your computer and use it in GitHub Desktop.
Constants for Power Menu Controls API
class CustomControlsConstants {
companion object {
// gist url: https://gist.github.com/SayantanRC/1ae3f93147dbfd405be79acfeeafad2e
/** Input fields i.e data expected from the caller app to create the control:
* SECTION 1 to SECTION 3
*/
/** Output fields i.e data sent back to the caller app by this app:
* SECTION 4 onwards.
*/
// Input fields
// SECTION 1.1 - Intent Definition
// ============================================================
/**
* Action to be mentioned in the Intent from caller app, to request this app to create and
* add a custom power-menu control from the caller app.
*/
val PMC_CONTROL_DEFINITION_ACTION = "balti.powermenu.shortcuts.SendControlDefinition"
/** Package name of this app */
val PMC_PACKAGE_NAME = "balti.powermenu.shortcuts"
/**
* The caller app must mention the following in the manifest:
<uses-permission android:name="balti.powermenu.shortcuts.AddControls"/>
*
* An intent to create a control can be created as below:
val sendIntent = Intent(PMC_CONTROL_DEFINITION_ACTION).apply {
// mandatory input fields
putExtra(CONTROL_TYPE, TYPE_APPLICATION_LAUNCH)
putExtra(SHORTCUT_TITLE, "My title")
putExtra(SHORTCUT_DESCRIPTION, "My description")
// other input fields
// ...
}
* Refer the following sections to check the mandatory input fields for each [CONTROL_TYPE]
*/
// ============================================================
// SECTION 1.2
// mandatory input fields =====================================
/** Please refer SECTION 5.2 to understand which type to use in [CONTROL_TYPE] */
val CONTROL_TYPE = "controlType"
val SHORTCUT_TITLE = "shortcutTitle"
val SHORTCUT_DESCRIPTION = "shortcutDescription"
// ============================================================
// SECTION 1.2.1
/** These are complusory fields to be mentioned for the [CONTROL_TYPE] = [TYPE_RANGE]
* Please refer SECTION 5.2 for more info on [TYPE_RANGE].
* Not required for any other type of control
* */
val MIN_RANGE = "minRange"
val MAX_RANGE = "maxRange"
// ============================================================
// SECTION 1.3
// optional fields ============================================
/**
* Custom icon for an control is not necessary.
* If nothing is specified, for control types [TYPE_ACTIVITY_LAUNCH] and [TYPE_APPLICATION_LAUNCH]
* the default icon of the package mentioned in [LAUNCH_PACKAGE_NAME] is used.
* If any other type of control type is used, by default the app icon of the caller app is used.
* A custom icon can be specified by passing a 'content' uri of a file in this field.
* Please make sure that you grant permission to the file by using:
* grantUriPermission(pmcPackage, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
* where pmcPackage = [PMC_PACKAGE_NAME],
* 'uri' is the content uri fo the file, say from [androidx.core.content.FileProvider.getUriForFile]
*/
val CUSTOM_ICON = "customIcon"
/**
* Optional for [CONTROL_TYPE] = [TYPE_APPLICATION_LAUNCH], [TYPE_ACTIVITY_LAUNCH]
* MANDATORY for all other types. Please refer SECTION 5 onwards for callback related info.
*/
val CALLBACK_RECEIVER_ACTION = "callbackReceiverAction" // broadcast receiver action in caller
// ============================================================
// SECTION 2 - Application / activity launch
// Input fields for launching apps / activities =====================
/** Definition for activity / application to launch when [CONTROL_TYPE] = [TYPE_APPLICATION_LAUNCH] or [TYPE_ACTIVITY_LAUNCH]
* For [TYPE_APPLICATION_LAUNCH], only [LAUNCH_PACKAGE_NAME] is mandatory. All other field values are not considered.
* For [TYPE_ACTIVITY_LAUNCH], the field [LAUNCH_PACKAGE_NAME] is still mandatory, but all other fields are also considered.
*/
val LAUNCH_PACKAGE_NAME = "launchPackageName"
val ACTIVITY_ACTION = "activityAction" // example: android.intent.action.VIEW
val ACTIVITY_CLASS_NAME = "activityClassName"
val ACTIVITY_DATA = "activityData"
val ACTIVITY_MIME_TYPE = "activityMimeType"
val ACTIVITY_EXTRAS = "activityExtras" // comma separated {key1:value1},{key2:value2}... pairs
// Example: {"Name":"Abc"},{"Age":22}
val ACTIVITY_FLAGS = "activityFlags" // comma separated values
val ACTIVITY_CATEGORIES = "activityCategories" // comma separated values
// ============================================================
// SECTION 3 - Activity to launch in long press
// Input fields for long pressing controls ==========================
/**
* Definition for activity to launch on lang pressing the power-menu control.
* All the fields are optional.
*
* By default, for control type [TYPE_APPLICATION_LAUNCH] and [TYPE_ACTIVITY_LAUNCH],
* long pressing would start the launcher activity for the package mentioned in [LAUNCH_PACKAGE_NAME]
*
* For other types, by default, long pressing would start the launcher activity of the caller app.
*
* If callback is applicable
* [CONTROL_ID] = Same Integer ID generated by this app while creating the toggle.
* [CONTROL_ACTION] = [USER_ACTION_LONG_PRESS]
* [CONTROL_TYPE] = same as originally mentioned by the caller app.
*/
val LONG_PRESS_LAUNCH_PACKAGE_NAME = "longPressLaunchPackageName"
val LONG_PRESS_ACTIVITY_ACTION = "longPressActivityAction"
val LONG_PRESS_ACTIVITY_CLASS_NAME = "longPressActivityClassName"
val LONG_PRESS_ACTIVITY_DATA = "longPressActivityData"
val LONG_PRESS_ACTIVITY_MIME_TYPE = "longPressActivityMimeType"
val LONG_PRESS_ACTIVITY_EXTRAS = "longPressActivityExtras"
val LONG_PRESS_ACTIVITY_FLAGS = "longPressActivityFlags"
val LONG_PRESS_ACTIVITY_CATEGORIES = "longPressActivityCategories"
// ============================================================
// Output fields
// SECTION 4 - values returned to onActivityResult() after calling startActivityForResult()
// ===========================================================
/**
* The following fields will be returned in onActivityResult()'s 'data' intent variable,
* after the user chooses to ALLOW or DENY the caller app's power-menu control.
*/
/**
* If the requested control from the caller app is not added, this field contains the rejection reason
* Please refer the last SECTION REJECTION for various reasons.
*/
val REJECTION_REASON = "rejectionReason"
/**
* A Unique integer ID generated to refer to this newly created control.
* You need to store this ID in your app. All further callbacks will include this ID.
* This ID can be also used to request an update to the control element created here.
*/
val CONTROL_ID = "controlId"
// ============================================================
// SECTION 5 - Callbacks
// mandatory callback fields ==================================
/**
* Denotes the action taken by the user on the control.
* May also denote other actions like the user removed your control from the power menu. [ACTION_TOGGLE_REMOVED]
* Or it can also denote acknowledgement to your request of updating the toggle. [ACTION_TOGGLE_UPDATE_ACKNOWLEDGE]
* Please refer SECTION 5.1
*/
val CONTROL_ACTION = "controlAction"
/** The fields: [CONTROL_TYPE] and [CONTROL_ID] are also returned.
* These 3 fields mentioned here are returned no matter what the CONTROL_TYPE is.
* There maybe other additional fields depending on the type.
* Please refer SECTION 5.2 for all control types.
*/
// ============================================================
// SECTION 5.1 - CONTROL_ACTION values
// =============================================================
/** Values for the field [CONTROL_ACTION] */
val ACTION_TOGGLE_REMOVED = "actionToggleRemoved"
val ACTION_TOGGLE_UPDATE_ACKNOWLEDGE = "actionToggleUpdateAcknowledge"
/**
* Values for the field [CONTROL_ACTION] when a user interacts with the control
*/
/** Delivered for [CONTROL_TYPE] = [TYPE_ACTIVITY_LAUNCH], [TYPE_APPLICATION_LAUNCH], [TYPE_STATELESS] */
val USER_ACTION_CLICK = "userActionClick"
/** Delivered for [CONTROL_TYPE] = [TYPE_TOGGLE]*/
val USER_ACTION_TOGGLE = "userActionToggle"
/** Delivered for [CONTROL_TYPE] = [TYPE_RANGE]*/
val USER_ACTION_SLIDE = "userActionSlide"
/** Delivered when user long presses a control. Please refer SECTION 3 for long-press related info */
val USER_ACTION_LONG_PRESS = "userActionLongPress"
// ============================================================
// SECTION 5.2 - Control types
// CONTROL_TYPE values ========================================
/**
* Launch an application from [LAUNCH_PACKAGE_NAME] (MANDATORY)
*
* Callback provided if [CALLBACK_RECEIVER_ACTION] is mentioned.
*
* Callback (if applicable) contains:
* [CONTROL_ID] = Integer ID generated by this app.
* [CONTROL_ACTION] = [USER_ACTION_CLICK],
* [CONTROL_TYPE] = [TYPE_APPLICATION_LAUNCH]
*/
val TYPE_APPLICATION_LAUNCH = "typeApplicationLaunch"
/**
* Launch an activity.
* Requires an activity from [LAUNCH_PACKAGE_NAME] (MANDATORY)
* Optionally requires fields mentioned in SECTION 3.
*
* Callback provided if [CALLBACK_RECEIVER_ACTION] is mentioned.
*
* Callback (if applicable) contains:
* [CONTROL_ID] = Integer ID generated by this app.
* [CONTROL_ACTION] = [USER_ACTION_CLICK],
* [CONTROL_TYPE] = [TYPE_ACTIVITY_LAUNCH]
*/
val TYPE_ACTIVITY_LAUNCH = "typeActivityLaunch"
/**
* A true / false type control button.
* Callback done using the action provided in [CALLBACK_RECEIVER_ACTION] (MANDATORY)
*
* Callback contains:
* [CONTROL_ID] = Integer ID generated by this app.
* [CONTROL_ACTION] = [USER_ACTION_TOGGLE],
* [CONTROL_TYPE] = [TYPE_TOGGLE]
* [TOGGLE_STATE] = true or false
*/
val TYPE_TOGGLE = "typeToggle"
/**
* A slider control button.
* Requires the fields [MIN_RANGE], [MAX_RANGE] (MANDATORY)
* Callback done using the action provided in [CALLBACK_RECEIVER_ACTION] (MANDATORY)
*
* Callback contains:
* [CONTROL_ID] = Integer ID generated by this app.
* [CONTROL_ACTION] = [USER_ACTION_SLIDE],
* [CONTROL_TYPE] = [TYPE_RANGE]
* [RANGE_STATE] = a value between [MIN_RANGE] and [MAX_RANGE]
*/
val TYPE_RANGE = "typeRange"
/**
* A stateless control button.
* Callback done using the action provided in [CALLBACK_RECEIVER_ACTION] (MANDATORY)
*
* Callback contains:
* [CONTROL_ID] = Integer ID generated by this app.
* [CONTROL_ACTION] = [USER_ACTION_CLICK],
* [CONTROL_TYPE] = [TYPE_STATELESS]
*/
val TYPE_STATELESS = "typeStateless"
// ============================================================
// SECTION 5.3
// fields for special type control =============================
val TOGGLE_STATE = "toggleState" // true or false
val RANGE_STATE = "rangeState" /** a value in between [MIN_RANGE] and [MAX_RANGE] */
// ============================================================
// SECTION REJECTION
val ERR_UNDEFINED = "Undefined error"
val ERR_USER_REJECTED = "User rejected to add control."
val ERR_NO_CALLER_PACKAGE = "No caller package found. Use `startActivityForResult()` to request a control."
val ERR_IMPROPER_CONTROL_TYPE = "Control type not specified. Please refer to the API to check options."
val ERR_IMPROPER_TITLE = "Control title not specified. Use '$SHORTCUT_TITLE' to specify a string title."
val ERR_NO_LAUNCH_PACKAGE = "Package name to launch not provided or is blank. Use '$LAUNCH_PACKAGE_NAME' to provide package name."
val ERR_NO_CALLBACK = "No action string is provided for callback class. Use '$CALLBACK_RECEIVER_ACTION' to provide the action string."
val ERR_IMPROPER_RANGE = "Please provide positive values for '$MIN_RANGE' and '$MAX_RANGE'. Also make sure the values for '$MAX_RANGE' > '$MIN_RANGE'."
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment