Home | History | Annotate | Download | only in mms
      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 android.support.v7.mms;
     18 
     19 import android.app.PendingIntent;
     20 import android.content.Context;
     21 import android.net.Uri;
     22 import android.os.Bundle;
     23 import android.telephony.SmsManager;
     24 import android.util.SparseArray;
     25 
     26 /**
     27  * The public interface of MMS library
     28  */
     29 public class MmsManager {
     30     /**
     31      * Default subscription ID
     32      */
     33     public static final int DEFAULT_SUB_ID = -1;
     34 
     35     // Whether to force legacy MMS sending
     36     private static volatile boolean sForceLegacyMms = false;
     37 
     38     // Cached computed overrides for carrier configuration values
     39     private static SparseArray<Bundle> sConfigOverridesMap = new SparseArray<>();
     40 
     41     /**
     42      * Set the flag about whether to force to use legacy system APIs instead of system MMS API
     43      *
     44      * @param forceLegacyMms value to set
     45      */
     46     public static void setForceLegacyMms(boolean forceLegacyMms) {
     47         sForceLegacyMms = forceLegacyMms;
     48     }
     49 
     50     /**
     51      * Set the size of thread pool for request execution.
     52      *
     53      * Default is 4
     54      *
     55      * Note: if system MMS API is used, this has no effect
     56      *
     57      * @param size thread pool size
     58      */
     59     public static void setThreadPoolSize(int size) {
     60         MmsService.setThreadPoolSize(size);
     61     }
     62 
     63     /**
     64      * Set whether to use wake lock while sending or downloading MMS.
     65      *
     66      * Default value is true
     67      *
     68      * Note: if system MMS API is used, this has no effect
     69      *
     70      * @param useWakeLock true to use wake lock, false otherwise
     71      */
     72     public static void setUseWakeLock(final boolean useWakeLock) {
     73         MmsService.setUseWakeLock(useWakeLock);
     74     }
     75 
     76     /**
     77      * Set the optional carrier config values loader
     78      *
     79      * Note: if system MMS API is used, this is used to compute the overrides
     80      * of carrier configuration values
     81      *
     82      * @param loader the carrier config values loader
     83      */
     84     public static void setCarrierConfigValuesLoader(CarrierConfigValuesLoader loader) {
     85         if (loader == null) {
     86             throw new IllegalArgumentException("Carrier configuration loader can not be empty");
     87         }
     88         synchronized (sConfigOverridesMap) {
     89             MmsService.setCarrierConfigValuesLoader(loader);
     90             sConfigOverridesMap.clear();
     91         }
     92     }
     93 
     94     /**
     95      * Set the optional APN settings loader
     96      *
     97      * Note: if system MMS API is used, this has no effect
     98      *
     99      * @param loader the APN settings loader
    100      */
    101     public static void setApnSettingsLoader(ApnSettingsLoader loader) {
    102         if (loader == null) {
    103             throw new IllegalArgumentException("APN settings loader can not be empty");
    104         }
    105         MmsService.setApnSettingsLoader(loader);
    106     }
    107 
    108     /**
    109      * Set user agent info loader
    110      *
    111      * Note: if system MMS API is used, this is used to compute the overrides
    112      * of carrier configuration values
    113 
    114      * @param loader the user agent info loader
    115      */
    116     public static void setUserAgentInfoLoader(final UserAgentInfoLoader loader) {
    117         if (loader == null) {
    118             throw new IllegalArgumentException("User agent info loader can not be empty");
    119         }
    120         synchronized (sConfigOverridesMap) {
    121             MmsService.setUserAgentInfoLoader(loader);
    122             sConfigOverridesMap.clear();
    123         }
    124     }
    125 
    126     /**
    127      * Send MMS via platform MMS API (if platform supports and not forced to
    128      * use legacy APIs) or legacy APIs
    129      *
    130      * @param subId the subscription ID of the SIM to use
    131      * @param context the Context to use
    132      * @param contentUri the content URI of the PDU to be sent
    133      * @param locationUrl the optional location URL to use for sending
    134      * @param sentIntent the pending intent for returning results
    135      */
    136     public static void sendMultimediaMessage(int subId, Context context, Uri contentUri,
    137             String locationUrl, PendingIntent sentIntent) {
    138         if (Utils.hasMmsApi() && !sForceLegacyMms) {
    139             subId = Utils.getEffectiveSubscriptionId(subId);
    140             final SmsManager smsManager = Utils.getSmsManager(subId);
    141             smsManager.sendMultimediaMessage(context, contentUri, locationUrl,
    142                     getConfigOverrides(subId), sentIntent);
    143         } else {
    144             MmsService.startRequest(context, new SendRequest(locationUrl, contentUri, sentIntent));
    145         }
    146     }
    147 
    148     /**
    149      * Download MMS via platform MMS API (if platform supports and not forced to
    150      * use legacy APIs) or legacy APIs
    151      *
    152      * @param subId the subscription ID of the SIM to use
    153      * @param context the Context to use
    154      * @param contentUri the content URI of the PDU to be sent
    155      * @param locationUrl the optional location URL to use for sending
    156      * @param downloadedIntent the pending intent for returning results
    157      */
    158     public static void downloadMultimediaMessage(int subId, Context context, String locationUrl,
    159             Uri contentUri, PendingIntent downloadedIntent) {
    160         if (Utils.hasMmsApi() && !sForceLegacyMms) {
    161             subId = Utils.getEffectiveSubscriptionId(subId);
    162             final SmsManager smsManager = Utils.getSmsManager(subId);
    163             smsManager.downloadMultimediaMessage(context, locationUrl, contentUri,
    164                     getConfigOverrides(subId), downloadedIntent);
    165         } else {
    166             MmsService.startRequest(context,
    167                     new DownloadRequest(locationUrl, contentUri, downloadedIntent));
    168         }
    169     }
    170 
    171     /**
    172      * Get carrier configuration values overrides when platform MMS API is called.
    173      * We only need to compute this if customized carrier config values loader or
    174      * user agent info loader are set
    175      *
    176      * @param subId the ID of the SIM to use
    177      * @return a Bundle containing the overrides
    178      */
    179     private static Bundle getConfigOverrides(final int subId) {
    180         if (!Utils.hasMmsApi()) {
    181             // If MMS API is not present, it is not necessary to compute overrides
    182             return null;
    183         }
    184         Bundle overrides = null;
    185         synchronized (sConfigOverridesMap) {
    186             overrides = sConfigOverridesMap.get(subId);
    187             if (overrides == null) {
    188                 overrides = new Bundle();
    189                 sConfigOverridesMap.put(subId, overrides);
    190                 computeOverridesLocked(subId, overrides);
    191             }
    192         }
    193         return overrides;
    194     }
    195 
    196     /**
    197      * Compute the overrides, incorporating the user agent info
    198      *
    199      * @param subId the subId of the SIM to use
    200      * @param overrides the computed values overrides
    201      */
    202     private static void computeOverridesLocked(final int subId, final Bundle overrides) {
    203         // Overrides not computed yet
    204         final CarrierConfigValuesLoader carrierConfigValuesLoader =
    205                 MmsService.getCarrierConfigValuesLoader();
    206         if (carrierConfigValuesLoader != null &&
    207                 !(carrierConfigValuesLoader instanceof DefaultCarrierConfigValuesLoader)) {
    208             // Compute the overrides for carrier config values first if the config loader
    209             // is not the default one.
    210             final Bundle systemValues = Utils.getSmsManager(subId).getCarrierConfigValues();
    211             final Bundle callerValues =
    212                     MmsService.getCarrierConfigValuesLoader().get(subId);
    213             if (systemValues != null && callerValues != null) {
    214                 computeConfigDelta(systemValues, callerValues, overrides);
    215             } else if (systemValues == null && callerValues != null) {
    216                 overrides.putAll(callerValues);
    217             }
    218         }
    219         final UserAgentInfoLoader userAgentInfoLoader = MmsService.getUserAgentInfoLoader();
    220         if (userAgentInfoLoader != null &&
    221                 !(userAgentInfoLoader instanceof DefaultUserAgentInfoLoader)) {
    222             // Also set the user agent and ua prof url via the overrides
    223             // if the user agent loader is not the default one.
    224             overrides.putString(UserAgentInfoLoader.CONFIG_USER_AGENT,
    225                     userAgentInfoLoader.getUserAgent());
    226             overrides.putString(UserAgentInfoLoader.CONFIG_UA_PROF_URL,
    227                     userAgentInfoLoader.getUAProfUrl());
    228         }
    229     }
    230 
    231     /**
    232      * Compute the delta between two sets of carrier configuration values: system and caller
    233      *
    234      * @param systemValues the system config values
    235      * @param callerValues the caller's config values
    236      * @param delta the delta of values (caller - system), using caller value to override system's
    237      */
    238     private static void computeConfigDelta(final Bundle systemValues, final Bundle callerValues,
    239             final Bundle delta) {
    240         for (final String key : callerValues.keySet()) {
    241             final Object callerValue = callerValues.get(key);
    242             final Object systemValue = systemValues.get(key);
    243             if ((callerValue != null && systemValue != null && !callerValue.equals(systemValue)) ||
    244                     (callerValue != null && systemValue == null) ||
    245                     (callerValue == null && systemValue != null)) {
    246                 if (callerValue == null || callerValue instanceof String) {
    247                     delta.putString(key, (String) callerValue);
    248                 } else if (callerValue instanceof Integer) {
    249                     delta.putInt(key, (Integer) callerValue);
    250                 } else if (callerValue instanceof Boolean) {
    251                     delta.putBoolean(key, (Boolean) callerValue);
    252                 }
    253             }
    254         }
    255     }
    256 }
    257