Add IntentFilter auto verification

The purpose of this feature is to prompt the Disambiguation dialog
to Users as less as possible.

- add the new "autoVerify" property to the IntentFilter class
- add new APIs to PackageManager:
 verifyIntentFilter(int, int, List<String>),
 getIntentVerificationStatus(String, int),
 updateIntentVerificationStatus(String, int, int),
 getIntentFilterVerifications(String)
for supporting IntentFilter verification
- add support for multi-user
- update PackageManager for IntentFilter verification:
basically when we are installing a new package, ask for verification
of all domains from the IntentFilters that have the "autoVerify" to true.
This means that the PackageManager will send a well defined protected
broadcast (with a new INTENT_FILTER_NEEDS_VERIFICATION action) to
an IntentFilter verifier to do the real job of verification.
We are passing in the broadcast Intent all the necessary data for
doing the verification. The PackageManager will receive as response
the result code of the domain verifications and, if needed, the list
of domains that have failed the verification.
- add a new INTENT_FILTER_VERIFICATION_AGENT permission that needs to
be set by an intent filter verifier to be considered as a trustable
party by the PackageManager.
- add also a new BIND_INTENT_FILTER_VERIFIER permission for securing
the binding between the PackageManager and a service doing the
intent filter verifications.
- add ResolveInfo filterNeedsVerification which is a boolean
to knows if the IntentFilter is of a type that needs a verification
(action VIEW, category BROWABLE, HTTP/HTTPS data URI)
- add new "domain-preferred-apps" / "d" dump command for listing the
prefered Apps for all domains
- add new "intent-filter-verifiers" / "ivf" command for listing the
IntentFilterVerifier used
- introduce the IntentVerificationService which is a basic service
for verifying IntentFilters. This service will send HTTPS requests
to the domain declared in the IntentFilter(s) for doing the
verification. This service has a low priority level so that it
can be replaced by a more sophisticated one if needed. This service
is updating the PackageManager intent verification states thru
the updateIntentVerificationStatus(...) API.
- update MockPackageManager

Change-Id: I0bfed193d0bf1f7c7ac79f6c1b160b7ab93b5fb5
diff --git a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
new file mode 100644
index 0000000..c09d6ae
--- /dev/null
+++ b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class IntentFilterVerificationState {
+    static final String TAG = IntentFilterVerificationState.class.getName();
+
+    public final static int STATE_UNDEFINED = 0;
+    public final static int STATE_VERIFICATION_PENDING = 1;
+    public final static int STATE_VERIFICATION_SUCCESS = 2;
+    public final static int STATE_VERIFICATION_FAILURE = 3;
+
+    private int mRequiredVerifierUid = 0;
+
+    private int mState;
+
+    private ArrayList<PackageParser.ActivityIntentInfo> mFilters = new ArrayList<>();
+    private ArraySet<String> mHosts = new ArraySet<>();
+    private int mUserId;
+
+    private String mPackageName;
+    private boolean mVerificationComplete;
+
+    public IntentFilterVerificationState(int verifierUid, int userId, String packageName) {
+        mRequiredVerifierUid = verifierUid;
+        mUserId = userId;
+        mPackageName = packageName;
+        mState = STATE_UNDEFINED;
+        mVerificationComplete = false;
+    }
+
+    public void setState(int state) {
+        if (state > STATE_VERIFICATION_FAILURE || state < STATE_UNDEFINED) {
+            mState = STATE_UNDEFINED;
+        } else {
+            mState = state;
+        }
+    }
+
+    public int getState() {
+        return mState;
+    }
+
+    public void setPendingState() {
+        setState(STATE_VERIFICATION_PENDING);
+    }
+
+    public ArrayList<PackageParser.ActivityIntentInfo> getFilters() {
+        return mFilters;
+    }
+
+    public boolean isVerificationComplete() {
+        return mVerificationComplete;
+    }
+
+    public boolean isVerified() {
+        if (mVerificationComplete) {
+            return (mState == STATE_VERIFICATION_SUCCESS);
+        }
+        return false;
+    }
+
+    public int getUserId() {
+        return mUserId;
+    }
+
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public String getHostsString() {
+        StringBuilder sb = new StringBuilder();
+        final int count = mHosts.size();
+        for (int i=0; i<count; i++) {
+            if (i > 0) {
+                sb.append(" ");
+            }
+            sb.append(mHosts.valueAt(i));
+        }
+        return sb.toString();
+    }
+
+    public boolean setVerifierResponse(int callerUid, int code) {
+        if (mRequiredVerifierUid == callerUid) {
+            int state = STATE_UNDEFINED;
+            if (code == PackageManager.INTENT_FILTER_VERIFICATION_SUCCESS) {
+                state = STATE_VERIFICATION_SUCCESS;
+            } else if (code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
+                state = STATE_VERIFICATION_FAILURE;
+            }
+            mVerificationComplete = true;
+            setState(state);
+            return true;
+        }
+        Log.d(TAG, "Cannot set verifier response with callerUid:" + callerUid + " and code:" +
+                code + " as required verifierUid is:" + mRequiredVerifierUid);
+        return false;
+    }
+
+    public void addFilter(PackageParser.ActivityIntentInfo filter) {
+        mFilters.add(filter);
+        mHosts.addAll(filter.getHostsList());
+    }
+}