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
17package com.android.statementservice.retriever;
18
19import android.content.Context;
20import android.annotation.NonNull;
21
22import java.util.List;
23
24/**
25 * Retrieves the statements made by assets. This class is the entry point of the package.
26 * <p>
27 * An asset is an identifiable and addressable online entity that typically
28 * provides some service or content. Examples of assets are websites, Android
29 * apps, Twitter feeds, and Plus Pages.
30 * <p>
31 * Ownership of an asset is defined by being able to control it and speak for it.
32 * An asset owner may establish a relationship between the asset and another
33 * asset by making a statement about an intended relationship between the two.
34 * An example of a relationship is permission delegation. For example, the owner
35 * of a website (the webmaster) may delegate the ability the handle URLs to a
36 * particular mobile app. Relationships are considered public information.
37 * <p>
38 * A particular kind of relationship (like permission delegation) defines a binary
39 * relation on assets. The relation is not symmetric or transitive, nor is it
40 * antisymmetric or anti-transitive.
41 * <p>
42 * A statement S(r, a, b) is an assertion that the relation r holds for the
43 * ordered pair of assets (a, b). For example, taking r = "delegates permission
44 * to view user's location", a = New York Times mobile app,
45 * b = nytimes.com website, S(r, a, b) would be an assertion that "the New York
46 * Times mobile app delegates its ability to use the user's location to the
47 * nytimes.com website".
48 * <p>
49 * A statement S(r, a, b) is considered <b>reliable</b> if we have confidence that
50 * the statement is true; the exact criterion depends on the kind of statement,
51 * since some kinds of statements may be true on their face whereas others may
52 * require multiple parties to agree.
53 * <p>
54 * For example, to get the statements made by www.example.com use:
55 * <pre>
56 * result = retrieveStatements(AssetFactory.create(
57 *     "{\"namespace\": \"web\", \"site\": \"https://www.google.com\"}"))
58 * </pre>
59 * {@code result} will contain the statements and the expiration time of this result. The statements
60 * are considered reliable until the expiration time.
61 */
62public abstract class AbstractStatementRetriever {
63
64    /**
65     * Returns the statements made by the {@code source} asset with ttl.
66     *
67     * @throws AssociationServiceException if the asset namespace is not supported.
68     */
69    public abstract Result retrieveStatements(AbstractAsset source)
70            throws AssociationServiceException;
71
72    /**
73     * The retrieved statements and the expiration date.
74     */
75    public interface Result {
76
77        /**
78         * @return the retrieved statements.
79         */
80        @NonNull
81        public List<Statement> getStatements();
82
83        /**
84         * @return the expiration time in millisecond.
85         */
86        public long getExpireMillis();
87    }
88
89    /**
90     * Creates a new StatementRetriever that directly retrieves statements from the asset.
91     *
92     * <p> For web assets, {@link AbstractStatementRetriever} will try to retrieve the statement
93     * file from URL: {@code [webAsset.site]/.well-known/assetlinks.json"} where {@code
94     * [webAsset.site]} is in the form {@code http{s}://[hostname]:[optional_port]}. The file
95     * should contain one JSON array of statements.
96     *
97     * <p> For Android assets, {@link AbstractStatementRetriever} will try to retrieve the statement
98     * from the AndroidManifest.xml. The developer should add a {@code meta-data} tag under
99     * {@code application} tag where attribute {@code android:name} equals "associated_assets"
100     * and {@code android:recourse} points to a string array resource. Each entry in the string
101     * array should contain exactly one statement in JSON format. Note that this implementation
102     * can only return statements made by installed apps.
103     */
104    public static AbstractStatementRetriever createDirectRetriever(Context context) {
105        return new DirectStatementRetriever(new URLFetcher(),
106                new AndroidPackageInfoFetcher(context));
107    }
108}
109