19a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri/*
29a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * Copyright (C) 2015 The Android Open Source Project
39a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri *
49a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
59a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * in compliance with the License. You may obtain a copy of the License at
69a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri *
79a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * http://www.apache.org/licenses/LICENSE-2.0
89a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri *
99a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * Unless required by applicable law or agreed to in writing, software distributed under the License
109a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
119a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * or implied. See the License for the specific language governing permissions and limitations under
129a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * the License.
139a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri */
149a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
159a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseripackage android.service.carrier;
169a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
17ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynnimport android.annotation.CallSuper;
189a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseriimport android.app.Service;
199a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseriimport android.content.Intent;
209a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseriimport android.os.IBinder;
214f9ad1678eca240afb5a2174dc35e4f0559312c3Jonathan Basseriimport android.os.PersistableBundle;
22ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynnimport android.os.RemoteException;
23ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynnimport android.os.ServiceManager;
24ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn
25ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynnimport com.android.internal.telephony.ITelephonyRegistry;
269a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
279a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri/**
2842ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson * A service that exposes carrier-specific functionality to the system.
299a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * <p>
309a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * To extend this class, you must declare the service in your manifest file to require the
31cdaaa91f7c67b2c56f17d5512f015c7c25c7c351Zach Johnson * {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission and include an intent
3208a244cee8ff946233b0719540573c36249dc505Zach Johnson * filter with the {@link #CARRIER_SERVICE_INTERFACE}. If the service should have a long-lived
3308a244cee8ff946233b0719540573c36249dc505Zach Johnson * binding, set android.service.carrier.LONG_LIVED_BINDING to true in the service's metadata.
345c04bd767b23bb7f9faa0eeb9b9ab4c5525c6ea7Zach Johnson * For example:
359a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * </p>
369a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri *
379a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * <pre>{@code
3842ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson * <service android:name=".MyCarrierService"
399a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri *       android:label="@string/service_name"
40cdaaa91f7c67b2c56f17d5512f015c7c25c7c351Zach Johnson *       android:permission="android.permission.BIND_CARRIER_SERVICES">
419a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri *  <intent-filter>
4208a244cee8ff946233b0719540573c36249dc505Zach Johnson *      <action android:name="android.service.carrier.CarrierService" />
439a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri *  </intent-filter>
4408a244cee8ff946233b0719540573c36249dc505Zach Johnson *  <meta-data android:name="android.service.carrier.LONG_LIVED_BINDING"
4508a244cee8ff946233b0719540573c36249dc505Zach Johnson *             android:value="true" />
469a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * </service>
479a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri * }</pre>
489a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri */
4942ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnsonpublic abstract class CarrierService extends Service {
509a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
5108a244cee8ff946233b0719540573c36249dc505Zach Johnson    public static final String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService";
529a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
53ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn    private static ITelephonyRegistry sRegistry;
54ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn
5542ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson    private final ICarrierService.Stub mStubWrapper;
569a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
5742ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson    public CarrierService() {
5842ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson        mStubWrapper = new ICarrierServiceWrapper();
59ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn        if (sRegistry == null) {
60ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn            sRegistry = ITelephonyRegistry.Stub.asInterface(
61ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn                    ServiceManager.getService("telephony.registry"));
62ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn        }
639a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri    }
649a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
659a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri    /**
669a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * Override this method to set carrier configuration.
679a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * <p>
689a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * This method will be called by telephony services to get carrier-specific configuration
699a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * values. The returned config will be saved by the system until,
709a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * <ol>
719a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * <li>The carrier app package is updated, or</li>
729a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * <li>The carrier app requests a reload with
735ea0c8f1c660630edcdd5abdac076f7df69a7f8aJonathan Basseri     * {@link android.telephony.CarrierConfigManager#notifyConfigChangedForSubId
745ea0c8f1c660630edcdd5abdac076f7df69a7f8aJonathan Basseri     * notifyConfigChangedForSubId}.</li>
759a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * </ol>
769a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * This method can be called after a SIM card loads, which may be before or after boot.
779a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * </p>
789a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * <p>
799a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * This method should not block for a long time. If expensive operations (e.g. network access)
809a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * are required, this method can schedule the work and return null. Then, use
815ea0c8f1c660630edcdd5abdac076f7df69a7f8aJonathan Basseri     * {@link android.telephony.CarrierConfigManager#notifyConfigChangedForSubId
825ea0c8f1c660630edcdd5abdac076f7df69a7f8aJonathan Basseri     * notifyConfigChangedForSubId} to trigger a reload when the config is ready.
839a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * </p>
849a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * <p>
859a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * Implementations should use the keys defined in {@link android.telephony.CarrierConfigManager
864f9ad1678eca240afb5a2174dc35e4f0559312c3Jonathan Basseri     * CarrierConfigManager}. Any configuration values not set in the returned {@link
874f9ad1678eca240afb5a2174dc35e4f0559312c3Jonathan Basseri     * PersistableBundle} may be overridden by the system's default configuration service.
889a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * </p>
899a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     *
909a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     * @param id contains details about the current carrier that can be used do decide what
919a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     *            configuration values to return.
924f9ad1678eca240afb5a2174dc35e4f0559312c3Jonathan Basseri     * @return a {@link PersistableBundle} object containing the configuration or null if default
934f9ad1678eca240afb5a2174dc35e4f0559312c3Jonathan Basseri     *         values should be used.
949a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     */
954f9ad1678eca240afb5a2174dc35e4f0559312c3Jonathan Basseri    public abstract PersistableBundle onLoadConfig(CarrierIdentifier id);
969a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
97ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn    /**
98ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * Informs the system of an intentional upcoming carrier network change by
99ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * a carrier app. This call is optional and is only used to allow the
100ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * system to provide alternative UI while telephony is performing an action
101ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * that may result in intentional, temporary network lack of connectivity.
102ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * <p>
103ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * Based on the active parameter passed in, this method will either show or
104ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * hide the alternative UI. There is no timeout associated with showing
105ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * this UX, so a carrier app must be sure to call with active set to false
106ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * sometime after calling with it set to true.
107ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * <p>
108ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * Requires Permission:
109ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
110ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * Or the calling app has carrier privileges.
111ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     *   @see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}
112ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     *
113ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * @param active Whether the carrier network change is or shortly will be
114ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     *               active. Set this value to true to begin showing
115ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     *               alternative UI and false to stop.
116ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     */
117ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn    public final void notifyCarrierNetworkChange(boolean active) {
118ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn        try {
119ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn            if (sRegistry != null) sRegistry.notifyCarrierNetworkChange(active);
120ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn        } catch (RemoteException | NullPointerException ex) {}
121ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn    }
122ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn
123ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn    /**
124ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * If overriding this method, call through to the super method for any unknown actions.
125ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     * {@inheritDoc}
126ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn     */
1279a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri    @Override
128ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn    @CallSuper
129ceaed68b074bd341ed9b5f13ff9cc69e3f533999Andrew Flynn    public IBinder onBind(Intent intent) {
13008a244cee8ff946233b0719540573c36249dc505Zach Johnson        return mStubWrapper;
1319a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri    }
1329a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri
1339a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri    /**
13442ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson     * A wrapper around ICarrierService that forwards calls to implementations of
13542ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson     * {@link CarrierService}.
1369a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri     */
13742ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson    private class ICarrierServiceWrapper extends ICarrierService.Stub {
1389a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri        @Override
1394f9ad1678eca240afb5a2174dc35e4f0559312c3Jonathan Basseri        public PersistableBundle getCarrierConfig(CarrierIdentifier id) {
14042ecc9eb902ef90876cd345a906c24e0d58720a3Zach Johnson            return CarrierService.this.onLoadConfig(id);
1419a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri        }
1429a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri    }
1439a1c9b67c4b2426884deb60c1ff84130ab47333cJonathan Basseri}
144