@capgo/capacitor-media-session 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CapgoMediaSession.podspec +17 -0
  2. package/Package.swift +28 -0
  3. package/README.md +164 -0
  4. package/android/build.gradle +60 -0
  5. package/android/src/main/AndroidManifest.xml +26 -0
  6. package/android/src/main/java/com/capgo/mediasession/MediaSessionCallback.java +55 -0
  7. package/android/src/main/java/com/capgo/mediasession/MediaSessionPlugin.java +277 -0
  8. package/android/src/main/java/com/capgo/mediasession/MediaSessionService.java +366 -0
  9. package/android/src/main/res/.gitkeep +0 -0
  10. package/android/src/main/res/drawable/ic_baseline_forward_30_24.xml +16 -0
  11. package/android/src/main/res/drawable/ic_baseline_pause_24.xml +10 -0
  12. package/android/src/main/res/drawable/ic_baseline_play_arrow_24.xml +10 -0
  13. package/android/src/main/res/drawable/ic_baseline_replay_30_24.xml +16 -0
  14. package/android/src/main/res/drawable/ic_baseline_skip_next_24.xml +10 -0
  15. package/android/src/main/res/drawable/ic_baseline_skip_previous_24.xml +10 -0
  16. package/android/src/main/res/drawable/ic_baseline_stop_24.xml +10 -0
  17. package/android/src/main/res/drawable/ic_baseline_volume_up_24.xml +10 -0
  18. package/dist/docs.json +326 -0
  19. package/dist/esm/definitions.d.ts +48 -0
  20. package/dist/esm/definitions.js +2 -0
  21. package/dist/esm/definitions.js.map +1 -0
  22. package/dist/esm/index.d.ts +4 -0
  23. package/dist/esm/index.js +8 -0
  24. package/dist/esm/index.js.map +1 -0
  25. package/dist/esm/web.d.ts +8 -0
  26. package/dist/esm/web.js +38 -0
  27. package/dist/esm/web.js.map +1 -0
  28. package/dist/plugin.cjs.js +53 -0
  29. package/dist/plugin.cjs.js.map +1 -0
  30. package/dist/plugin.js +56 -0
  31. package/dist/plugin.js.map +1 -0
  32. package/ios/Sources/MediaSessionPlugin/MediaSessionPlugin.swift +9 -0
  33. package/ios/Tests/MediaSessionPluginTests/MediaSessionPluginTests.swift +15 -0
  34. package/package.json +83 -0
@@ -0,0 +1,366 @@
1
+ package com.capgo.mediasession;
2
+
3
+ import android.annotation.SuppressLint;
4
+ import android.app.NotificationChannel;
5
+ import android.app.NotificationManager;
6
+ import android.app.PendingIntent;
7
+ import android.app.Service;
8
+ import android.content.Intent;
9
+ import android.content.pm.ServiceInfo;
10
+ import android.graphics.Bitmap;
11
+ import android.os.Binder;
12
+ import android.os.Build;
13
+ import android.os.IBinder;
14
+ import android.support.v4.media.MediaMetadataCompat;
15
+ import android.support.v4.media.session.MediaSessionCompat;
16
+ import android.support.v4.media.session.PlaybackStateCompat;
17
+ import android.util.Log;
18
+ import androidx.core.app.NotificationCompat;
19
+ import androidx.media.app.NotificationCompat.MediaStyle;
20
+ import androidx.media.session.MediaButtonReceiver;
21
+ import java.util.Arrays;
22
+ import java.util.HashMap;
23
+ import java.util.HashSet;
24
+ import java.util.Map;
25
+ import java.util.Set;
26
+
27
+ public class MediaSessionService extends Service {
28
+
29
+ private static final String TAG = "MediaSessionService";
30
+ private static final String CHANNEL_ID = "playback";
31
+ private static final int NOTIFICATION_ID = 1;
32
+
33
+ private MediaSessionCompat mediaSession;
34
+ private PlaybackStateCompat.Builder playbackStateBuilder;
35
+ private MediaMetadataCompat.Builder mediaMetadataBuilder;
36
+ private NotificationManager notificationManager;
37
+ private NotificationCompat.Builder notificationBuilder;
38
+ private MediaStyle notificationStyle;
39
+
40
+ private final Map<String, NotificationCompat.Action> notificationActions = new HashMap<>();
41
+ private final Map<String, Long> playbackStateActions = new HashMap<>();
42
+ private final String[] possibleActions = {
43
+ "previoustrack",
44
+ "seekbackward",
45
+ "play",
46
+ "pause",
47
+ "seekforward",
48
+ "nexttrack",
49
+ "seekto",
50
+ "stop"
51
+ };
52
+ private final Set<String> possibleCompactViewActions = new HashSet<>(
53
+ Arrays.asList("previoustrack", "play", "pause", "nexttrack", "stop")
54
+ );
55
+
56
+ private int playbackState = PlaybackStateCompat.STATE_NONE;
57
+ private String title = "";
58
+ private String artist = "";
59
+ private String album = "";
60
+ private Bitmap artwork;
61
+ private long duration = 0;
62
+ private long position = 0;
63
+ private float playbackSpeed = 1.0F;
64
+
65
+ private boolean possibleActionsUpdate = true;
66
+ private boolean playbackStateUpdate = false;
67
+ private boolean mediaMetadataUpdate = false;
68
+ private boolean notificationUpdate = false;
69
+
70
+ private MediaSessionPlugin plugin;
71
+
72
+ private final IBinder binder = new LocalBinder();
73
+
74
+ public final class LocalBinder extends Binder {
75
+
76
+ MediaSessionService getService() {
77
+ return MediaSessionService.this;
78
+ }
79
+ }
80
+
81
+ @Override
82
+ public IBinder onBind(Intent intent) {
83
+ return binder;
84
+ }
85
+
86
+ @Override
87
+ public boolean onUnbind(Intent intent) {
88
+ destroy();
89
+ return super.onUnbind(intent);
90
+ }
91
+
92
+ public void connectAndInitialize(MediaSessionPlugin plugin, Intent intent) {
93
+ this.plugin = plugin;
94
+
95
+ mediaSession = new MediaSessionCompat(this, "CapgoMediaSession");
96
+ mediaSession.setCallback(new MediaSessionCallback(plugin));
97
+ mediaSession.setActive(true);
98
+
99
+ playbackStateBuilder = new PlaybackStateCompat.Builder()
100
+ .setActions(PlaybackStateCompat.ACTION_PLAY)
101
+ .setState(PlaybackStateCompat.STATE_PAUSED, position, playbackSpeed);
102
+ mediaSession.setPlaybackState(playbackStateBuilder.build());
103
+
104
+ mediaMetadataBuilder = new MediaMetadataCompat.Builder().putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration);
105
+ mediaSession.setMetadata(mediaMetadataBuilder.build());
106
+
107
+ notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
108
+ if (notificationManager == null) {
109
+ Log.w(TAG, "Notification manager unavailable");
110
+ return;
111
+ }
112
+
113
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
114
+ NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Playback", NotificationManager.IMPORTANCE_LOW);
115
+ notificationManager.createNotificationChannel(channel);
116
+ }
117
+
118
+ notificationStyle = new MediaStyle().setMediaSession(mediaSession.getSessionToken());
119
+ notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
120
+ .setStyle(notificationStyle)
121
+ .setSmallIcon(R.drawable.ic_baseline_volume_up_24)
122
+ .setContentIntent(
123
+ PendingIntent.getActivity(
124
+ getApplicationContext(),
125
+ 0,
126
+ intent,
127
+ PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
128
+ )
129
+ )
130
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
131
+
132
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
133
+ startForeground(NOTIFICATION_ID, notificationBuilder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
134
+ } else {
135
+ startForeground(NOTIFICATION_ID, notificationBuilder.build());
136
+ }
137
+
138
+ notificationActions.put(
139
+ "play",
140
+ new NotificationCompat.Action(
141
+ R.drawable.ic_baseline_play_arrow_24,
142
+ "Play",
143
+ MediaButtonReceiver.buildMediaButtonPendingIntent(
144
+ this,
145
+ PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PLAY
146
+ )
147
+ )
148
+ );
149
+ notificationActions.put(
150
+ "pause",
151
+ new NotificationCompat.Action(
152
+ R.drawable.ic_baseline_pause_24,
153
+ "Pause",
154
+ MediaButtonReceiver.buildMediaButtonPendingIntent(
155
+ this,
156
+ PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PAUSE
157
+ )
158
+ )
159
+ );
160
+ notificationActions.put(
161
+ "seekbackward",
162
+ new NotificationCompat.Action(
163
+ R.drawable.ic_baseline_replay_30_24,
164
+ "Seek backward",
165
+ MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_REWIND)
166
+ )
167
+ );
168
+ notificationActions.put(
169
+ "seekforward",
170
+ new NotificationCompat.Action(
171
+ R.drawable.ic_baseline_forward_30_24,
172
+ "Seek forward",
173
+ MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_FAST_FORWARD)
174
+ )
175
+ );
176
+ notificationActions.put(
177
+ "previoustrack",
178
+ new NotificationCompat.Action(
179
+ R.drawable.ic_baseline_skip_previous_24,
180
+ "Previous track",
181
+ MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)
182
+ )
183
+ );
184
+ notificationActions.put(
185
+ "nexttrack",
186
+ new NotificationCompat.Action(
187
+ R.drawable.ic_baseline_skip_next_24,
188
+ "Next track",
189
+ MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_SKIP_TO_NEXT)
190
+ )
191
+ );
192
+ notificationActions.put(
193
+ "stop",
194
+ new NotificationCompat.Action(
195
+ R.drawable.ic_baseline_stop_24,
196
+ "Stop",
197
+ MediaButtonReceiver.buildMediaButtonPendingIntent(this, PlaybackStateCompat.ACTION_STOP)
198
+ )
199
+ );
200
+
201
+ playbackStateActions.put("previoustrack", PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS);
202
+ playbackStateActions.put("seekbackward", PlaybackStateCompat.ACTION_REWIND);
203
+ playbackStateActions.put("play", PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PLAY);
204
+ playbackStateActions.put("pause", PlaybackStateCompat.ACTION_PLAY_PAUSE | PlaybackStateCompat.ACTION_PAUSE);
205
+ playbackStateActions.put("seekforward", PlaybackStateCompat.ACTION_FAST_FORWARD);
206
+ playbackStateActions.put("nexttrack", PlaybackStateCompat.ACTION_SKIP_TO_NEXT);
207
+ playbackStateActions.put("seekto", PlaybackStateCompat.ACTION_SEEK_TO);
208
+ playbackStateActions.put("stop", PlaybackStateCompat.ACTION_STOP);
209
+ }
210
+
211
+ public void destroy() {
212
+ stopForeground(true);
213
+ stopSelf();
214
+ }
215
+
216
+ @Override
217
+ public int onStartCommand(Intent intent, int flags, int startId) {
218
+ if (mediaSession != null) {
219
+ MediaButtonReceiver.handleIntent(mediaSession, intent);
220
+ }
221
+ return super.onStartCommand(intent, flags, startId);
222
+ }
223
+
224
+ public void setPlaybackState(int newPlaybackState) {
225
+ if (playbackState != newPlaybackState) {
226
+ playbackState = newPlaybackState;
227
+ playbackStateUpdate = true;
228
+ possibleActionsUpdate = true;
229
+ }
230
+ }
231
+
232
+ public void setTitle(String newTitle) {
233
+ if (!title.equals(newTitle)) {
234
+ title = newTitle != null ? newTitle : "";
235
+ mediaMetadataUpdate = true;
236
+ notificationUpdate = true;
237
+ }
238
+ }
239
+
240
+ public void setArtist(String newArtist) {
241
+ if (!artist.equals(newArtist)) {
242
+ artist = newArtist != null ? newArtist : "";
243
+ mediaMetadataUpdate = true;
244
+ notificationUpdate = true;
245
+ }
246
+ }
247
+
248
+ public void setAlbum(String newAlbum) {
249
+ if (!album.equals(newAlbum)) {
250
+ album = newAlbum != null ? newAlbum : "";
251
+ mediaMetadataUpdate = true;
252
+ notificationUpdate = true;
253
+ }
254
+ }
255
+
256
+ public void setArtwork(Bitmap newArtwork) {
257
+ artwork = newArtwork;
258
+ mediaMetadataUpdate = true;
259
+ notificationUpdate = true;
260
+ }
261
+
262
+ public void setDuration(long newDuration) {
263
+ if (duration != newDuration) {
264
+ duration = newDuration;
265
+ mediaMetadataUpdate = true;
266
+ notificationUpdate = true;
267
+ }
268
+ }
269
+
270
+ public void setPosition(long newPosition) {
271
+ if (position != newPosition) {
272
+ position = newPosition;
273
+ playbackStateUpdate = true;
274
+ }
275
+ }
276
+
277
+ public void setPlaybackSpeed(float newPlaybackSpeed) {
278
+ if (playbackSpeed != newPlaybackSpeed) {
279
+ playbackSpeed = newPlaybackSpeed;
280
+ playbackStateUpdate = true;
281
+ }
282
+ }
283
+
284
+ @SuppressLint("RestrictedApi")
285
+ public void update() {
286
+ if (possibleActionsUpdate) {
287
+ if (notificationBuilder != null) {
288
+ notificationBuilder.mActions.clear();
289
+ }
290
+
291
+ long activePlaybackStateActions = 0;
292
+ int[] activeCompactViewActionIndices = new int[3];
293
+ int notificationActionIndex = 0;
294
+ int compactNotificationActionIndicesIndex = 0;
295
+
296
+ for (String actionName : possibleActions) {
297
+ if (plugin != null && plugin.hasActionHandler(actionName)) {
298
+ if ("play".equals(actionName) && playbackState != PlaybackStateCompat.STATE_PAUSED) {
299
+ continue;
300
+ }
301
+ if ("pause".equals(actionName) && playbackState != PlaybackStateCompat.STATE_PLAYING) {
302
+ continue;
303
+ }
304
+
305
+ if (playbackStateActions.containsKey(actionName)) {
306
+ activePlaybackStateActions = activePlaybackStateActions | playbackStateActions.get(actionName);
307
+ }
308
+
309
+ if (notificationActions.containsKey(actionName) && notificationBuilder != null) {
310
+ notificationBuilder.addAction(notificationActions.get(actionName));
311
+ if (possibleCompactViewActions.contains(actionName) && compactNotificationActionIndicesIndex < 3) {
312
+ activeCompactViewActionIndices[compactNotificationActionIndicesIndex] = notificationActionIndex;
313
+ compactNotificationActionIndicesIndex++;
314
+ }
315
+ notificationActionIndex++;
316
+ }
317
+ }
318
+ }
319
+
320
+ if (playbackStateBuilder != null) {
321
+ playbackStateBuilder.setActions(activePlaybackStateActions);
322
+ }
323
+ if (notificationStyle != null) {
324
+ if (compactNotificationActionIndicesIndex > 0) {
325
+ notificationStyle.setShowActionsInCompactView(
326
+ Arrays.copyOfRange(activeCompactViewActionIndices, 0, compactNotificationActionIndicesIndex)
327
+ );
328
+ } else {
329
+ notificationStyle.setShowActionsInCompactView();
330
+ }
331
+ }
332
+
333
+ possibleActionsUpdate = false;
334
+ playbackStateUpdate = true;
335
+ notificationUpdate = true;
336
+ }
337
+
338
+ if (playbackStateUpdate && playbackStateBuilder != null) {
339
+ playbackStateBuilder.setState(playbackState, position, playbackSpeed);
340
+ mediaSession.setPlaybackState(playbackStateBuilder.build());
341
+ playbackStateUpdate = false;
342
+ }
343
+
344
+ if (mediaMetadataUpdate && mediaMetadataBuilder != null) {
345
+ mediaMetadataBuilder
346
+ .putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
347
+ .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
348
+ .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album)
349
+ .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, artwork)
350
+ .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration);
351
+ mediaSession.setMetadata(mediaMetadataBuilder.build());
352
+ mediaMetadataUpdate = false;
353
+ }
354
+
355
+ if (notificationUpdate && notificationBuilder != null && notificationManager != null) {
356
+ notificationBuilder.setContentTitle(title).setContentText(artist + " - " + album).setLargeIcon(artwork);
357
+ notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
358
+ notificationUpdate = false;
359
+ }
360
+ }
361
+
362
+ public void updatePossibleActions() {
363
+ possibleActionsUpdate = true;
364
+ update();
365
+ }
366
+ }
File without changes
@@ -0,0 +1,16 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:height="24dp"
3
+ android:tint="#000000"
4
+ android:viewportHeight="24"
5
+ android:viewportWidth="24"
6
+ android:width="24dp">
7
+ <path
8
+ android:fillColor="@android:color/white"
9
+ android:pathData="M18,13c0,3.31 -2.69,6 -6,6s-6,-2.69 -6,-6s2.69,-6 6,-6v4l5,-5l-5,-5v4c-4.42,0 -8,3.58 -8,8c0,4.42 3.58,8 8,8s8,-3.58 8,-8H18z" />
10
+ <path
11
+ android:fillColor="@android:color/white"
12
+ android:pathData="M10.06,15.38c-0.29,0 -0.62,-0.17 -0.62,-0.54H8.59c0,0.97 0.9,1.23 1.45,1.23c0.87,0 1.51,-0.46 1.51,-1.25c0,-0.66 -0.45,-0.9 -0.71,-1c0.11,-0.05 0.65,-0.32 0.65,-0.92c0,-0.21 -0.05,-1.22 -1.44,-1.22c-0.62,0 -1.4,0.35 -1.4,1.16h0.85c0,-0.34 0.31,-0.48 0.57,-0.48c0.59,0 0.58,0.5 0.58,0.54c0,0.52 -0.41,0.59 -0.63,0.59H9.56v0.66h0.45c0.65,0 0.7,0.42 0.7,0.64C10.71,15.11 10.5,15.38 10.06,15.38z" />
13
+ <path
14
+ android:fillColor="@android:color/white"
15
+ android:pathData="M13.85,11.68c-0.14,0 -1.44,-0.08 -1.44,1.82v0.74c0,1.9 1.31,1.82 1.44,1.82c0.14,0 1.44,0.09 1.44,-1.82V13.5C15.3,11.59 13.99,11.68 13.85,11.68zM14.45,14.35c0,0.77 -0.21,1.03 -0.59,1.03c-0.38,0 -0.6,-0.26 -0.6,-1.03v-0.97c0,-0.75 0.22,-1.01 0.59,-1.01c0.38,0 0.6,0.26 0.6,1.01V14.35z" />
16
+ </vector>
@@ -0,0 +1,10 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:height="24dp"
3
+ android:tint="#000000"
4
+ android:viewportHeight="24"
5
+ android:viewportWidth="24"
6
+ android:width="24dp">
7
+ <path
8
+ android:fillColor="@android:color/white"
9
+ android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z" />
10
+ </vector>
@@ -0,0 +1,10 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:height="24dp"
3
+ android:tint="#000000"
4
+ android:viewportHeight="24"
5
+ android:viewportWidth="24"
6
+ android:width="24dp">
7
+ <path
8
+ android:fillColor="@android:color/white"
9
+ android:pathData="M8,5v14l11,-7z" />
10
+ </vector>
@@ -0,0 +1,16 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:height="24dp"
3
+ android:tint="#000000"
4
+ android:viewportHeight="24"
5
+ android:viewportWidth="24"
6
+ android:width="24dp">
7
+ <path
8
+ android:fillColor="@android:color/white"
9
+ android:pathData="M12,5V1L7,6l5,5V7c3.31,0 6,2.69 6,6s-2.69,6 -6,6s-6,-2.69 -6,-6H4c0,4.42 3.58,8 8,8s8,-3.58 8,-8S16.42,5 12,5z" />
10
+ <path
11
+ android:fillColor="@android:color/white"
12
+ android:pathData="M9.56,13.49h0.45c0.21,0 0.37,-0.05 0.48,-0.16s0.16,-0.25 0.16,-0.43c0,-0.08 -0.01,-0.15 -0.04,-0.22s-0.06,-0.12 -0.11,-0.17s-0.11,-0.09 -0.18,-0.11s-0.16,-0.04 -0.25,-0.04c-0.08,0 -0.15,0.01 -0.22,0.03s-0.13,0.05 -0.18,0.1s-0.09,0.09 -0.12,0.15s-0.05,0.13 -0.05,0.2H8.65c0,-0.18 0.04,-0.34 0.11,-0.48s0.17,-0.27 0.3,-0.37s0.27,-0.18 0.44,-0.23s0.35,-0.08 0.54,-0.08c0.21,0 0.41,0.03 0.59,0.08s0.33,0.13 0.46,0.23s0.23,0.23 0.3,0.38s0.11,0.33 0.11,0.53c0,0.09 -0.01,0.18 -0.04,0.27s-0.07,0.17 -0.13,0.25s-0.12,0.15 -0.2,0.22s-0.17,0.12 -0.28,0.17c0.24,0.09 0.42,0.21 0.54,0.39s0.18,0.38 0.18,0.61c0,0.2 -0.04,0.38 -0.12,0.53s-0.18,0.29 -0.32,0.39s-0.29,0.19 -0.48,0.24s-0.38,0.08 -0.6,0.08c-0.18,0 -0.36,-0.02 -0.53,-0.07s-0.33,-0.12 -0.46,-0.23s-0.25,-0.23 -0.33,-0.38s-0.12,-0.34 -0.12,-0.55h0.85c0,0.08 0.02,0.15 0.05,0.22s0.07,0.12 0.13,0.17s0.12,0.09 0.2,0.11s0.16,0.04 0.25,0.04c0.1,0 0.19,-0.01 0.27,-0.04s0.15,-0.07 0.2,-0.12s0.1,-0.11 0.13,-0.18s0.04,-0.15 0.04,-0.24c0,-0.11 -0.02,-0.21 -0.05,-0.29s-0.08,-0.15 -0.14,-0.2s-0.13,-0.09 -0.22,-0.11s-0.18,-0.04 -0.29,-0.04H9.56V13.49z" />
13
+ <path
14
+ android:fillColor="@android:color/white"
15
+ android:pathData="M15.3,14.24c0,0.32 -0.03,0.6 -0.1,0.82s-0.17,0.42 -0.29,0.57s-0.28,0.26 -0.45,0.33s-0.37,0.1 -0.59,0.1s-0.41,-0.03 -0.59,-0.1s-0.33,-0.18 -0.46,-0.33s-0.23,-0.34 -0.3,-0.57s-0.11,-0.5 -0.11,-0.82V13.5c0,-0.32 0.03,-0.6 0.1,-0.82s0.17,-0.42 0.29,-0.57s0.28,-0.26 0.45,-0.33s0.37,-0.1 0.59,-0.1s0.41,0.03 0.59,0.1s0.33,0.18 0.46,0.33s0.23,0.34 0.3,0.57s0.11,0.5 0.11,0.82V14.24zM14.45,13.38c0,-0.19 -0.01,-0.35 -0.04,-0.48c-0.03,-0.13 -0.07,-0.23 -0.12,-0.31s-0.11,-0.14 -0.19,-0.17s-0.16,-0.05 -0.25,-0.05s-0.18,0.02 -0.25,0.05s-0.14,0.09 -0.19,0.17s-0.09,0.18 -0.12,0.31s-0.04,0.29 -0.04,0.48v0.97c0,0.19 0.01,0.35 0.04,0.48s0.07,0.24 0.12,0.32s0.11,0.14 0.19,0.17s0.16,0.05 0.25,0.05s0.18,-0.02 0.25,-0.05s0.14,-0.09 0.19,-0.17s0.09,-0.19 0.11,-0.32c0.03,-0.13 0.04,-0.29 0.04,-0.48V13.38z" />
16
+ </vector>
@@ -0,0 +1,10 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:height="24dp"
3
+ android:tint="#000000"
4
+ android:viewportHeight="24"
5
+ android:viewportWidth="24"
6
+ android:width="24dp">
7
+ <path
8
+ android:fillColor="@android:color/white"
9
+ android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z" />
10
+ </vector>
@@ -0,0 +1,10 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:height="24dp"
3
+ android:tint="#000000"
4
+ android:viewportHeight="24"
5
+ android:viewportWidth="24"
6
+ android:width="24dp">
7
+ <path
8
+ android:fillColor="@android:color/white"
9
+ android:pathData="M6,6h2v12L6,18zM9.5,12l8.5,6L18,6z" />
10
+ </vector>
@@ -0,0 +1,10 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:height="24dp"
3
+ android:tint="#000000"
4
+ android:viewportHeight="24"
5
+ android:viewportWidth="24"
6
+ android:width="24dp">
7
+ <path
8
+ android:fillColor="@android:color/white"
9
+ android:pathData="M6,6h12v12H6z" />
10
+ </vector>
@@ -0,0 +1,10 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:height="24dp"
3
+ android:tint="#000000"
4
+ android:viewportHeight="24"
5
+ android:viewportWidth="24"
6
+ android:width="24dp">
7
+ <path
8
+ android:fillColor="@android:color/white"
9
+ android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z" />
10
+ </vector>