1 /* 2 * Copyright 2021 HIMSA II K/S - www.himsa.com. 3 * Represented by EHIMA - www.ehima.com. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.bluetooth.mcp; 19 20 import static java.util.Map.entry; 21 22 import java.util.Map; 23 24 /** 25 * Media control request, from client to Media Player 26 */ 27 public final class Request { 28 private final int mOpcode; 29 private final Integer mIntArg; 30 31 /** 32 * Media control request constructor 33 * 34 * @param opcode Control request opcode 35 * @param arg Control request argument 36 */ Request(int opcode, int arg)37 public Request(int opcode, int arg) { 38 this.mOpcode = opcode; 39 this.mIntArg = arg; 40 } 41 42 /** 43 * Media control results opcode getter 44 * 45 * @return Control request opcode 46 */ getOpcode()47 public int getOpcode() { 48 return mOpcode; 49 } 50 51 /** 52 * Media control results argument getter 53 * 54 * @return Control request argument 55 */ getIntArg()56 public int getIntArg() { 57 return mIntArg; 58 } 59 60 /** 61 * Media control request results definition 62 */ 63 public enum Results { 64 SUCCESS(0x01), 65 OPCODE_NOT_SUPPORTED(0x02), 66 MEDIA_PLAYER_INACTIVE(0x03), 67 COMMAND_CANNOT_BE_COMPLETED(0x04); 68 69 private final int mValue; 70 Results(int value)71 Results(int value) { 72 mValue = value; 73 } 74 getValue()75 public int getValue() { 76 return mValue; 77 } 78 } 79 80 /** 81 * Media control request supported opcodes definition 82 */ 83 public final static class SupportedOpcodes { 84 public static final int NONE = 0x00; 85 public static final int PLAY = 0x01; 86 public static final int PAUSE = 0x02; 87 public static final int FAST_REWIND = 0x04; 88 public static final int FAST_FORWARD = 0x08; 89 public static final int STOP = 0x10; 90 public static final int MOVE_RELATIVE = 0x20; 91 public static final int PREVIOUS_SEGMENT = 0x40; 92 public static final int NEXT_SEGMENT = 0x80; 93 public static final int FIRST_SEGMENT = 0x0100; 94 public static final int LAST_SEGMENT = 0x0200; 95 public static final int GOTO_SEGMENT = 0x0400; 96 public static final int PREVIOUS_TRACK = 0x0800; 97 public static final int NEXT_TRACK = 0x1000; 98 public static final int FIRST_TRACK = 0x2000; 99 public static final int LAST_TRACK = 0x4000; 100 public static final int GOTO_TRACK = 0x8000; 101 public static final int PREVIOUS_GROUP = 0x010000; 102 public static final int NEXT_GROUP = 0x020000; 103 public static final int FIRST_GROUP = 0x040000; 104 public static final int LAST_GROUP = 0x080000; 105 public static final int GOTO_GROUP = 0x100000; 106 } 107 108 /** 109 * Media control request opcodes definition 110 */ 111 public final static class Opcodes { 112 public static final int PLAY = 0x01; 113 public static final int PAUSE = 0x02; 114 public static final int FAST_REWIND = 0x03; 115 public static final int FAST_FORWARD = 0x04; 116 public static final int STOP = 0x05; 117 public static final int MOVE_RELATIVE = 0x10; 118 public static final int PREVIOUS_SEGMENT = 0x20; 119 public static final int NEXT_SEGMENT = 0x21; 120 public static final int FIRST_SEGMENT = 0x22; 121 public static final int LAST_SEGMENT = 0x23; 122 public static final int GOTO_SEGMENT = 0x24; 123 public static final int PREVIOUS_TRACK = 0x30; 124 public static final int NEXT_TRACK = 0x31; 125 public static final int FIRST_TRACK = 0x32; 126 public static final int LAST_TRACK = 0x33; 127 public static final int GOTO_TRACK = 0x34; 128 public static final int PREVIOUS_GROUP = 0x40; 129 public static final int NEXT_GROUP = 0x41; 130 public static final int FIRST_GROUP = 0x42; 131 public static final int LAST_GROUP = 0x43; 132 public static final int GOTO_GROUP = 0x44; 133 toString(int opcode)134 static String toString(int opcode) { 135 switch(opcode) { 136 case 0x01: 137 return "PLAY(0x01)"; 138 case 0x02: 139 return "PAUSE(0x02)"; 140 case 0x03: 141 return "FAST_REWIND(0x03)"; 142 case 0x04: 143 return "FAST_FORWARD(0x04)"; 144 case 0x05: 145 return "STOP(0x05)"; 146 case 0x10: 147 return "MOVE_RELATIVE(0x10)"; 148 case 0x20: 149 return "PREVIOUS_SEGMENT(0x20)"; 150 case 0x21: 151 return "NEXT_SEGMENT(0x21)"; 152 case 0x22: 153 return "FIRST_SEGMENT(0x22)"; 154 case 0x23: 155 return "LAST_SEGMENT(0x23)"; 156 case 0x24: 157 return "GOTO_SEGMENT(0x24)"; 158 case 0x30: 159 return "PREVIOUS_TRACK(0x30)"; 160 case 0x31: 161 return "NEXT_TRACK(0x31)"; 162 case 0x32: 163 return "FIRST_TRACK(0x32)"; 164 case 0x33: 165 return "LAST_TRACK(0x33)"; 166 case 0x34: 167 return "GOTO_TRACK(0x34)"; 168 case 0x40: 169 return "PREVIOUS_GROUP(0x40)"; 170 case 0x41: 171 return "NEXT_GROUP(0x41)"; 172 case 0x42: 173 return "FIRST_GROUP(0x42)"; 174 case 0x43: 175 return "LAST_GROUP(0x43)"; 176 case 0x44: 177 return "GOTO_GROUP(0x44)"; 178 default: 179 return "UNKNOWN(0x" + Integer.toHexString(opcode) + ")"; 180 } 181 } 182 } 183 184 /* Map opcodes which are written to 'Media Control Point' characteristics to their corresponding 185 * feature bit masks used in 'Media Control Point Opcodes Supported' characteristic. 186 */ 187 public final static Map<Integer, Integer> OpcodeToOpcodeSupport = Map.ofEntries( 188 entry(Opcodes.PLAY, SupportedOpcodes.PLAY), 189 entry(Opcodes.PAUSE, SupportedOpcodes.PAUSE), 190 entry(Opcodes.FAST_REWIND, SupportedOpcodes.FAST_REWIND), 191 entry(Opcodes.FAST_FORWARD, SupportedOpcodes.FAST_FORWARD), 192 entry(Opcodes.STOP, SupportedOpcodes.STOP), 193 entry(Opcodes.MOVE_RELATIVE, SupportedOpcodes.MOVE_RELATIVE), 194 entry(Opcodes.PREVIOUS_SEGMENT, SupportedOpcodes.PREVIOUS_SEGMENT), 195 entry(Opcodes.NEXT_SEGMENT, SupportedOpcodes.NEXT_SEGMENT), 196 entry(Opcodes.FIRST_SEGMENT, SupportedOpcodes.FIRST_SEGMENT), 197 entry(Opcodes.LAST_SEGMENT, SupportedOpcodes.LAST_SEGMENT), 198 entry(Opcodes.GOTO_SEGMENT, SupportedOpcodes.GOTO_SEGMENT), 199 entry(Opcodes.PREVIOUS_TRACK, SupportedOpcodes.PREVIOUS_TRACK), 200 entry(Opcodes.NEXT_TRACK, SupportedOpcodes.NEXT_TRACK), 201 entry(Opcodes.FIRST_TRACK, SupportedOpcodes.FIRST_TRACK), 202 entry(Opcodes.LAST_TRACK, SupportedOpcodes.LAST_TRACK), 203 entry(Opcodes.GOTO_TRACK, SupportedOpcodes.GOTO_TRACK), 204 entry(Opcodes.PREVIOUS_GROUP, SupportedOpcodes.PREVIOUS_GROUP), 205 entry(Opcodes.NEXT_GROUP, SupportedOpcodes.NEXT_GROUP), 206 entry(Opcodes.FIRST_GROUP, SupportedOpcodes.FIRST_GROUP), 207 entry(Opcodes.LAST_GROUP, SupportedOpcodes.LAST_GROUP), 208 entry(Opcodes.GOTO_GROUP, SupportedOpcodes.GOTO_GROUP)); 209 210 } 211