• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.statementservice.retriever;
18 
19 import android.annotation.NonNull;
20 import android.net.Network;
21 
22 import com.android.statementservice.network.retriever.StatementRetriever;
23 
24 import kotlin.coroutines.Continuation;
25 
26 import java.util.Collections;
27 import java.util.List;
28 
29 
30 /**
31  * An immutable value type representing a statement, consisting of a source, target, and relation.
32  * This reflects an assertion that the relation holds for the source, target pair. For example, if a
33  * web site has the following in its assetlinks.json file:
34  *
35  * <pre>
36  * {
37  * "relation": ["delegate_permission/common.handle_all_urls"],
38  * "target"  : {"namespace": "android_app", "package_name": "com.example.app",
39  *              "sha256_cert_fingerprints": ["00:11:22:33"] },
40  * "relation_extensions": {
41  *     "delegate_permission/common_handle_all_urls": {
42  *         "dynamic_app_link_components": [
43  *             {
44  *                 "/": "/foo*",
45  *                 "exclude": true,
46  *                 "comments": "App should not handle paths that start with foo"
47  *             },
48  *             {
49  *                 "/": "*",
50  *                 "comments": "Catch all other paths"
51  *             }
52  *         ]
53  *     }
54  * }
55  * </pre>
56  *
57  * Then invoking {@link StatementRetriever#retrieve(AbstractAsset, Network, Continuation)} will
58  * return a {@link Statement} with {@link #getSource} equal to the input parameter,
59  * {@link #getRelation} equal to
60  *
61  * <pre>Relation.create("delegate_permission", "common.handle_all_urls");</pre>
62  *
63  * and with {@link #getTarget} equal to
64  *
65  * <pre>AbstractAsset.create("{\"namespace\" : \"android_app\","
66  *                           + "\"package_name\": \"com.example.app\"}"
67  *                           + "\"sha256_cert_fingerprints\": \"[\"00:11:22:33\"]\"}");
68  * </pre>
69  *
70  * If extensions exist for the handle_all_urls relation then {@link #getDynamicAppLinkComponents}
71  * will return a list of parsed {@link DynamicAppLinkComponent}s.
72  */
73 public final class Statement {
74 
75     private final AbstractAsset mTarget;
76     private final Relation mRelation;
77     private final AbstractAsset mSource;
78     private final List<DynamicAppLinkComponent> mDynamicAppLinkComponents;
79 
Statement(AbstractAsset source, AbstractAsset target, Relation relation, List<DynamicAppLinkComponent> components)80     private Statement(AbstractAsset source, AbstractAsset target, Relation relation,
81                       List<DynamicAppLinkComponent> components) {
82         mSource = source;
83         mTarget = target;
84         mRelation = relation;
85         mDynamicAppLinkComponents = Collections.unmodifiableList(components);
86     }
87 
88     /**
89      * Returns the source asset of the statement.
90      */
91     @NonNull
getSource()92     public AbstractAsset getSource() {
93         return mSource;
94     }
95 
96     /**
97      * Returns the target asset of the statement.
98      */
99     @NonNull
getTarget()100     public AbstractAsset getTarget() {
101         return mTarget;
102     }
103 
104     /**
105      * Returns the relation of the statement.
106      */
107     @NonNull
getRelation()108     public Relation getRelation() {
109         return mRelation;
110     }
111 
112     /**
113      * Returns the relation matching rules of the statement.
114      */
115     @NonNull
getDynamicAppLinkComponents()116     public List<DynamicAppLinkComponent> getDynamicAppLinkComponents() {
117         return mDynamicAppLinkComponents;
118     }
119 
120     /**
121      * Creates a new Statement object for the specified target asset and relation. For example:
122      * <pre>
123      *   Asset asset = Asset.Factory.create(
124      *       "{\"namespace\" : \"web\",\"site\": \"https://www.test.com\"}");
125      *   Relation relation = Relation.create("delegate_permission", "common.get_login_creds");
126      *   Statement statement = Statement.create(asset, relation);
127      * </pre>
128      */
create(@onNull AbstractAsset source, @NonNull AbstractAsset target, @NonNull Relation relation, @NonNull List<DynamicAppLinkComponent> components)129     public static Statement create(@NonNull AbstractAsset source, @NonNull AbstractAsset target,
130                                    @NonNull Relation relation,
131                                    @NonNull List<DynamicAppLinkComponent> components) {
132         return new Statement(source, target, relation, components);
133     }
134 
135     @Override
equals(Object o)136     public boolean equals(Object o) {
137         if (this == o) {
138             return true;
139         }
140         if (o == null || getClass() != o.getClass()) {
141             return false;
142         }
143 
144         Statement statement = (Statement) o;
145 
146         if (!mRelation.equals(statement.mRelation)) {
147             return false;
148         }
149         if (!mTarget.equals(statement.mTarget)) {
150             return false;
151         }
152         if (!mSource.equals(statement.mSource)) {
153             return false;
154         }
155         if (!mDynamicAppLinkComponents.equals(statement.mDynamicAppLinkComponents)) {
156             return false;
157         }
158 
159         return true;
160     }
161 
162     @Override
hashCode()163     public int hashCode() {
164         int result = mTarget.hashCode();
165         result = 31 * result + mRelation.hashCode();
166         result = 31 * result + mSource.hashCode();
167         result = 31 * result + mDynamicAppLinkComponents.hashCode();
168         return result;
169     }
170 
171     @Override
toString()172     public String toString() {
173         StringBuilder statement = new StringBuilder();
174         statement.append("Statement: ");
175         statement.append(mSource);
176         statement.append(", ");
177         statement.append(mTarget);
178         statement.append(", ");
179         statement.append(mRelation);
180         if (!mDynamicAppLinkComponents.isEmpty()) {
181             statement.append(", ");
182             statement.append(mDynamicAppLinkComponents);
183         }
184         return statement.toString();
185     }
186 }
187