System API used by telephony to bind to WapPushManager app.

Bug: 145179378
Test: make
Change-Id: Ibfb5ce49d20addcd19775d9e8d762945e71b9843
diff --git a/api/system-current.txt b/api/system-current.txt
index 41ded16..fe50525 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -10381,6 +10381,20 @@
     method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
   }
 
+  public final class WapPushManagerConnector {
+    ctor public WapPushManagerConnector(@NonNull android.content.Context);
+    method public boolean bindToWapPushManagerService();
+    method @Nullable public String getConnectedWapPushManagerServicePackage();
+    method public int processMessage(@NonNull String, @NonNull String, @NonNull android.content.Intent);
+    method public void unbindWapPushManagerService();
+    field public static final int RESULT_APP_QUERY_FAILED = 2; // 0x2
+    field public static final int RESULT_EXCEPTION_CAUGHT = 16; // 0x10
+    field public static final int RESULT_FURTHER_PROCESSING = 32768; // 0x8000
+    field public static final int RESULT_INVALID_RECEIVER_NAME = 8; // 0x8
+    field public static final int RESULT_MESSAGE_HANDLED = 1; // 0x1
+    field public static final int RESULT_SIGNATURE_NO_MATCH = 4; // 0x4
+  }
+
 }
 
 package android.telephony.cdma {
diff --git a/core/java/android/telephony/WapPushManagerConnector.java b/core/java/android/telephony/WapPushManagerConnector.java
new file mode 100644
index 0000000..a9df506
--- /dev/null
+++ b/core/java/android/telephony/WapPushManagerConnector.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2019 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 android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.android.internal.telephony.IWapPushManager;
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * APIs for platform to connect to the WAP push manager service.
+ *
+ * <p>To start connection, {@link #bindToWapPushManagerService} should be called.
+ *
+ * <p>Upon completion {@link #unbindWapPushManagerService} should be called to unbind the service.
+ *
+ * @hide
+ */
+@SystemApi
+public final class WapPushManagerConnector {
+    private final Context mContext;
+
+    private volatile WapPushManagerConnection mConnection;
+    private volatile IWapPushManager mWapPushManager;
+    private String mWapPushManagerPackage;
+
+    /**
+     * The {@link android.content.Intent} that must be declared as handled by the
+     * WAP push manager service.
+     * @hide
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "com.android.internal.telephony.IWapPushManager";
+
+    /** @hide */
+    @IntDef(flag = true, prefix = {"RESULT_"}, value = {
+            RESULT_MESSAGE_HANDLED,
+            RESULT_APP_QUERY_FAILED,
+            RESULT_SIGNATURE_NO_MATCH,
+            RESULT_INVALID_RECEIVER_NAME,
+            RESULT_EXCEPTION_CAUGHT,
+            RESULT_FURTHER_PROCESSING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ProcessMessageResult{}
+
+    /** {@link #processMessage} return value: Message is handled. */
+    public static final int RESULT_MESSAGE_HANDLED = 0x1;
+    /** {@link #processMessage} return value: Application ID or content type was not found. */
+    public static final int RESULT_APP_QUERY_FAILED = 0x2;
+    /** {@link #processMessage} return value: Receiver application signature check failed. */
+    public static final int RESULT_SIGNATURE_NO_MATCH = 0x4;
+    /** {@link #processMessage} return value: Receiver application was not found. */
+    public static final int RESULT_INVALID_RECEIVER_NAME = 0x8;
+    /** {@link #processMessage} return value: Unknown exception. */
+    public static final int RESULT_EXCEPTION_CAUGHT = 0x10;
+    /** {@link #processMessage} return value: further processing needed. */
+    public static final int RESULT_FURTHER_PROCESSING = 0x8000;
+
+    /** The application package name of the WAP push manager service. */
+    private static final String SERVICE_PACKAGE = "com.android.smspush";
+
+    public WapPushManagerConnector(@NonNull Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Binds to the WAP push manager service. This method should be called exactly once.
+     *
+     * @return {@code true} upon successfully binding to a service, {@code false} otherwise
+     */
+    public boolean bindToWapPushManagerService() {
+        Preconditions.checkState(mConnection == null);
+
+        Intent intent = new Intent(SERVICE_INTERFACE);
+        ComponentName component = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(component);
+        mConnection = new WapPushManagerConnection();
+        if (component != null
+                && mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
+            mWapPushManagerPackage = component.getPackageName();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the package name of WAP push manager service application connected to,
+     * or {@code null} if not connected.
+     */
+    @Nullable
+    public String getConnectedWapPushManagerServicePackage() {
+        return mWapPushManagerPackage;
+    }
+
+    /**
+     * Processes WAP push message and triggers the {@code intent}.
+     *
+     * @see RESULT_MESSAGE_HANDLED
+     * @see RESULT_APP_QUERY_FAILED
+     * @see RESULT_SIGNATURE_NO_MATCH
+     * @see RESULT_INVALID_RECEIVER_NAME
+     * @see RESULT_EXCEPTION_CAUGHT
+     * @see RESULT_FURTHER_PROCESSING
+     */
+    @ProcessMessageResult
+    public int processMessage(
+            @NonNull String applicationId, @NonNull String contentType, @NonNull Intent intent) {
+        try {
+            return mWapPushManager.processMessage(applicationId, contentType, intent);
+        } catch (NullPointerException | RemoteException e) {
+            return RESULT_EXCEPTION_CAUGHT;
+        }
+    }
+
+    /**
+     * Unbinds the WAP push manager service. This method should be called exactly once.
+     */
+    public void unbindWapPushManagerService() {
+        Preconditions.checkNotNull(mConnection);
+
+        mContext.unbindService(mConnection);
+        mConnection = null;
+    }
+
+    private class WapPushManagerConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            // Because we have bound to an explicit
+            // service that is running in our own process, we can
+            // cast its IBinder to a concrete class and directly access it.
+            mWapPushManager = IWapPushManager.Stub.asInterface(service);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            mWapPushManager = null;
+        }
+
+        @Override
+        public void onNullBinding(ComponentName name) {
+            onServiceDisconnected(name);
+        }
+
+        @Override
+        public void onBindingDied(ComponentName name) {
+            onServiceDisconnected(name);
+        }
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/IWapPushManager.aidl b/core/java/com/android/internal/telephony/IWapPushManager.aidl
similarity index 82%
rename from telephony/java/com/android/internal/telephony/IWapPushManager.aidl
rename to core/java/com/android/internal/telephony/IWapPushManager.aidl
index 1c3df65..9f6851b 100644
--- a/telephony/java/com/android/internal/telephony/IWapPushManager.aidl
+++ b/core/java/com/android/internal/telephony/IWapPushManager.aidl
@@ -18,6 +18,7 @@
 
 import android.content.Intent;
 
+/** @hide */
 interface IWapPushManager {
     /**
      * Processes WAP push message and triggers the receiver application registered
@@ -26,11 +27,10 @@
     int processMessage(String app_id, String content_type, in Intent intent);
 
     /**
-     * Add receiver application into the application ID table.
-     * Returns true if inserting the information is successfull. Inserting the duplicated
+     * Adds receiver application into the application ID table.
+     * Returns true if inserting the information is successful. Inserting duplicated
      * record in the application ID table is not allowed. Use update/delete method.
      */
-    @UnsupportedAppUsage
     boolean addPackage(String x_app_id, String content_type,
             String package_name, String class_name,
             int app_type, boolean need_signature, boolean further_processing);
@@ -39,17 +39,14 @@
      * Updates receiver application that is last added.
      * Returns true if updating the information is successfull.
      */
-    @UnsupportedAppUsage
     boolean updatePackage(String x_app_id, String content_type,
             String package_name, String class_name,
             int app_type, boolean need_signature, boolean further_processing);
 
     /**
-     * Delites receiver application information.
+     * Deletes receiver application information.
      * Returns true if deleting is successfull.
      */
-    @UnsupportedAppUsage
     boolean deletePackage(String x_app_id, String content_type,
-                            String package_name, String class_name);
+            String package_name, String class_name);
 }
-
diff --git a/core/java/com/android/internal/telephony/WapPushManagerParams.java b/core/java/com/android/internal/telephony/WapPushManagerParams.java
new file mode 100644
index 0000000..eafb8f1
--- /dev/null
+++ b/core/java/com/android/internal/telephony/WapPushManagerParams.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 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.internal.telephony;
+
+import android.telephony.WapPushManagerConnector;
+
+/**
+ * WapPushManager constant value definitions.
+ * @hide
+ */
+public class WapPushManagerParams {
+    /**
+     * Application type activity
+     */
+    public static final int APP_TYPE_ACTIVITY = 0;
+
+    /**
+     * Application type service
+     */
+    public static final int APP_TYPE_SERVICE = 1;
+
+    /**
+     * Process Message return value
+     * Message is handled
+     */
+    public static final int MESSAGE_HANDLED = WapPushManagerConnector.RESULT_MESSAGE_HANDLED;
+
+    /**
+     * Process Message return value
+     * Application ID or content type was not found in the application ID table
+     */
+    public static final int APP_QUERY_FAILED = WapPushManagerConnector.RESULT_APP_QUERY_FAILED;
+
+    /**
+     * Process Message return value
+     * Receiver application signature check failed
+     */
+    public static final int SIGNATURE_NO_MATCH = WapPushManagerConnector.RESULT_SIGNATURE_NO_MATCH;
+
+    /**
+     * Process Message return value
+     * Receiver application was not found
+     */
+    public static final int INVALID_RECEIVER_NAME =
+            WapPushManagerConnector.RESULT_INVALID_RECEIVER_NAME;
+
+    /**
+     * Process Message return value
+     * Unknown exception
+     */
+    public static final int EXCEPTION_CAUGHT = WapPushManagerConnector.RESULT_EXCEPTION_CAUGHT;
+
+    /**
+     * Process Message return value
+     * Need further processing after WapPushManager message processing
+     */
+    public static final int FURTHER_PROCESSING = WapPushManagerConnector.RESULT_FURTHER_PROCESSING;
+}