diff options
| -rw-r--r-- | api/system-current.txt | 16 | ||||
| -rw-r--r-- | core/java/android/app/SystemServiceRegistry.java | 4 | ||||
| -rw-r--r-- | core/java/android/content/Context.java | 3 | ||||
| -rw-r--r-- | core/java/android/service/carrier/CarrierService.java | 2 | ||||
| -rw-r--r-- | core/java/android/telephony/PhoneStateListener.java (renamed from telephony/java/android/telephony/PhoneStateListener.java) | 2 | ||||
| -rw-r--r-- | core/java/android/telephony/TelephonyRegistryManager.java (renamed from core/java/android/os/telephony/TelephonyRegistryManager.java) | 152 | ||||
| -rw-r--r-- | core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl (renamed from telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl) | 0 | ||||
| -rw-r--r-- | core/java/com/android/internal/telephony/IPhoneStateListener.aidl (renamed from telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl) | 3 | ||||
| -rw-r--r-- | core/java/com/android/internal/telephony/ITelephonyRegistry.aidl (renamed from telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl) | 0 | ||||
| -rw-r--r-- | telephony/java/android/telephony/SubscriptionManager.java | 131 |
10 files changed, 209 insertions, 104 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 6e3520017db4..117be3bb4c7a 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5691,14 +5691,6 @@ package android.os.storage { } -package android.os.telephony { - - public class TelephonyRegistryManager { - method public void notifyCarrierNetworkChange(boolean); - } - -} - package android.permission { public final class PermissionControllerManager { @@ -8379,6 +8371,14 @@ package android.telephony { field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0 } + public class TelephonyRegistryManager { + method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor); + method public void addOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor); + method public void notifyCarrierNetworkChange(boolean); + method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); + method public void removeOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); + } + public final class UiccAccessRule implements android.os.Parcelable { ctor public UiccAccessRule(byte[], @Nullable String, long); method public int describeContents(); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index e81dc1c59040..8350fa13b097 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -152,7 +152,7 @@ import android.os.health.SystemHealthManager; import android.os.image.DynamicSystemManager; import android.os.image.IDynamicSystemService; import android.os.storage.StorageManager; -import android.os.telephony.TelephonyRegistryManager; +import android.telephony.TelephonyRegistryManager; import android.permission.PermissionControllerManager; import android.permission.PermissionManager; import android.print.IPrintManager; @@ -611,7 +611,7 @@ public final class SystemServiceRegistry { new CachedServiceFetcher<TelephonyRegistryManager>() { @Override public TelephonyRegistryManager createService(ContextImpl ctx) { - return new TelephonyRegistryManager(); + return new TelephonyRegistryManager(ctx); }}); registerService(Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class, diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index e7e278f431ba..3eb066e9d99e 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -63,6 +63,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; import android.provider.MediaStore; +import android.telephony.TelephonyRegistryManager; import android.util.AttributeSet; import android.view.Display; import android.view.DisplayAdjustments; @@ -4716,7 +4717,7 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve an - * {@link android.os.telephony.TelephonyRegistryManager}. + * {@link TelephonyRegistryManager}. * @hide */ @SystemApi diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java index 9184d6d51f44..eefc1b70bac9 100644 --- a/core/java/android/service/carrier/CarrierService.java +++ b/core/java/android/service/carrier/CarrierService.java @@ -22,7 +22,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.PersistableBundle; import android.os.ResultReceiver; -import android.os.telephony.TelephonyRegistryManager; +import android.telephony.TelephonyRegistryManager; import android.util.Log; /** diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 1ba0a41024ed..a65c8fdf50c9 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -35,8 +35,8 @@ import android.telephony.Annotation.SrvccState; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IPhoneStateListener; +import com.android.internal.annotations.VisibleForTesting; import dalvik.system.VMRuntime; diff --git a/core/java/android/os/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 133233124b70..64d612405c34 100644 --- a/core/java/android/os/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -13,12 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.os.telephony; +package android.telephony; +import android.annotation.CallbackExecutor; +import android.annotation.NonNull; import android.annotation.SystemApi; +import android.content.Context; import android.net.LinkProperties; import android.net.NetworkCapabilities; +import android.os.Binder; import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerExecutor; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.Annotation.ApnType; @@ -40,8 +46,15 @@ import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.ims.ImsReasonInfo; +import android.util.Log; + import com.android.internal.telephony.ITelephonyRegistry; +import com.android.internal.telephony.IOnSubscriptionsChangedListener; + +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; /** * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update @@ -58,9 +71,26 @@ public class TelephonyRegistryManager { private static final String TAG = "TelephonyRegistryManager"; private static ITelephonyRegistry sRegistry; + private final Context mContext; + + /** + * A mapping between {@link SubscriptionManager.OnSubscriptionsChangedListener} and + * its callback IOnSubscriptionsChangedListener. + */ + private final Map<SubscriptionManager.OnSubscriptionsChangedListener, + IOnSubscriptionsChangedListener> mSubscriptionChangedListenerMap = new HashMap<>(); + /** + * A mapping between {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} and + * its callback IOnSubscriptionsChangedListener. + */ + private final Map<SubscriptionManager.OnOpportunisticSubscriptionsChangedListener, + IOnSubscriptionsChangedListener> mOpportunisticSubscriptionChangedListenerMap + = new HashMap<>(); + /** @hide **/ - public TelephonyRegistryManager() { + public TelephonyRegistryManager(@NonNull Context context) { + mContext = context; if (sRegistry == null) { sRegistry = ITelephonyRegistry.Stub.asInterface( ServiceManager.getService("telephony.registry")); @@ -68,6 +98,113 @@ public class TelephonyRegistryManager { } /** + * Register for changes to the list of active {@link SubscriptionInfo} records or to the + * individual records themselves. When a change occurs the onSubscriptionsChanged method of + * the listener will be invoked immediately if there has been a notification. The + * onSubscriptionChanged method will also be triggered once initially when calling this + * function. + * + * @param listener an instance of {@link SubscriptionManager.OnSubscriptionsChangedListener} + * with onSubscriptionsChanged overridden. + * @param executor the executor that will execute callbacks. + */ + public void addOnSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener, + @NonNull Executor executor) { + IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { + @Override + public void onSubscriptionsChanged () { + Log.d(TAG, "onSubscriptionsChangedListener callback received."); + executor.execute(() -> listener.onSubscriptionsChanged()); + } + }; + mSubscriptionChangedListenerMap.put(listener, callback); + try { + sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), callback); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Unregister the {@link SubscriptionManager.OnSubscriptionsChangedListener}. This is not + * strictly necessary as the listener will automatically be unregistered if an attempt to + * invoke the listener fails. + * + * @param listener that is to be unregistered. + */ + public void removeOnSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener) { + if (mSubscriptionChangedListenerMap.get(listener) == null) { + return; + } + try { + sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(), + mSubscriptionChangedListenerMap.get(listener)); + mSubscriptionChangedListenerMap.remove(listener); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Register for changes to the list of opportunistic subscription records or to the + * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged + * method of the listener will be invoked immediately if there has been a notification. + * + * @param listener an instance of + * {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} with + * onOpportunisticSubscriptionsChanged overridden. + * @param executor an Executor that will execute callbacks. + */ + public void addOnOpportunisticSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener, + @NonNull Executor executor) { + /** + * The callback methods need to be called on the executor thread where + * this object was created. If the binder did that for us it'd be nice. + */ + IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { + @Override + public void onSubscriptionsChanged() { + final long identity = Binder.clearCallingIdentity(); + try { + Log.d(TAG, "onOpportunisticSubscriptionsChanged callback received."); + executor.execute(() -> listener.onOpportunisticSubscriptionsChanged()); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + }; + mOpportunisticSubscriptionChangedListenerMap.put(listener, callback); + try { + sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(), + callback); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Unregister the {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} + * that is currently listening opportunistic subscriptions change. This is not strictly + * necessary as the listener will automatically be unregistered if an attempt to invoke the + * listener fails. + * + * @param listener that is to be unregistered. + */ + public void removeOnOpportunisticSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener) { + try { + sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(), + mOpportunisticSubscriptionChangedListenerMap.get(listener)); + mOpportunisticSubscriptionChangedListenerMap.remove(listener); + } catch (RemoteException ex) { + // system server crash + } + } + + /** * Informs the system of an intentional upcoming carrier network change by a carrier app. * This call only used to allow the system to provide alternative UI while telephony is * performing an action that may result in intentional, temporary network lack of connectivity. @@ -546,4 +683,15 @@ public class TelephonyRegistryManager { } } + /** + * @param activeDataSubId + * @hide + */ + public void notifyActiveDataSubIdChanged(int activeDataSubId) { + try { + sRegistry.notifyActiveDataSubIdChanged(activeDataSubId); + } catch (RemoteException ex) { + + } + } } diff --git a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl b/core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl index 493b1ff6aba7..493b1ff6aba7 100644 --- a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl +++ b/core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index 90019eef62fd..084a3cc64a35 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -29,6 +29,9 @@ import android.telephony.SignalStrength; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; +/** + * {@hide} + */ oneway interface IPhoneStateListener { void onServiceStateChanged(in ServiceState serviceState); void onSignalStrengthChanged(int asu); diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index d7a7af1d530f..d7a7af1d530f 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 40d057ffd6fe..8425ec13b282 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -47,6 +47,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; @@ -58,10 +59,8 @@ import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; import android.util.Log; -import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ISetOpportunisticDataCallback; import com.android.internal.telephony.ISub; -import com.android.internal.telephony.ITelephonyRegistry; import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.Preconditions; @@ -923,20 +922,24 @@ public class SubscriptionManager { OnSubscriptionsChangedListenerHandler(Looper looper) { super(looper); } - - @Override - public void handleMessage(Message msg) { - if (DBG) { - log("handleMessage: invoke the overriden onSubscriptionsChanged()"); - } - OnSubscriptionsChangedListener.this.onSubscriptionsChanged(); - } } - private final Handler mHandler; + /** + * Posted executor callback on the handler associated with a given looper. + * The looper can be the calling thread's looper or the looper passed from the + * constructor {@link #OnSubscriptionsChangedListener(Looper)}. + */ + private final HandlerExecutor mExecutor; + + /** + * @hide + */ + public HandlerExecutor getHandlerExecutor() { + return mExecutor; + } public OnSubscriptionsChangedListener() { - mHandler = new OnSubscriptionsChangedListenerHandler(); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler()); } /** @@ -945,7 +948,7 @@ public class SubscriptionManager { * @hide */ public OnSubscriptionsChangedListener(Looper looper) { - mHandler = new OnSubscriptionsChangedListenerHandler(looper); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper)); } /** @@ -957,18 +960,6 @@ public class SubscriptionManager { if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN"); } - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - */ - IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { - @Override - public void onSubscriptionsChanged() { - if (DBG) log("callback: received, sendEmptyMessage(0) to handler"); - mHandler.sendEmptyMessage(0); - } - }; - private void log(String s) { Rlog.d(LOG_TAG, s); } @@ -1010,21 +1001,19 @@ public class SubscriptionManager { * onSubscriptionsChanged overridden. */ public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + if (listener == null) return; String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (DBG) { logd("register OnSubscriptionsChangedListener pkgName=" + pkgName + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available. Where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.addOnSubscriptionsChangedListener(pkgName, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available. Where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.addOnSubscriptionsChangedListener(listener, + listener.mExecutor); } } @@ -1036,21 +1025,18 @@ public class SubscriptionManager { * @param listener that is to be unregistered. */ public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + if (listener == null) return; String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (DBG) { logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener); } } @@ -1069,7 +1055,6 @@ public class SubscriptionManager { * for #onOpportunisticSubscriptionsChanged to be invoked. */ public static class OnOpportunisticSubscriptionsChangedListener { - private Executor mExecutor; /** * Callback invoked when there is any change to any SubscriptionInfo. Typically * this method would invoke {@link #getActiveSubscriptionInfoList} @@ -1078,27 +1063,6 @@ public class SubscriptionManager { if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN"); } - private void setExecutor(Executor executor) { - mExecutor = executor; - } - - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - */ - IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { - @Override - public void onSubscriptionsChanged() { - final long identity = Binder.clearCallingIdentity(); - try { - if (DBG) log("onOpportunisticSubscriptionsChanged callback received."); - mExecutor.execute(() -> onOpportunisticSubscriptionsChanged()); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - }; - private void log(String s) { Rlog.d(LOG_TAG, s); } @@ -1125,18 +1089,13 @@ public class SubscriptionManager { + " listener=" + listener); } - listener.setExecutor(executor); - - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available. Where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.addOnOpportunisticSubscriptionsChangedListener(pkgName, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener( + listener, executor); } } @@ -1156,16 +1115,10 @@ public class SubscriptionManager { logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener); } } |