174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry/*
274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * Copyright (C) 2017 The Android Open Source Project
374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry *
474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * Licensed under the Apache License, Version 2.0 (the "License");
574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * you may not use this file except in compliance with the License.
674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * You may obtain a copy of the License at
774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry *
874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry *      http://www.apache.org/licenses/LICENSE-2.0
974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry *
1074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * Unless required by applicable law or agreed to in writing, software
1174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * distributed under the License is distributed on an "AS IS" BASIS,
1274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * See the License for the specific language governing permissions and
1474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * limitations under the License.
1574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry */
1674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
1774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastrypackage com.android.internal.telephony;
1874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
1974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.content.Context;
2074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.content.Intent;
2174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.content.pm.PackageManager;
2274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.content.pm.ResolveInfo;
2374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.os.Binder;
2474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.os.RemoteException;
2574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.service.carrier.CarrierMessagingService;
2674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.service.carrier.ICarrierMessagingCallback;
2774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.service.carrier.ICarrierMessagingService;
2874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.service.carrier.MessagePdu;
2974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.telephony.CarrierMessagingServiceManager;
3074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport android.telephony.Rlog;
3174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
32311e8950a8e2662422d999c5bda4f90cca7bf39aAbhijith Shastryimport com.android.internal.annotations.VisibleForTesting;
3374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport com.android.internal.telephony.uicc.UiccCard;
3474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport com.android.internal.telephony.uicc.UiccController;
3574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
3674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport java.util.ArrayList;
3774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport java.util.Arrays;
3874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastryimport java.util.List;
3999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastryimport java.util.Optional;
4074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
4174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry/**
4274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * Filters incoming SMS with carrier services.
4374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry * <p> A new instance must be created for filtering each message.
4474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry */
4574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastrypublic class CarrierServicesSmsFilter {
4674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    protected static final boolean DBG = true;
4774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
4874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private final Context mContext;
494256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala    private final Phone mPhone;
5074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private final byte[][] mPdus;
5174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private final int mDestPort;
5274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private final String mPduFormat;
5374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private final CarrierServicesSmsFilterCallbackInterface mCarrierServicesSmsFilterCallback;
5474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private final String mLogTag;
5574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
56311e8950a8e2662422d999c5bda4f90cca7bf39aAbhijith Shastry    @VisibleForTesting
57311e8950a8e2662422d999c5bda4f90cca7bf39aAbhijith Shastry    public CarrierServicesSmsFilter(
5874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            Context context,
594256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala            Phone phone,
6074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            byte[][] pdus,
6174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            int destPort,
6274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            String pduFormat,
6374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            CarrierServicesSmsFilterCallbackInterface carrierServicesSmsFilterCallback,
6474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            String logTag) {
6574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        mContext = context;
664256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala        mPhone = phone;
6774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        mPdus = pdus;
6874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        mDestPort = destPort;
6974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        mPduFormat = pduFormat;
7074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        mCarrierServicesSmsFilterCallback = carrierServicesSmsFilterCallback;
7174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        mLogTag = logTag;
7274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
7374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
7474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    /**
7574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     * @return {@code true} if the SMS was handled by carrier services.
7674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     */
77311e8950a8e2662422d999c5bda4f90cca7bf39aAbhijith Shastry    @VisibleForTesting
78311e8950a8e2662422d999c5bda4f90cca7bf39aAbhijith Shastry    public boolean filter() {
7999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        Optional<String> carrierAppForFiltering = getCarrierAppPackageForFiltering();
8099462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        List<String> smsFilterPackages = new ArrayList<>();
8199462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        if (carrierAppForFiltering.isPresent()) {
8299462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            smsFilterPackages.add(carrierAppForFiltering.get());
8399462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        }
844256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala        String carrierImsPackage = CarrierSmsUtils.getCarrierImsPackageForIntent(mContext, mPhone,
854256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala                new Intent(CarrierMessagingService.SERVICE_INTERFACE));
864256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala        if (carrierImsPackage != null) {
874256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala            smsFilterPackages.add(carrierImsPackage);
884256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala        }
8999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        FilterAggregator filterAggregator = new FilterAggregator(smsFilterPackages.size());
9099462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        for (String smsFilterPackage : smsFilterPackages) {
9199462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            filterWithPackage(smsFilterPackage, filterAggregator);
9299462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        }
9399462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        boolean handled = smsFilterPackages.size() > 0;
9499462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        return handled;
9599462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry    }
9699462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry
9799462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry    private Optional<String> getCarrierAppPackageForFiltering() {
9874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        List<String> carrierPackages = null;
994256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala        UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
10074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        if (card != null) {
10174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            carrierPackages = card.getCarrierPackageNamesForIntent(
10274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                    mContext.getPackageManager(),
10374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                    new Intent(CarrierMessagingService.SERVICE_INTERFACE));
10474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        } else {
10574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            Rlog.e(mLogTag, "UiccCard not initialized.");
10674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
10774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        if (carrierPackages != null && carrierPackages.size() == 1) {
10874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            log("Found carrier package.");
10999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            return Optional.of(carrierPackages.get(0));
11074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
11174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
11274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        // It is possible that carrier app is not present as a CarrierPackage, but instead as a
11374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        // system app
11474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        List<String> systemPackages =
11574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                getSystemAppForIntent(new Intent(CarrierMessagingService.SERVICE_INTERFACE));
11674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
11774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        if (systemPackages != null && systemPackages.size() == 1) {
11874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            log("Found system package.");
11999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            return Optional.of(systemPackages.get(0));
12074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
12174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        logv("Unable to find carrier package: " + carrierPackages
12274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                + ", nor systemPackages: " + systemPackages);
12399462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        return Optional.empty();
12474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
12574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
12699462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry    private void filterWithPackage(String packageName, FilterAggregator filterAggregator) {
12774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        CarrierSmsFilter smsFilter = new CarrierSmsFilter(mPdus, mDestPort, mPduFormat);
12874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        CarrierSmsFilterCallback smsFilterCallback =
12999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                new CarrierSmsFilterCallback(filterAggregator, smsFilter);
13099462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        smsFilter.filterSms(packageName, smsFilterCallback);
13174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
13274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
13374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private List<String> getSystemAppForIntent(Intent intent) {
13474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        List<String> packages = new ArrayList<String>();
13574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        PackageManager packageManager = mContext.getPackageManager();
13674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        List<ResolveInfo> receivers = packageManager.queryIntentServices(intent, 0);
13774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        String carrierFilterSmsPerm = "android.permission.CARRIER_FILTER_SMS";
13874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
13974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        for (ResolveInfo info : receivers) {
14074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            if (info.serviceInfo == null) {
14174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                loge("Can't get service information from " + info);
14274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                continue;
14374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            }
14474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            String packageName = info.serviceInfo.packageName;
14574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            if (packageManager.checkPermission(carrierFilterSmsPerm, packageName)
14674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                    == packageManager.PERMISSION_GRANTED) {
14774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                packages.add(packageName);
14874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                if (DBG) log("getSystemAppForIntent: added package " + packageName);
14974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            }
15074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
15174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        return packages;
15274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
15374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
15474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private void log(String message) {
15574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        Rlog.d(mLogTag, message);
15674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
15774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
15874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private void loge(String message) {
15974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        Rlog.e(mLogTag, message);
16074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
16174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
16274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private void logv(String message) {
16374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        Rlog.e(mLogTag, message);
16474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
16574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
16674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    /**
16774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     * Result of filtering SMS is returned in this callback.
16874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     */
169311e8950a8e2662422d999c5bda4f90cca7bf39aAbhijith Shastry    @VisibleForTesting
170311e8950a8e2662422d999c5bda4f90cca7bf39aAbhijith Shastry    public interface CarrierServicesSmsFilterCallbackInterface {
17174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        void onFilterComplete(int result);
17274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
17374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
17474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    /**
17574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     * Asynchronously binds to the carrier messaging service, and filters out the message if
17674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     * instructed to do so by the carrier messaging service. A new instance must be used for every
17774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     * message.
17874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     */
17974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private final class CarrierSmsFilter extends CarrierMessagingServiceManager {
18074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        private final byte[][] mPdus;
18174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        private final int mDestPort;
18274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        private final String mSmsFormat;
18374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        // Instantiated in filterSms.
18474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        private volatile CarrierSmsFilterCallback mSmsFilterCallback;
18574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
18674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        CarrierSmsFilter(byte[][] pdus, int destPort, String smsFormat) {
18774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            mPdus = pdus;
18874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            mDestPort = destPort;
18974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            mSmsFormat = smsFormat;
19074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
19174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
19274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        /**
19374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry         * Attempts to bind to a {@link ICarrierMessagingService}. Filtering is initiated
19474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry         * asynchronously once the service is ready using {@link #onServiceReady}.
19574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry         */
19674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        void filterSms(String carrierPackageName, CarrierSmsFilterCallback smsFilterCallback) {
19774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            mSmsFilterCallback = smsFilterCallback;
19874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            if (!bindToCarrierMessagingService(mContext, carrierPackageName)) {
19974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                loge("bindService() for carrier messaging service failed");
20074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                smsFilterCallback.onFilterComplete(CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT);
20174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            } else {
20274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                logv("bindService() for carrier messaging service succeeded");
20374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            }
20474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
20574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
20674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        /**
20774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry         * Invokes the {@code carrierMessagingService} to filter messages. The filtering result is
20874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry         * delivered to {@code smsFilterCallback}.
20974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry         */
21074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        @Override
21174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        protected void onServiceReady(ICarrierMessagingService carrierMessagingService) {
21274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            try {
21374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                carrierMessagingService.filterSms(
2144256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala                        new MessagePdu(Arrays.asList(mPdus)), mSmsFormat, mDestPort,
2154256e499c8e1e0a07998dcaf1f3aa127b693fc42Madhusudhan R. Adupala                        mPhone.getSubId(), mSmsFilterCallback);
21674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            } catch (RemoteException e) {
21774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                loge("Exception filtering the SMS: " + e);
21874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                mSmsFilterCallback.onFilterComplete(
21974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry                        CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT);
22074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            }
22174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
22274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
22374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
22474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    /**
22574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     * A callback used to notify the platform of the carrier messaging app filtering result. Once
22674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     * the result is ready, the carrier messaging service connection is disposed.
22774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry     */
22874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    private final class CarrierSmsFilterCallback extends ICarrierMessagingCallback.Stub {
22999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        private final FilterAggregator mFilterAggregator;
23074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        private final CarrierMessagingServiceManager mCarrierMessagingServiceManager;
23174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
23299462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        CarrierSmsFilterCallback(FilterAggregator filterAggregator,
23399462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                                 CarrierMessagingServiceManager carrierMessagingServiceManager) {
23499462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            mFilterAggregator = filterAggregator;
23574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            mCarrierMessagingServiceManager = carrierMessagingServiceManager;
23674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
23774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
23874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        /**
23974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry         * This method should be called only once.
24074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry         */
24174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        @Override
24274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        public void onFilterComplete(int result) {
24374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            mCarrierMessagingServiceManager.disposeConnection(mContext);
24499462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            mFilterAggregator.onFilterComplete(result);
24574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
24674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
24774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        @Override
24874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        public void onSendSmsComplete(int result, int messageRef) {
24974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            loge("Unexpected onSendSmsComplete call with result: " + result);
25074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
25174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
25274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        @Override
25374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        public void onSendMultipartSmsComplete(int result, int[] messageRefs) {
25474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            loge("Unexpected onSendMultipartSmsComplete call with result: " + result);
25574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
25674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
25774da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        @Override
25874da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        public void onSendMmsComplete(int result, byte[] sendConfPdu) {
25974da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            loge("Unexpected onSendMmsComplete call with result: " + result);
26074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
26174da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry
26274da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        @Override
26374da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        public void onDownloadMmsComplete(int result) {
26474da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry            loge("Unexpected onDownloadMmsComplete call with result: " + result);
26574da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry        }
26674da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry    }
26799462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry
26899462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry    private final class FilterAggregator {
26999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        private final Object mFilterLock = new Object();
27099462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        private int mNumPendingFilters;
27199462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        private int mFilterResult;
27299462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry
27399462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        FilterAggregator(int numFilters) {
27499462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            mNumPendingFilters = numFilters;
27599462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            mFilterResult = CarrierMessagingService.RECEIVE_OPTIONS_DEFAULT;
27699462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        }
27799462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry
27899462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        void onFilterComplete(int result) {
27999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            synchronized (mFilterLock) {
28099462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                mNumPendingFilters--;
28199462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                combine(result);
28299462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                if (mNumPendingFilters == 0) {
28399462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                    // Calling identity was the CarrierMessagingService in this callback, change it
28499462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                    // back to ours.
28599462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                    long token = Binder.clearCallingIdentity();
28699462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                    try {
28799462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                        mCarrierServicesSmsFilterCallback.onFilterComplete(mFilterResult);
28899462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                    } finally {
28999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                        // return back to the CarrierMessagingService, restore the calling identity.
29099462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                        Binder.restoreCallingIdentity(token);
29199462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                    }
29299462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry                }
29399462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            }
29499462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        }
29599462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry
29699462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        private void combine(int result) {
29799462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry            mFilterResult = mFilterResult | result;
29899462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry        }
29999462ddf1fa86f86b283507ddddbd576c5d3b6bbAbhijith Shastry    }
30074da2b4a09ab735c7538cf1610fa302135c4ec1bAbhijith Shastry}
301