1 00:00:04,530 --> 00:00:06,510 Alright so at the end of the last 2 00:00:06,510 --> 00:00:08,309 video, well actually the one before, not 3 00:00:08,309 --> 00:00:10,889 including the build update files, well 4 00:00:10,889 --> 00:00:12,599 actually the end of the video prior to 5 00:00:12,599 --> 00:00:14,280 that, because of course the last video I 6 00:00:14,280 --> 00:00:16,340 talked, I showed you how to actually update the 7 00:00:16,340 --> 00:00:19,290 Kotlin Runtime. But in that previous 8 00:00:19,290 --> 00:00:21,270 video we talked about, we were going to 9 00:00:21,270 --> 00:00:23,910 add the getId function to our Tasks 10 00:00:23,910 --> 00:00:25,890 Contract class, and obviously you can see 11 00:00:25,890 --> 00:00:27,269 here we've got an error there because 12 00:00:27,269 --> 00:00:28,740 that function doesn't exist at the 13 00:00:28,740 --> 00:00:30,420 moment. Now there's a few other things we 14 00:00:30,420 --> 00:00:32,369 need to do in there, so I'm going to do 15 00:00:32,369 --> 00:00:34,500 them all together. Now that we understand 16 00:00:34,500 --> 00:00:36,719 how URIs will be used, this should 17 00:00:36,719 --> 00:00:38,430 make more sense for you. So I'm going to 18 00:00:38,430 --> 00:00:41,840 start by opening up my TasksContract 19 00:00:41,840 --> 00:00:44,940 class, and you want to make sure that 20 00:00:44,940 --> 00:00:46,620 your cursor, when we start typing, is 21 00:00:46,620 --> 00:00:48,930 above the object Columns. Don't be typing 22 00:00:48,930 --> 00:00:50,129 in there because you'll get a weird error 23 00:00:50,129 --> 00:00:51,539 if you do that. So I'm going to put a 24 00:00:51,539 --> 00:00:52,920 comment here about what we're doing. 25 00:00:52,920 --> 00:00:55,590 We're creating a public constant here, of 26 00:00:55,590 --> 00:00:57,090 CONTENT_URI so that 27 00:00:57,090 --> 00:00:58,710 other classes will be able to use this 28 00:00:58,710 --> 00:01:02,489 URI for our Tasks table. So this is 29 00:01:02,489 --> 00:01:06,300 going to be "The URI to access the 30 00:01:06,300 --> 00:01:13,290 Tasks table". And in terms of the, what I'm 31 00:01:13,290 --> 00:01:15,869 typing here, we're going to type val and it's 32 00:01:15,869 --> 00:01:21,780 going to be CONTENT_URI: Uri 33 00:01:21,780 --> 00:01:26,330 is equal to Uri.with 34 00:01:26,330 --> 00:01:29,850 AppendedPath, in parentheses - we're going to 35 00:01:29,850 --> 00:01:30,900 ignore that error that appeared up 36 00:01:30,900 --> 00:01:32,460 before there with the IDE in the bottom 37 00:01:32,460 --> 00:01:34,320 right hand corner - CONTENT_ 38 00:01:34,320 --> 00:01:36,210 AUTHORITY_URI. There should have been 39 00:01:36,210 --> 00:01:38,130 a comma there, so TABLE_NAME. 40 00:01:38,130 --> 00:01:41,490 Okay, so the CONTENT__AUTHORITY 41 00:01:41,490 --> 00:01:43,950 _URI, that's coming 42 00:01:43,950 --> 00:01:46,439 from the AppProvider file. Now once 43 00:01:46,439 --> 00:01:47,700 again we didn't have to concatenate 44 00:01:47,700 --> 00:01:50,850 strings to create the CONTENT__URI from 45 00:01:50,850 --> 00:01:53,430 the CONTENT__AUTHORITY and our TABLE_NAME. 46 00:01:53,430 --> 00:01:55,860 The Uri class provides several 47 00:01:55,860 --> 00:01:57,720 methods for dealing with URIs. In 48 00:01:57,720 --> 00:02:00,600 here we're creating a new URI with a 49 00:02:00,600 --> 00:02:03,060 path appended, using the withAppended 50 00:02:03,060 --> 00:02:05,850 Path method from the Uri class. Now 51 00:02:05,850 --> 00:02:08,039 CONTENT_URI will be used 52 00:02:08,039 --> 00:02:11,008 by external classes, including different 53 00:02:11,008 --> 00:02:13,230 apps that use our content provider to 54 00:02:13,230 --> 00:02:16,440 refer to our Tasks table. Alright, so the 55 00:02:16,440 --> 00:02:17,819 other thing we decided to put in this 56 00:02:17,819 --> 00:02:18,300 class 57 00:02:18,300 --> 00:02:20,910 is the getId method. Now that will be 58 00:02:20,910 --> 00:02:24,330 used to extract the ID from a URI, and it 59 00:02:24,330 --> 00:02:25,620 also makes sense to include the 60 00:02:25,620 --> 00:02:28,230 complimentary method, buildUriFrom 61 00:02:28,230 --> 00:02:29,730 Id, to do the opposite. 62 00:02:29,730 --> 00:02:32,610 It'll add an ID to a CONTENT_ 63 00:02:32,610 --> 00:02:33,990 URI. So I'm going to add these 64 00:02:33,990 --> 00:02:36,090 functions we're about to write, below the 65 00:02:36,090 --> 00:02:37,800 definitions for the Columns object at 66 00:02:37,800 --> 00:02:41,490 the end of the class. So I'll start by fun get 67 00:02:41,490 --> 00:02:44,940 Id parentheses uri : 68 00:02:44,940 --> 00:02:46,830 Uri. Then a right parentheses 69 00:02:46,830 --> 00:02:52,050 then a : Long, and we'll add our left 70 00:02:52,050 --> 00:02:53,460 and right curly braces, and we want a 71 00:02:53,460 --> 00:02:59,370 return ContentUris.parseId, in 72 00:02:59,370 --> 00:03:02,010 parentheses uri, which of course was 73 00:03:02,010 --> 00:03:04,590 the argument passed in this method. Then 74 00:03:04,590 --> 00:03:05,550 the second one was that other 75 00:03:05,550 --> 00:03:08,000 complimentary method I talked about: fun 76 00:03:08,000 --> 00:03:12,420 buildUriFromId. The argument for 77 00:03:12,420 --> 00:03:15,030 that one is an ID of type long, id : 78 00:03:15,030 --> 00:03:17,700 Long, and that returns a Uri. So 79 00:03:17,700 --> 00:03:21,030 : Uri left and right curly braces, and 80 00:03:21,030 --> 00:03:24,170 we're going to return ContentUris 81 00:03:24,170 --> 00:03:27,930 dot withAppendedId, in lower case with, 82 00:03:27,930 --> 00:03:30,090 and in parentheses it's going to be 83 00:03:30,090 --> 00:03:33,950 CONTENT_URI comma id. 84 00:03:33,950 --> 00:03:35,850 So I've done something slightly 85 00:03:35,850 --> 00:03:38,100 different with the buildUriFrom 86 00:03:38,100 --> 00:03:40,470 Id function. Now I could have used the 87 00:03:40,470 --> 00:03:42,480 withAppendedPath function of the Uri 88 00:03:42,480 --> 00:03:44,940 class, like we did to create the CONTENT 89 00:03:44,940 --> 00:03:46,920 _URI, but that would 90 00:03:46,920 --> 00:03:49,860 involve converting the TaskId, which is 91 00:03:49,860 --> 00:03:52,620 a Long, into a string. Now the function 92 00:03:52,620 --> 00:03:54,450 call would also be slightly confusing 93 00:03:54,450 --> 00:03:56,430 because we're not actually appending a 94 00:03:56,430 --> 00:03:58,650 path in that case. The Uri class 95 00:03:58,650 --> 00:04:00,330 doesn't have a function to 96 00:04:00,330 --> 00:04:02,220 append an ID and there's no reason why it 97 00:04:02,220 --> 00:04:04,530 should. IDs mean something in our 98 00:04:04,530 --> 00:04:06,660 content scheme but aren't part of the 99 00:04:06,660 --> 00:04:09,900 basic URI specification. Now you've 100 00:04:09,900 --> 00:04:11,370 probably already called up the 101 00:04:11,370 --> 00:04:13,110 documentation for the withAppendedId 102 00:04:13,110 --> 00:04:15,090 function, but if you haven't, open that 103 00:04:15,090 --> 00:04:20,250 now and take a quick look. You'll see that 104 00:04:20,250 --> 00:04:23,580 it says it appends the given ID to the 105 00:04:23,580 --> 00:04:24,960 end of the path, so that's pretty 106 00:04:24,960 --> 00:04:26,940 straightforward. The documentation for 107 00:04:26,940 --> 00:04:28,680 the ContentUris class also is 108 00:04:28,680 --> 00:04:30,990 really interesting if we have a quick 109 00:04:30,990 --> 00:04:31,980 look at that, 110 00:04:31,980 --> 00:04:33,930 because it reviews what we've already 111 00:04:33,930 --> 00:04:36,420 discussed about Uris and applies it 112 00:04:36,420 --> 00:04:38,670 to the CONTENT_URIs that we're 113 00:04:38,670 --> 00:04:40,710 using with our content provider. Al 114 00:04:40,710 --> 00:04:44,130 right. So the getId function performs 115 00:04:44,130 --> 00:04:45,900 the opposite function, so it returns the 116 00:04:45,900 --> 00:04:49,530 ID from a URI using the parseId function 117 00:04:49,530 --> 00:04:52,020 of CONTENT_URIs to do the job. Al 118 00:04:52,020 --> 00:04:53,460 right so there's just two more constants 119 00:04:53,460 --> 00:04:55,950 now we need to add, to complete our Tasks 120 00:04:55,950 --> 00:04:57,960 contract class. So I'm going to go up to the 121 00:04:57,960 --> 00:05:00,240 top and add those just after the CONTENT 122 00:05:00,240 --> 00:05:03,090 _URI. So the first one, 123 00:05:03,090 --> 00:05:05,970 we'll do const Val and the CONTENT 124 00:05:05,970 --> 00:05:09,240 _TYPE is equal to, in double 125 00:05:09,240 --> 00:05:16,230 quotes, vnd.android.cursor dot 126 00:05:16,230 --> 00:05:21,480 dir, then a slash, a forward slash, vnd dot then a 127 00:05:21,480 --> 00:05:24,090 dollar sign CONTENT_ 128 00:05:24,090 --> 00:05:30,090 AUTHORITY. So that's CONTENT__AUTHORITY dot 129 00:05:30,090 --> 00:05:34,280 then a dollar sign TABLE_NAME. 130 00:05:34,280 --> 00:05:36,570 And there shouldn't be a dot there, 131 00:05:36,570 --> 00:05:37,950 after the dir there should be slash 132 00:05:37,950 --> 00:05:40,980 actually. So it's vnd.android.cursor dot 133 00:05:40,980 --> 00:05:45,300 dir, slash, a forward slash, vnd dot then the dollar sign 134 00:05:45,300 --> 00:05:47,670 CONTENT__AUTHORITY, then a dot 135 00:05:47,670 --> 00:05:49,680 then a dollar TABLE_NAME. Now we're 136 00:05:49,680 --> 00:05:51,390 actually getting an error here, and it looks 137 00:05:51,390 --> 00:05:52,530 like I might have made a mistake with 138 00:05:52,530 --> 00:05:54,720 the CONTENT__AUTHORITY definition. So 139 00:05:54,720 --> 00:05:55,590 let's just have a quick look at that - 140 00:05:55,590 --> 00:05:58,380 we'll go to the definition for that. And in 141 00:05:58,380 --> 00:05:59,850 fact I did make a an error there, 142 00:05:59,850 --> 00:06:01,740 so I've made it a private and it 143 00:06:01,740 --> 00:06:03,480 should have actually been a const. So I'm 144 00:06:03,480 --> 00:06:04,950 going to delete the word private there 145 00:06:04,950 --> 00:06:07,950 and make that a const, and if we go back 146 00:06:07,950 --> 00:06:11,370 to our TasksContract, that error then 147 00:06:11,370 --> 00:06:14,130 disappears. Alright let's add the second 148 00:06:14,130 --> 00:06:17,430 one now. So it's const val, this is 149 00:06:17,430 --> 00:06:20,010 CONTENT_ITEM_ 150 00:06:20,010 --> 00:06:23,010 TYPE. Set that equal vnd dot 151 00:06:23,010 --> 00:06:27,240 android.cursor dot, this time it's dot item 152 00:06:27,240 --> 00:06:31,470 instead of dot dir, then /vnd dot, a dollar 153 00:06:31,470 --> 00:06:33,690 sign CONTENT__AUTHORITY, noticing that 154 00:06:33,690 --> 00:06:36,090 that is now coming up correctly because 155 00:06:36,090 --> 00:06:38,280 I've corrected the definition there. So 156 00:06:38,280 --> 00:06:40,140 CONTENT__AUTHORITY dot and a dollar 157 00:06:40,140 --> 00:06:43,860 TABLE_NAME. Now I'll come back 158 00:06:43,860 --> 00:06:45,870 to these constants shortly, but 159 00:06:45,870 --> 00:06:47,760 before we switched to the TasksContract 160 00:06:47,760 --> 00:06:49,560 class to finish it off, we were looking 161 00:06:49,560 --> 00:06:51,570 at the query method in AppProvider. 162 00:06:51,570 --> 00:06:55,360 So let's just go back to AppProvider again, 163 00:06:55,360 --> 00:06:57,220 noting that we've no longer got an error 164 00:06:57,220 --> 00:07:00,310 on line 78. Now if the URI doesn't have 165 00:07:00,310 --> 00:07:02,560 an ID the matcher will return the value 166 00:07:02,560 --> 00:07:05,379 Tasks - line 74, effectively, is where it's 167 00:07:05,379 --> 00:07:07,180 testing for that - and we just call in the 168 00:07:07,180 --> 00:07:09,849 queryBuilder setTables method here, to 169 00:07:09,849 --> 00:07:11,650 add our Tasks table, or we're actually 170 00:07:11,650 --> 00:07:13,150 setting the property. Now I'm 171 00:07:13,150 --> 00:07:15,220 referring to the Java method 172 00:07:15,220 --> 00:07:17,020 here, and that's because queryBuilder's 173 00:07:17,020 --> 00:07:18,789 written in Java. Because we're 174 00:07:18,789 --> 00:07:20,680 programming in Kotlin we can assign the 175 00:07:20,680 --> 00:07:22,389 value directly to the tables property, 176 00:07:22,389 --> 00:07:23,530 which is effectively what we're doing - 177 00:07:23,530 --> 00:07:26,979 again on line 74. Now if there is an ID, 178 00:07:26,979 --> 00:07:29,530 the matcher returns TASKS_ID, 179 00:07:29,530 --> 00:07:32,349 and that's the code for that is line 76, 180 00:07:32,349 --> 00:07:34,599 starts on line 76, and we're using the 181 00:07:34,599 --> 00:07:37,090 appendWhereEscapeString method to add 182 00:07:37,090 --> 00:07:40,270 a where clause to specify the ID. Now the 183 00:07:40,270 --> 00:07:41,860 same thing will ultimately happen for 184 00:07:41,860 --> 00:07:43,330 the other tables once we've written 185 00:07:43,330 --> 00:07:46,060 their Contract classes and uncommented 186 00:07:46,060 --> 00:07:47,949 this code. Now if the URI isn't 187 00:07:47,949 --> 00:07:49,840 matched, down the bottom here, we'll throw 188 00:07:49,840 --> 00:07:51,789 an illegal argument exception and the 189 00:07:51,789 --> 00:07:54,039 rest of the code won't be executed. But 190 00:07:54,039 --> 00:07:56,379 assuming the URI is valid and matches 191 00:07:56,379 --> 00:07:58,330 one of our values, we can use the App 192 00:07:58,330 --> 00:07:59,949 Database instance to get a readable 193 00:07:59,949 --> 00:08:02,949 database object. Now we're only querying 194 00:08:02,949 --> 00:08:04,479 the database so we don't need to call 195 00:08:04,479 --> 00:08:06,729 the getWritableDatabase, so I'm using 196 00:08:06,729 --> 00:08:09,279 this, referring to this code here now, on 197 00:08:09,279 --> 00:08:11,620 line 101. So we don't need to call get 198 00:08:11,620 --> 00:08:13,090 WritableDatabase because it's a query, 199 00:08:13,090 --> 00:08:14,949 but we'll be doing that shortly when we 200 00:08:14,949 --> 00:08:16,900 come to insert rows into the database. 201 00:08:16,900 --> 00:08:18,550 But at this point we've now got 202 00:08:18,550 --> 00:08:20,710 everything we need to finish building 203 00:08:20,710 --> 00:08:23,139 the query to retrieve the data. And now 204 00:08:23,139 --> 00:08:24,580 it's time to use some of these those 205 00:08:24,580 --> 00:08:27,129 other parameters that the query method 206 00:08:27,129 --> 00:08:28,990 defines, so we'll just go back up and we'll 207 00:08:28,990 --> 00:08:31,659 look at that again. You can see line 66 208 00:08:31,659 --> 00:08:33,130 there, we've got quite a few arguments 209 00:08:33,130 --> 00:08:36,490 showing there, and what I might do is just going to 210 00:08:36,490 --> 00:08:38,289 press ENTER there, just so we can more 211 00:08:38,289 --> 00:08:40,510 clearly see what those arguments are. 212 00:08:40,510 --> 00:08:42,458 Alright, so looking at them, we'll start out 213 00:08:42,458 --> 00:08:44,949 with the first one, and we'll take the 214 00:08:44,949 --> 00:08:47,070 opportunity to open up the 215 00:08:47,070 --> 00:08:48,970 documentation for the query method. Let's 216 00:08:48,970 --> 00:08:52,329 do that. Alright that'll do, we can see, I'll put this down here 217 00:08:52,329 --> 00:08:53,589 a little bit further so you can still 218 00:08:53,589 --> 00:08:55,360 see the original parameters because we can't 219 00:08:55,360 --> 00:08:56,620 quite see them onto the right of the screen 220 00:08:56,620 --> 00:08:58,779 there. But in terms of the actual 221 00:08:58,779 --> 00:09:01,510 arguments, the first parameter's a URI 222 00:09:01,510 --> 00:09:03,430 and we've discussed that already. The 223 00:09:03,430 --> 00:09:05,740 next one is a projection. Well what is 224 00:09:05,740 --> 00:09:07,630 projection? And what that is is a 225 00:09:07,630 --> 00:09:08,330 string array 226 00:09:08,330 --> 00:09:10,580 containing the names of the columns that 227 00:09:10,580 --> 00:09:13,160 we want to be returned by the query. So 228 00:09:13,160 --> 00:09:15,170 this method effectively provides a great 229 00:09:15,170 --> 00:09:18,470 deal of flexibility in specifying what 230 00:09:18,470 --> 00:09:20,690 we'll get back from the database. Now the 231 00:09:20,690 --> 00:09:23,240 final parameter is a sortOrder. It's 232 00:09:23,240 --> 00:09:25,240 just the name of a row, or several rows, 233 00:09:25,240 --> 00:09:28,220 separated by commas that the data will 234 00:09:28,220 --> 00:09:30,650 be returned sorted by. so whatever's 235 00:09:30,650 --> 00:09:32,300 passed for the sortOrder will 236 00:09:32,300 --> 00:09:34,880 effectively appear in the SQL ORDER BY 237 00:09:34,880 --> 00:09:36,920 clause. Now I've deliberately skipped 238 00:09:36,920 --> 00:09:38,690 over the selection and selectionArgs 239 00:09:38,690 --> 00:09:40,880 parameters. I'll come back to them, as 240 00:09:40,880 --> 00:09:42,740 it's much easier to see how they work with 241 00:09:42,740 --> 00:09:44,810 an example, rather than just talking 242 00:09:44,810 --> 00:09:47,320 about them. But outside the when, our 243 00:09:47,320 --> 00:09:50,000 content providers query method calls the 244 00:09:50,000 --> 00:09:53,120 queryBuilders query method, and you can see 245 00:09:53,120 --> 00:09:55,850 that here on line 103. So that's the one 246 00:09:55,850 --> 00:09:57,200 we're writing, not the queryBuilders 247 00:09:57,200 --> 00:09:59,180 query method. So it's passing it the 248 00:09:59,180 --> 00:10:01,040 database object that we get by calling 249 00:10:01,040 --> 00:10:03,920 the AppDatabase getInstance function. 250 00:10:03,920 --> 00:10:06,110 You can see that db being called there, 251 00:10:06,110 --> 00:10:08,390 being passed I should say, to the query 252 00:10:08,390 --> 00:10:10,070 Builder.query function, or method, 253 00:10:10,070 --> 00:10:12,590 because again the query builder is 254 00:10:12,590 --> 00:10:14,330 written in Java. Now most of the 255 00:10:14,330 --> 00:10:15,890 parameters of our query method are 256 00:10:15,890 --> 00:10:17,510 passed straight into the queryBuilders 257 00:10:17,510 --> 00:10:20,300 query method, but it also includes two 258 00:10:20,300 --> 00:10:21,680 other parameters that we've just passed 259 00:10:21,680 --> 00:10:23,660 null for. And you can see they're grouped 260 00:10:23,660 --> 00:10:27,200 by, and having, both null currently. Now if we 261 00:10:27,200 --> 00:10:28,460 check out the documentation this time 262 00:10:28,460 --> 00:10:36,350 for the queryBuilder.query method, you 263 00:10:36,350 --> 00:10:37,820 can see that looks very similar to our 264 00:10:37,820 --> 00:10:40,580 content providers query method. So one's 265 00:10:40,580 --> 00:10:42,110 your projection to specify which columns 266 00:10:42,110 --> 00:10:44,120 should appear in the result, the 267 00:10:44,120 --> 00:10:45,800 selection and selectionArgs 268 00:10:45,800 --> 00:10:47,390 parameters that we'll look at shortly, 269 00:10:47,390 --> 00:10:49,880 and a sortOrder. But it also allows 270 00:10:49,880 --> 00:10:51,880 groupBy and having clauses to be used. 271 00:10:51,880 --> 00:10:54,440 Now we looked at groupBy in a SQL 272 00:10:54,440 --> 00:10:56,690 tutorial earlier in a previous section 273 00:10:56,690 --> 00:10:59,000 in this course. having is like a where 274 00:10:59,000 --> 00:11:01,100 clause but it also applies to the 275 00:11:01,100 --> 00:11:03,110 grouping, so I'm not going to use having. 276 00:11:03,110 --> 00:11:05,120 But if you did something like, for 277 00:11:05,120 --> 00:11:07,640 example, group by month to get the total 278 00:11:07,640 --> 00:11:09,230 of some value for each month, then you 279 00:11:09,230 --> 00:11:11,120 could do something like; adding having 280 00:11:11,120 --> 00:11:14,150 days equals 31, to only total the data 281 00:11:14,150 --> 00:11:16,430 for months that have got 31 days. So it's 282 00:11:16,430 --> 00:11:18,350 useful to know how you can do that, and 283 00:11:18,350 --> 00:11:20,060 there's quite a lot more to SQL than 284 00:11:20,060 --> 00:11:21,940 we've covered in the tutorials, 285 00:11:21,940 --> 00:11:23,620 but we won't be using the having clause in 286 00:11:23,620 --> 00:11:25,710 this app. So go back to our code now and 287 00:11:25,710 --> 00:11:29,050 the function finally finishes - down here 288 00:11:29,050 --> 00:11:31,450 is the last line returning a cursor. So 289 00:11:31,450 --> 00:11:33,070 it's returning the cursor that it's 290 00:11:33,070 --> 00:11:34,630 got back from the queryBuilder dot 291 00:11:34,630 --> 00:11:37,210 query method. Now to make it obvious that 292 00:11:37,210 --> 00:11:39,460 we get a cursor, I've used two lines of 293 00:11:39,460 --> 00:11:41,800 code and also logged the number of rows 294 00:11:41,800 --> 00:11:44,110 in the cursor. When we're happy that it 295 00:11:44,110 --> 00:11:46,210 works we can directly return the result 296 00:11:46,210 --> 00:11:47,920 of calling queryBuilder.query, 297 00:11:47,920 --> 00:11:50,260 instead of storing the cursor in a local 298 00:11:50,260 --> 00:11:52,780 variable first. Okay, and we haven't 299 00:11:52,780 --> 00:11:55,390 created a user interface yet, but we can 300 00:11:55,390 --> 00:11:57,760 test the content provider by logging the 301 00:11:57,760 --> 00:11:59,650 values in the logcat. But there's 302 00:11:59,650 --> 00:12:01,330 something else we need to do first, and 303 00:12:01,330 --> 00:12:03,840 that's to register our content provider 304 00:12:03,840 --> 00:12:06,370 so that the content resolver knows 305 00:12:06,370 --> 00:12:08,140 about it. So we'll do that and then test 306 00:12:08,140 --> 00:12:12,150 the content provider in the next video.