1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.bedstead.testapp;
18 
19 import com.android.queryable.Queryable;
20 import com.android.queryable.queries.StringQuery;
21 import com.android.queryable.queries.StringQueryHelper;
22 
23 /** Builder for progressively building {@link TestApp} queries. */
24 public final class TestAppQueryBuilder implements Queryable {
25     private final TestAppProvider mProvider;
26 
27     StringQueryHelper<TestAppQueryBuilder> mPackageName = new StringQueryHelper<>(this);
28 
TestAppQueryBuilder(TestAppProvider provider)29     TestAppQueryBuilder(TestAppProvider provider) {
30         if (provider == null) {
31             throw new NullPointerException();
32         }
33         mProvider = provider;
34     }
35 
36     /**
37      * Query for a {@link TestApp} with a given package name.
38      *
39      * <p>Only use this filter when you are relying specifically on the package name itself. If you
40      * are relying on features you know the {@link TestApp} with that package name has, query for
41      * those features directly.
42      */
wherePackageName()43     public StringQuery<TestAppQueryBuilder> wherePackageName() {
44         return mPackageName;
45     }
46 
47     /**
48      * Get the {@link TestApp} matching the query.
49      *
50      * @throws NotFoundException if there is no matching @{link TestApp}.
51      */
get()52     public TestApp get() {
53         // TODO(scottjonathan): Provide instructions on adding the TestApp if the query fails
54         return new TestApp(resolveQuery());
55     }
56 
resolveQuery()57     private TestAppDetails resolveQuery() {
58         for (TestAppDetails details : mProvider.testApps()) {
59             if (!matches(details)) {
60                 continue;
61             }
62 
63             mProvider.markTestAppUsed(details);
64             return details;
65         }
66 
67         throw new NotFoundException(this);
68     }
69 
matches(TestAppDetails details)70     private boolean matches(TestAppDetails details) {
71         if (!StringQueryHelper.matches(mPackageName, details.mPackageName)) {
72             return false;
73         }
74 
75         return true;
76     }
77 }
78