diff options
author | Tyler Gunn <tgunn@google.com> | 2014-09-17 12:19:39 -0700 |
---|---|---|
committer | Tyler Gunn <tgunn@google.com> | 2014-09-17 12:19:39 -0700 |
commit | 91d43cf9c985cc5a83795f256ef5c46ebb8fbdc1 (patch) | |
tree | 14551cd3cc9a0de2e96bffe1e8499c0b297d748b /src/com/android/server | |
parent | b3c4b285b747c58bfa58e2c58e09cdfb2c2b03b8 (diff) | |
download | android_packages_services_Telecomm-91d43cf9c985cc5a83795f256ef5c46ebb8fbdc1.tar.gz android_packages_services_Telecomm-91d43cf9c985cc5a83795f256ef5c46ebb8fbdc1.tar.bz2 android_packages_services_Telecomm-91d43cf9c985cc5a83795f256ef5c46ebb8fbdc1.zip |
Preparatory work to move Telecom to system service.
- Removed use of TelecomApp.getInstance() as context.
- Refactored singleton logic and initialization to support being
performed from a SystemService.
- Note: You will see some commented out references to
"import com.android.internal.R"; these must uncommented when the code
is moved to a system service.
- You will also notice in PhoneAccountRegistrar.java a comment block with:
"UNCOMMENT_FOR_MOVE_TO_SYSTEM_SERVICE"
The code in that comment block will replace the existing file path
code.
These were added as a convenience so that I can run a simple sed script
to make the required changes to the code in an automated manner once it
is moved to its new location.
Bug: 17364651
Change-Id: I8e80e9cffc481b688c10a2bca0b59f5ccf8e0fb2
Diffstat (limited to 'src/com/android/server')
30 files changed, 418 insertions, 206 deletions
diff --git a/src/com/android/server/telecom/AsyncRingtonePlayer.java b/src/com/android/server/telecom/AsyncRingtonePlayer.java index 343abfbd..44344243 100644 --- a/src/com/android/server/telecom/AsyncRingtonePlayer.java +++ b/src/com/android/server/telecom/AsyncRingtonePlayer.java @@ -16,6 +16,7 @@ package com.android.server.telecom; +import android.content.Context; import android.media.AudioManager; import android.media.Ringtone; import android.media.RingtoneManager; @@ -25,7 +26,7 @@ import android.os.HandlerThread; import android.os.Message; import android.provider.Settings; -import com.google.common.base.Preconditions; +import com.android.internal.util.Preconditions; /** * Plays the default ringtone. Uses {@link Ringtone} in a separate thread so that this class can be @@ -46,6 +47,15 @@ class AsyncRingtonePlayer { /** The current ringtone. Only used by the ringtone thread. */ private Ringtone mRingtone; + /** + * The context. + */ + private final Context mContext; + + AsyncRingtonePlayer(Context context) { + mContext = context; + } + /** Plays the ringtone. */ void play(Uri ringtone) { Log.d(this, "Posting play."); @@ -185,7 +195,7 @@ class AsyncRingtonePlayer { ringtoneUri = Settings.System.DEFAULT_RINGTONE_URI; } - Ringtone ringtone = RingtoneManager.getRingtone(TelecomApp.getInstance(), ringtoneUri); + Ringtone ringtone = RingtoneManager.getRingtone(mContext, ringtoneUri); ringtone.setStreamType(AudioManager.STREAM_RING); return ringtone; } diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java index 906be744..7d4223a0 100644 --- a/src/com/android/server/telecom/Call.java +++ b/src/com/android/server/telecom/Call.java @@ -16,6 +16,7 @@ package com.android.server.telecom; +import android.content.Context; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -44,7 +45,7 @@ import com.android.internal.telephony.CallerInfoAsyncQuery.OnQueryCompleteListen import com.android.internal.telephony.SmsApplication; import com.android.server.telecom.ContactsAsyncHelper.OnImageLoadCompleteListener; -import com.google.common.base.Preconditions; +import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.Collections; @@ -275,10 +276,13 @@ final class Call implements CreateConnectionResponse { private boolean mIsVoipAudioMode; private StatusHints mStatusHints; private final ConnectionServiceRepository mRepository; + private final Context mContext; /** * Persists the specified parameters and initializes the new instance. * + * @param context The context. + * @param repository The connection service repository. * @param handle The handle to dial. * @param gatewayInfo Gateway information to use for the call. * @param connectionManagerPhoneAccountHandle Account to use for the service managing the call. @@ -289,6 +293,7 @@ final class Call implements CreateConnectionResponse { * @param isIncoming True if this is an incoming call. */ Call( + Context context, ConnectionServiceRepository repository, Uri handle, GatewayInfo gatewayInfo, @@ -297,6 +302,7 @@ final class Call implements CreateConnectionResponse { boolean isIncoming, boolean isConference) { mState = isConference ? CallState.ACTIVE : CallState.NEW; + mContext = context; mRepository = repository; setHandle(handle); setHandle(handle, TelecomManager.PRESENTATION_ALLOWED); @@ -384,8 +390,8 @@ final class Call implements CreateConnectionResponse { if (!Objects.equals(handle, mHandle) || presentation != mHandlePresentation) { mHandle = handle; mHandlePresentation = presentation; - mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber( - TelecomApp.getInstance(), mHandle.getSchemeSpecificPart()); + mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber(mContext, + mHandle.getSchemeSpecificPart()); startCallerInfoLookup(); for (Listener l : mListeners) { l.onHandleChanged(this); @@ -543,6 +549,15 @@ final class Call implements CreateConnectionResponse { return mConnectionService; } + /** + * Retrieves the {@link Context} for the call. + * + * @return The {@link Context}. + */ + Context getContext() { + return mContext; + } + void setConnectionService(ConnectionServiceWrapper service) { Preconditions.checkNotNull(service); @@ -597,10 +612,13 @@ final class Call implements CreateConnectionResponse { /** * Starts the create connection sequence. Upon completion, there should exist an active * connection through a connection service (or the call will have failed). + * + * @param phoneAccountRegistrar The phone account registrar. */ - void startCreateConnection() { + void startCreateConnection(PhoneAccountRegistrar phoneAccountRegistrar) { Preconditions.checkState(mCreateConnectionProcessor == null); - mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this); + mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this, + phoneAccountRegistrar, mContext); mCreateConnectionProcessor.process(); } @@ -635,7 +653,8 @@ final class Call implements CreateConnectionResponse { // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before // showing the user the incoming call screen. - mHandler.postDelayed(mDirectToVoicemailRunnable, Timeouts.getDirectToVoicemailMillis()); + mHandler.postDelayed(mDirectToVoicemailRunnable, Timeouts.getDirectToVoicemailMillis( + mContext.getContentResolver())); } else { for (Listener l : mListeners) { l.onSuccessfulOutgoingCall(this, @@ -955,7 +974,7 @@ final class Call implements CreateConnectionResponse { } // Is there a valid SMS application on the phone? - if (SmsApplication.getDefaultRespondViaMessageApplication(TelecomApp.getInstance(), + if (SmsApplication.getDefaultRespondViaMessageApplication(mContext, true /*updateIfNeeded*/) == null) { return false; } @@ -1015,7 +1034,7 @@ final class Call implements CreateConnectionResponse { Log.v(this, "Looking up information for: %s.", Log.piiHandle(number)); CallerInfoAsyncQuery.startQuery( mQueryToken, - TelecomApp.getInstance(), + mContext, number, sCallerInfoQueryListener, this); @@ -1041,7 +1060,7 @@ final class Call implements CreateConnectionResponse { mCallerInfo.contactDisplayPhotoUri, this); ContactsAsyncHelper.startObtainPhotoAsync( token, - TelecomApp.getInstance(), + mContext, mCallerInfo.contactDisplayPhotoUri, sPhotoLoadListener, this); @@ -1100,7 +1119,8 @@ final class Call implements CreateConnectionResponse { Log.w(Call.this, "Error obtaining canned SMS responses: %d %s", code, msg); } - } + }, + mContext ); } else { Log.d(this, "maybeLoadCannedSmsResponses: doing nothing"); diff --git a/src/com/android/server/telecom/CallActivity.java b/src/com/android/server/telecom/CallActivity.java index 96ffb96c..a4dc1a8e 100644 --- a/src/com/android/server/telecom/CallActivity.java +++ b/src/com/android/server/telecom/CallActivity.java @@ -32,6 +32,8 @@ import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.widget.Toast; +// TODO: Needed for move to system service: import com.android.internal.R; + /** * Activity that handles system CALL actions and forwards them to {@link CallsManager}. * Handles all three CALL action types: CALL, CALL_PRIVILEGED, and CALL_EMERGENCY. @@ -159,7 +161,7 @@ public class CallActivity extends Activity { setResult(RESULT_CANCELED); } else { NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster( - mCallsManager, call, intent, isDefaultDialer()); + this, mCallsManager, call, intent, isDefaultDialer()); final int result = broadcaster.processIntent(); final boolean success = result == DisconnectCause.NOT_DISCONNECTED; diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java index 312f58f1..e3b2e421 100644 --- a/src/com/android/server/telecom/CallAudioManager.java +++ b/src/com/android/server/telecom/CallAudioManager.java @@ -21,7 +21,7 @@ import android.media.AudioManager; import android.telecom.AudioState; import android.telecom.CallState; -import com.google.common.base.Preconditions; +import com.android.internal.util.Preconditions; import java.util.Objects; diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java index 47046474..89d93163 100644 --- a/src/com/android/server/telecom/CallLogManager.java +++ b/src/com/android/server/telecom/CallLogManager.java @@ -26,6 +26,7 @@ import android.telecom.PhoneAccountHandle; import android.telecom.VideoProfile; import android.telephony.PhoneNumberUtils; +// TODO: Needed for move to system service: import com.android.internal.R; import com.android.internal.telephony.CallerInfo; import com.android.internal.telephony.PhoneConstants; diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java index 6936c5ce..420bdf84 100644 --- a/src/com/android/server/telecom/CallsManager.java +++ b/src/com/android/server/telecom/CallsManager.java @@ -16,6 +16,7 @@ package com.android.server.telecom; +import android.content.Context; import android.net.Uri; import android.os.Bundle; @@ -30,6 +31,7 @@ import android.telecom.PhoneCapabilities; import android.telephony.TelephonyManager; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.IndentingPrintWriter; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; @@ -68,7 +70,12 @@ public final class CallsManager extends Call.ListenerBase { void onVideoStateChanged(Call call); } - private static final CallsManager INSTANCE = new CallsManager(); + /** + * Singleton instance of the {@link CallsManager}, initialized from {@link TelecomService}. + */ + private static CallsManager INSTANCE = null; + + private static final String TAG = "CallsManager"; private static final int MAXIMUM_LIVE_CALLS = 1; private static final int MAXIMUM_HOLD_CALLS = 1; @@ -92,10 +99,9 @@ public final class CallsManager extends Call.ListenerBase { private final Set<Call> mCalls = Collections.newSetFromMap( new ConcurrentHashMap<Call, Boolean>(8, 0.9f, 1)); - private final ConnectionServiceRepository mConnectionServiceRepository = - new ConnectionServiceRepository(); - private final DtmfLocalTonePlayer mDtmfLocalTonePlayer = new DtmfLocalTonePlayer(); - private final InCallController mInCallController = new InCallController(); + private final ConnectionServiceRepository mConnectionServiceRepository; + private final DtmfLocalTonePlayer mDtmfLocalTonePlayer; + private final InCallController mInCallController; private final CallAudioManager mCallAudioManager; private final Ringer mRinger; // For this set initial table size to 16 because we add 13 listeners in @@ -108,6 +114,9 @@ public final class CallsManager extends Call.ListenerBase { private final ProximitySensorManager mProximitySensorManager; private final PhoneStateBroadcaster mPhoneStateBroadcaster; private final CallLogManager mCallLogManager; + private final Context mContext; + private final PhoneAccountRegistrar mPhoneAccountRegistrar; + private final MissedCallNotifier mMissedCallNotifier; /** * The call the user is currently interacting with. This is the call that should have audio @@ -121,21 +130,36 @@ public final class CallsManager extends Call.ListenerBase { } /** - * Initializes the required Telecom components. + * Sets the static singleton instance. + * + * @param instance The instance to set. */ - private CallsManager() { - TelecomApp app = TelecomApp.getInstance(); + static void initialize(CallsManager instance) { + INSTANCE = instance; + } - StatusBarNotifier statusBarNotifier = new StatusBarNotifier(app, this); - mWiredHeadsetManager = new WiredHeadsetManager(app); - mCallAudioManager = new CallAudioManager(app, statusBarNotifier, mWiredHeadsetManager); + /** + * Initializes the required Telecom components. + */ + CallsManager(Context context, MissedCallNotifier missedCallNotifier, + PhoneAccountRegistrar phoneAccountRegistrar) { + mContext = context; + mPhoneAccountRegistrar = phoneAccountRegistrar; + mMissedCallNotifier = missedCallNotifier; + StatusBarNotifier statusBarNotifier = new StatusBarNotifier(context, this); + mWiredHeadsetManager = new WiredHeadsetManager(context); + mCallAudioManager = new CallAudioManager(context, statusBarNotifier, mWiredHeadsetManager); InCallTonePlayer.Factory playerFactory = new InCallTonePlayer.Factory(mCallAudioManager); - mRinger = new Ringer(mCallAudioManager, this, playerFactory, app); - mHeadsetMediaButton = new HeadsetMediaButton(app, this); - mTtyManager = new TtyManager(app, mWiredHeadsetManager); - mProximitySensorManager = new ProximitySensorManager(app); + mRinger = new Ringer(mCallAudioManager, this, playerFactory, context); + mHeadsetMediaButton = new HeadsetMediaButton(context, this); + mTtyManager = new TtyManager(context, mWiredHeadsetManager); + mProximitySensorManager = new ProximitySensorManager(context); mPhoneStateBroadcaster = new PhoneStateBroadcaster(); - mCallLogManager = new CallLogManager(app); + mCallLogManager = new CallLogManager(context); + mInCallController = new InCallController(context); + mDtmfLocalTonePlayer = new DtmfLocalTonePlayer(context); + mConnectionServiceRepository = new ConnectionServiceRepository(mPhoneAccountRegistrar, + context); mListeners.add(statusBarNotifier); mListeners.add(mCallLogManager); @@ -145,7 +169,7 @@ public final class CallsManager extends Call.ListenerBase { mListeners.add(new RingbackPlayer(this, playerFactory)); mListeners.add(new InCallToneMonitor(playerFactory, this)); mListeners.add(mCallAudioManager); - mListeners.add(app.getMissedCallNotifier()); + mListeners.add(missedCallNotifier); mListeners.add(mDtmfLocalTonePlayer); mListeners.add(mHeadsetMediaButton); mListeners.add(RespondViaSmsManager.getInstance()); @@ -188,8 +212,7 @@ public final class CallsManager extends Call.ListenerBase { incomingCall.reject(false, null); // since the call was not added to the list of calls, we have to call the missed // call notifier and the call logger manually. - TelecomApp.getInstance().getMissedCallNotifier() - .showMissedCallNotification(incomingCall); + mMissedCallNotifier.showMissedCallNotification(incomingCall); mCallLogManager.logCall(incomingCall, Calls.MISSED_TYPE); } else { addCall(incomingCall); @@ -290,6 +313,7 @@ public final class CallsManager extends Call.ListenerBase { Log.d(this, "processIncomingCallIntent"); Uri handle = extras.getParcelable(TelephonyManager.EXTRA_INCOMING_NUMBER); Call call = new Call( + mContext, mConnectionServiceRepository, handle, null /* gatewayInfo */, @@ -301,7 +325,7 @@ public final class CallsManager extends Call.ListenerBase { call.setExtras(extras); // TODO: Move this to be a part of addCall() call.addListener(this); - call.startCreateConnection(); + call.startCreateConnection(mPhoneAccountRegistrar); } /** @@ -313,14 +337,12 @@ public final class CallsManager extends Call.ListenerBase { * @param extras The optional extras Bundle passed with the intent used for the incoming call. */ Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras) { - TelecomApp app = TelecomApp.getInstance(); - // Only dial with the requested phoneAccount if it is still valid. Otherwise treat this call // as if a phoneAccount was not specified (does the default behavior instead). // Note: We will not attempt to dial with a requested phoneAccount if it is disabled. if (phoneAccountHandle != null) { List<PhoneAccountHandle> accounts = - app.getPhoneAccountRegistrar().getCallCapablePhoneAccounts(handle.getScheme()); + mPhoneAccountRegistrar.getCallCapablePhoneAccounts(handle.getScheme()); if (!accounts.contains(phoneAccountHandle)) { phoneAccountHandle = null; } @@ -330,7 +352,7 @@ public final class CallsManager extends Call.ListenerBase { // No preset account, check if default exists that supports the URI scheme for the // handle. PhoneAccountHandle defaultAccountHandle = - app.getPhoneAccountRegistrar().getDefaultOutgoingPhoneAccount( + mPhoneAccountRegistrar.getDefaultOutgoingPhoneAccount( handle.getScheme()); if (defaultAccountHandle != null) { phoneAccountHandle = defaultAccountHandle; @@ -340,6 +362,7 @@ public final class CallsManager extends Call.ListenerBase { // Create a call with original handle. The handle may be changed when the call is attached // to a connection service, but in most cases will remain the same. Call call = new Call( + mContext, mConnectionServiceRepository, handle, null /* gatewayInfo */, @@ -349,7 +372,8 @@ public final class CallsManager extends Call.ListenerBase { false /* isConference */); call.setExtras(extras); - boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(app, call.getHandle()); + boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(mContext, + call.getHandle()); // Do not support any more live calls. Our options are to move a call to hold, disconnect // a call, or cancel this call altogether. @@ -405,8 +429,8 @@ public final class CallsManager extends Call.ListenerBase { call.setStartWithSpeakerphoneOn(speakerphoneOn); call.setVideoState(videoState); - TelecomApp app = TelecomApp.getInstance(); - boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(app, call.getHandle()); + boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(mContext, + call.getHandle()); if (isEmergencyCall) { // Emergency -- CreateConnectionProcessor will choose accounts automatically call.setTargetPhoneAccount(null); @@ -415,7 +439,7 @@ public final class CallsManager extends Call.ListenerBase { if (call.getTargetPhoneAccount() != null || isEmergencyCall) { // If the account has been set, proceed to place the outgoing call. // Otherwise the connection will be initiated when the account is set by the user. - call.startCreateConnection(); + call.startCreateConnection(mPhoneAccountRegistrar); } } @@ -628,7 +652,7 @@ public final class CallsManager extends Call.ListenerBase { // Note: emergency calls never go through account selection dialog so they never // arrive here. if (makeRoomForOutgoingCall(call, false /* isEmergencyCall */)) { - call.startCreateConnection(); + call.startCreateConnection(mPhoneAccountRegistrar); } else { call.disconnect(); } @@ -800,6 +824,7 @@ public final class CallsManager extends Call.ListenerBase { PhoneAccountHandle phoneAccount, ParcelableConference parcelableConference) { Call call = new Call( + mContext, mConnectionServiceRepository, null /* handle */, null /* gatewayInfo */, @@ -828,6 +853,23 @@ public final class CallsManager extends Call.ListenerBase { } /** + * Retrieves the {@link PhoneAccountRegistrar}. + * + * @return The {@link PhoneAccountRegistrar}. + */ + PhoneAccountRegistrar getPhoneAccountRegistrar() { + return mPhoneAccountRegistrar; + } + + /** + * Retrieves the {@link MissedCallNotifier} + * @return The {@link MissedCallNotifier}. + */ + MissedCallNotifier getMissedCallNotifier() { + return mMissedCallNotifier; + } + + /** * Adds the specified call to the main list of live calls. * * @param call The call to add. @@ -1018,4 +1060,23 @@ public final class CallsManager extends Call.ListenerBase { } return true; } + + /** + * Dumps the state of the {@link CallsManager}. + * + * @param pw The {@code IndentingPrintWriter} to write the state to. + */ + public void dump(IndentingPrintWriter pw) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); + pw.increaseIndent(); + if (mCalls != null) { + pw.println("mCalls: "); + pw.increaseIndent(); + for (Call call : mCalls) { + pw.println(call); + } + pw.decreaseIndent(); + } + pw.decreaseIndent(); + } } diff --git a/src/com/android/server/telecom/ConnectionServiceRepository.java b/src/com/android/server/telecom/ConnectionServiceRepository.java index d7a6d3e6..e9a447dc 100644 --- a/src/com/android/server/telecom/ConnectionServiceRepository.java +++ b/src/com/android/server/telecom/ConnectionServiceRepository.java @@ -17,6 +17,7 @@ package com.android.server.telecom; import android.content.ComponentName; +import android.content.Context; import java.util.HashMap; @@ -27,8 +28,12 @@ final class ConnectionServiceRepository implements ServiceBinder.Listener<ConnectionServiceWrapper> { private final HashMap<ComponentName, ConnectionServiceWrapper> mServiceCache = new HashMap<ComponentName, ConnectionServiceWrapper>(); + private final PhoneAccountRegistrar mPhoneAccountRegistrar; + private final Context mContext; - ConnectionServiceRepository() { + ConnectionServiceRepository(PhoneAccountRegistrar phoneAccountRegistrar, Context context) { + mPhoneAccountRegistrar = phoneAccountRegistrar; + mContext = context; } ConnectionServiceWrapper getService(ComponentName componentName) { @@ -37,7 +42,8 @@ final class ConnectionServiceRepository service = new ConnectionServiceWrapper( componentName, this, - TelecomApp.getInstance().getPhoneAccountRegistrar()); + mPhoneAccountRegistrar, + mContext); service.addListener(this); mServiceCache.put(componentName, service); } diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java index e77b8967..efa01e94 100644 --- a/src/com/android/server/telecom/ConnectionServiceWrapper.java +++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java @@ -17,6 +17,7 @@ package com.android.server.telecom; import android.content.ComponentName; +import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -42,7 +43,7 @@ import com.android.internal.telecom.IConnectionService; import com.android.internal.telecom.IConnectionServiceAdapter; import com.android.internal.telecom.IVideoProvider; import com.android.internal.telecom.RemoteServiceCallback; -import com.google.common.base.Preconditions; +import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.Collections; @@ -560,6 +561,7 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> { private Binder mBinder = new Binder(); private IConnectionService mServiceInterface; private final ConnectionServiceRepository mConnectionServiceRepository; + private final PhoneAccountRegistrar mPhoneAccountRegistrar; /** * Creates a connection service. @@ -567,17 +569,20 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> { * @param componentName The component name of the service with which to bind. * @param connectionServiceRepository Connection service repository. * @param phoneAccountRegistrar Phone account registrar + * @param context The context. */ ConnectionServiceWrapper( ComponentName componentName, ConnectionServiceRepository connectionServiceRepository, - PhoneAccountRegistrar phoneAccountRegistrar) { - super(ConnectionService.SERVICE_INTERFACE, componentName); + PhoneAccountRegistrar phoneAccountRegistrar, + Context context) { + super(ConnectionService.SERVICE_INTERFACE, componentName, context); mConnectionServiceRepository = connectionServiceRepository; phoneAccountRegistrar.addListener(new PhoneAccountRegistrar.Listener() { // TODO -- Upon changes to PhoneAccountRegistrar, need to re-wire connections // To do this, we must proxy remote ConnectionService objects }); + mPhoneAccountRegistrar = phoneAccountRegistrar; } /** See {@link IConnectionService#addConnectionServiceAdapter}. */ @@ -913,11 +918,9 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> { } private void queryRemoteConnectionServices(final RemoteServiceCallback callback) { - PhoneAccountRegistrar registrar = TelecomApp.getInstance().getPhoneAccountRegistrar(); - // Only give remote connection services to this connection service if it is listed as // the connection manager. - PhoneAccountHandle simCallManager = registrar.getSimCallManager(); + PhoneAccountHandle simCallManager = mPhoneAccountRegistrar.getSimCallManager(); Log.d(this, "queryRemoteConnectionServices finds simCallManager = %s", simCallManager); if (simCallManager == null || !simCallManager.getComponentName().equals(getComponentName())) { @@ -928,8 +931,8 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> { // Make a list of ConnectionServices that are listed as being associated with SIM accounts final Set<ConnectionServiceWrapper> simServices = Collections.newSetFromMap( new ConcurrentHashMap<ConnectionServiceWrapper, Boolean>(8, 0.9f, 1)); - for (PhoneAccountHandle handle : registrar.getCallCapablePhoneAccounts()) { - PhoneAccount account = registrar.getPhoneAccount(handle); + for (PhoneAccountHandle handle : mPhoneAccountRegistrar.getCallCapablePhoneAccounts()) { + PhoneAccount account = mPhoneAccountRegistrar.getPhoneAccount(handle); if ((account.getCapabilities() & PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0) { ConnectionServiceWrapper service = mConnectionServiceRepository.getService(handle.getComponentName()); diff --git a/src/com/android/server/telecom/ContactsAsyncHelper.java b/src/com/android/server/telecom/ContactsAsyncHelper.java index aa99ac35..1fbf5eec 100644 --- a/src/com/android/server/telecom/ContactsAsyncHelper.java +++ b/src/com/android/server/telecom/ContactsAsyncHelper.java @@ -27,6 +27,8 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Message; +// TODO: Needed for move to system service: import com.android.internal.R; + import java.io.IOException; import java.io.InputStream; diff --git a/src/com/android/server/telecom/CreateConnectionProcessor.java b/src/com/android/server/telecom/CreateConnectionProcessor.java index c0198816..6adb72cb 100644 --- a/src/com/android/server/telecom/CreateConnectionProcessor.java +++ b/src/com/android/server/telecom/CreateConnectionProcessor.java @@ -16,11 +16,15 @@ package com.android.server.telecom; +import android.content.Context; import android.telecom.DisconnectCause; import android.telecom.ParcelableConnection; +import android.telecom.Phone; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; +// TODO: Needed for move to system service: import com.android.internal.R; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -83,12 +87,17 @@ final class CreateConnectionProcessor { private Iterator<CallAttemptRecord> mAttemptRecordIterator; private CreateConnectionResponse mResponse; private DisconnectCause mLastErrorDisconnectCause; + private final PhoneAccountRegistrar mPhoneAccountRegistrar; + private final Context mContext; CreateConnectionProcessor( - Call call, ConnectionServiceRepository repository, CreateConnectionResponse response) { + Call call, ConnectionServiceRepository repository, CreateConnectionResponse response, + PhoneAccountRegistrar phoneAccountRegistrar, Context context) { mCall = call; mRepository = repository; mResponse = response; + mPhoneAccountRegistrar = phoneAccountRegistrar; + mContext = context; } void process() { @@ -124,12 +133,12 @@ final class CreateConnectionProcessor { private void attemptNextPhoneAccount() { Log.v(this, "attemptNextPhoneAccount"); - PhoneAccountRegistrar registrar = TelecomApp.getInstance().getPhoneAccountRegistrar(); CallAttemptRecord attempt = null; if (mAttemptRecordIterator.hasNext()) { attempt = mAttemptRecordIterator.next(); - if (!registrar.phoneAccountHasPermission(attempt.connectionManagerPhoneAccount)) { + if (!mPhoneAccountRegistrar.phoneAccountHasPermission( + attempt.connectionManagerPhoneAccount)) { Log.w(this, "Connection mgr does not have BIND_CONNECTION_SERVICE for attempt: %s", attempt); @@ -140,7 +149,7 @@ final class CreateConnectionProcessor { // If the target PhoneAccount differs from the ConnectionManager phone acount, ensure it // also has BIND_CONNECTION_SERVICE permission. if (!attempt.connectionManagerPhoneAccount.equals(attempt.targetPhoneAccount) && - !registrar.phoneAccountHasPermission(attempt.targetPhoneAccount)) { + !mPhoneAccountRegistrar.phoneAccountHasPermission(attempt.targetPhoneAccount)) { Log.w(this, "Target PhoneAccount does not have BIND_CONNECTION_SERVICE for attempt: %s", attempt); @@ -185,8 +194,7 @@ final class CreateConnectionProcessor { return false; } - PhoneAccountRegistrar registrar = TelecomApp.getInstance().getPhoneAccountRegistrar(); - PhoneAccountHandle connectionManager = registrar.getSimCallManager(); + PhoneAccountHandle connectionManager = mPhoneAccountRegistrar.getSimCallManager(); if (connectionManager == null) { return false; } @@ -197,7 +205,8 @@ final class CreateConnectionProcessor { } // Connection managers are only allowed to manage SIM subscriptions. - PhoneAccount targetPhoneAccount = registrar.getPhoneAccount(targetPhoneAccountHandle); + PhoneAccount targetPhoneAccount = mPhoneAccountRegistrar.getPhoneAccount( + targetPhoneAccountHandle); boolean isSimSubscription = (targetPhoneAccount.getCapabilities() & PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0; if (!isSimSubscription) { @@ -211,7 +220,7 @@ final class CreateConnectionProcessor { private void adjustAttemptsForConnectionManager() { if (shouldSetConnectionManager()) { CallAttemptRecord record = new CallAttemptRecord( - TelecomApp.getInstance().getPhoneAccountRegistrar().getSimCallManager(), + mPhoneAccountRegistrar.getSimCallManager(), mAttemptRecords.get(0).targetPhoneAccount); Log.v(this, "setConnectionManager, changing %s -> %s", mAttemptRecords.get(0).targetPhoneAccount, record); @@ -224,11 +233,10 @@ final class CreateConnectionProcessor { // If we are possibly attempting to call a local emergency number, ensure that the // plain PSTN connection services are listed, and nothing else. private void adjustAttemptsForEmergency() { - if (TelephonyUtil.shouldProcessAsEmergency(TelecomApp.getInstance(), mCall.getHandle())) { + if (TelephonyUtil.shouldProcessAsEmergency(mContext, mCall.getHandle())) { Log.i(this, "Emergency number detected"); mAttemptRecords.clear(); - List<PhoneAccount> allAccounts = TelecomApp.getInstance() - .getPhoneAccountRegistrar().getAllPhoneAccounts(); + List<PhoneAccount> allAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts(); // First, add SIM phone accounts which can place emergency calls. for (PhoneAccount phoneAccount : allAccounts) { if (phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS) && @@ -243,14 +251,13 @@ final class CreateConnectionProcessor { } // Next, add the connection manager account as a backup if it can place emergency calls. - PhoneAccountHandle callManagerHandle = TelecomApp.getInstance() - .getPhoneAccountRegistrar().getSimCallManager(); + PhoneAccountHandle callManagerHandle = mPhoneAccountRegistrar.getSimCallManager(); if (callManagerHandle != null) { - PhoneAccount callManager = TelecomApp.getInstance() - .getPhoneAccountRegistrar().getPhoneAccount(callManagerHandle); + PhoneAccount callManager = mPhoneAccountRegistrar + .getPhoneAccount(callManagerHandle); if (callManager.hasCapabilities(PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)) { CallAttemptRecord callAttemptRecord = new CallAttemptRecord(callManagerHandle, - TelecomApp.getInstance().getPhoneAccountRegistrar(). + mPhoneAccountRegistrar. getDefaultOutgoingPhoneAccount(mCall.getHandle().getScheme()) ); diff --git a/src/com/android/server/telecom/DtmfLocalTonePlayer.java b/src/com/android/server/telecom/DtmfLocalTonePlayer.java index eb3f9a00..6b4b74de 100644 --- a/src/com/android/server/telecom/DtmfLocalTonePlayer.java +++ b/src/com/android/server/telecom/DtmfLocalTonePlayer.java @@ -16,10 +16,12 @@ package com.android.server.telecom; +import android.content.Context; import android.media.AudioManager; import android.media.ToneGenerator; import android.provider.Settings; +// TODO: Needed for move to system service: import com.android.internal.R; import com.google.common.collect.ImmutableMap; import java.util.Map; @@ -53,6 +55,13 @@ class DtmfLocalTonePlayer extends CallsManagerListenerBase { /** The current call associated with an existing dtmf session. */ private Call mCall; + /** The context. */ + private final Context mContext; + + public DtmfLocalTonePlayer(Context context) { + mContext = context; + } + /** {@inheritDoc} */ @Override public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) { @@ -110,12 +119,11 @@ class DtmfLocalTonePlayer extends CallsManagerListenerBase { if (call == null) { return; } - TelecomApp app = TelecomApp.getInstance(); - + final Context context = call.getContext(); final boolean areLocalTonesEnabled; - if (app.getResources().getBoolean(R.bool.allow_local_dtmf_tones)) { + if (context.getResources().getBoolean(R.bool.allow_local_dtmf_tones)) { areLocalTonesEnabled = Settings.System.getInt( - app.getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1; + context.getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1; } else { areLocalTonesEnabled = false; } diff --git a/src/com/android/server/telecom/ErrorDialogActivity.java b/src/com/android/server/telecom/ErrorDialogActivity.java index 0e6bca01..a669f101 100644 --- a/src/com/android/server/telecom/ErrorDialogActivity.java +++ b/src/com/android/server/telecom/ErrorDialogActivity.java @@ -22,6 +22,8 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +// TODO: Needed for move to system service: import com.android.internal.R; + /** * Used to display an error dialog from within the Telecom service when an outgoing call fails */ diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java index a80d9afe..2dc30da2 100644 --- a/src/com/android/server/telecom/InCallController.java +++ b/src/com/android/server/telecom/InCallController.java @@ -38,6 +38,7 @@ import android.telecom.PhoneCapabilities; import android.telecom.TelecomManager; import android.util.ArrayMap; +// TODO: Needed for move to system service: import com.android.internal.R; import com.android.internal.telecom.IInCallService; import com.google.common.collect.ImmutableCollection; @@ -135,9 +136,11 @@ public final class InCallController extends CallsManagerListenerBase { /** The {@link ComponentName} of the default InCall UI. */ private final ComponentName mInCallComponentName; - public InCallController() { - Context context = TelecomApp.getInstance(); - Resources resources = context.getResources(); + private final Context mContext; + + public InCallController(Context context) { + mContext = context; + Resources resources = mContext.getResources(); mInCallComponentName = new ComponentName( resources.getString(R.string.ui_default_package), @@ -245,7 +248,7 @@ public final class InCallController extends CallsManagerListenerBase { mServiceConnections.entrySet().iterator(); while (iterator.hasNext()) { Log.i(this, "Unbinding from InCallService %s"); - TelecomApp.getInstance().unbindService(iterator.next().getValue()); + mContext.unbindService(iterator.next().getValue()); iterator.remove(); } mInCallServices.clear(); @@ -259,8 +262,8 @@ public final class InCallController extends CallsManagerListenerBase { ThreadUtil.checkOnMainThread(); if (mInCallServices.isEmpty()) { mServiceConnections.clear(); - Context context = TelecomApp.getInstance(); - PackageManager packageManager = TelecomApp.getInstance().getPackageManager(); + + PackageManager packageManager = mContext.getPackageManager(); Intent serviceIntent = new Intent(InCallService.SERVICE_INTERFACE); for (ResolveInfo entry : packageManager.queryIntentServices(serviceIntent, 0)) { @@ -295,7 +298,7 @@ public final class InCallController extends CallsManagerListenerBase { Intent intent = new Intent(InCallService.SERVICE_INTERFACE); intent.setComponent(componentName); - if (context.bindServiceAsUser(intent, inCallServiceConnection, + if (mContext.bindServiceAsUser(intent, inCallServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) { mServiceConnections.put(componentName, inCallServiceConnection); } @@ -359,7 +362,6 @@ public final class InCallController extends CallsManagerListenerBase { private void onDisconnected(ComponentName disconnectedComponent) { Log.i(this, "onDisconnected from %s", disconnectedComponent); ThreadUtil.checkOnMainThread(); - Context context = TelecomApp.getInstance(); if (mInCallServices.containsKey(disconnectedComponent)) { mInCallServices.remove(disconnectedComponent); @@ -382,7 +384,7 @@ public final class InCallController extends CallsManagerListenerBase { mServiceConnections.get(disconnectedComponent); // We still need to call unbind even though it disconnected. - context.unbindService(serviceConnection); + mContext.unbindService(serviceConnection); mServiceConnections.remove(disconnectedComponent); mInCallServices.remove(disconnectedComponent); diff --git a/src/com/android/server/telecom/Log.java b/src/com/android/server/telecom/Log.java index ff3c8ce3..6e3ff6de 100644 --- a/src/com/android/server/telecom/Log.java +++ b/src/com/android/server/telecom/Log.java @@ -48,82 +48,82 @@ public class Log { public static void d(String prefix, String format, Object... args) { if (DEBUG) { - android.util.Log.d(TAG, buildMessage(prefix, format, args)); + android.util.Slog.d(TAG, buildMessage(prefix, format, args)); } } public static void d(Object objectPrefix, String format, Object... args) { if (DEBUG) { - android.util.Log.d(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); + android.util.Slog.d(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); } } public static void i(String prefix, String format, Object... args) { if (INFO) { - android.util.Log.i(TAG, buildMessage(prefix, format, args)); + android.util.Slog.i(TAG, buildMessage(prefix, format, args)); } } public static void i(Object objectPrefix, String format, Object... args) { if (INFO) { - android.util.Log.i(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); + android.util.Slog.i(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); } } public static void v(String prefix, String format, Object... args) { if (VERBOSE) { - android.util.Log.v(TAG, buildMessage(prefix, format, args)); + android.util.Slog.v(TAG, buildMessage(prefix, format, args)); } } public static void v(Object objectPrefix, String format, Object... args) { if (VERBOSE) { - android.util.Log.v(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); + android.util.Slog.v(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); } } public static void w(String prefix, String format, Object... args) { if (WARN) { - android.util.Log.w(TAG, buildMessage(prefix, format, args)); + android.util.Slog.w(TAG, buildMessage(prefix, format, args)); } } public static void w(Object objectPrefix, String format, Object... args) { if (WARN) { - android.util.Log.w(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); + android.util.Slog.w(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); } } public static void e(String prefix, Throwable tr, String format, Object... args) { if (ERROR) { - android.util.Log.e(TAG, buildMessage(prefix, format, args), tr); + android.util.Slog.e(TAG, buildMessage(prefix, format, args), tr); } } public static void e(Object objectPrefix, Throwable tr, String format, Object... args) { if (ERROR) { - android.util.Log.e(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args), + android.util.Slog.e(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args), tr); } } public static void wtf(String prefix, Throwable tr, String format, Object... args) { - android.util.Log.wtf(TAG, buildMessage(prefix, format, args), tr); + android.util.Slog.wtf(TAG, buildMessage(prefix, format, args), tr); } public static void wtf(Object objectPrefix, Throwable tr, String format, Object... args) { - android.util.Log.wtf(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args), + android.util.Slog.wtf(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args), tr); } public static void wtf(String prefix, String format, Object... args) { String msg = buildMessage(prefix, format, args); - android.util.Log.wtf(TAG, msg, new IllegalStateException(msg)); + android.util.Slog.wtf(TAG, msg, new IllegalStateException(msg)); } public static void wtf(Object objectPrefix, String format, Object... args) { String msg = buildMessage(getPrefixFromObject(objectPrefix), format, args); - android.util.Log.wtf(TAG, msg, new IllegalStateException(msg)); + android.util.Slog.wtf(TAG, msg, new IllegalStateException(msg)); } public static String piiHandle(Object pii) { diff --git a/src/com/android/server/telecom/MissedCallNotifier.java b/src/com/android/server/telecom/MissedCallNotifier.java index de6a423b..8abd5b7c 100644 --- a/src/com/android/server/telecom/MissedCallNotifier.java +++ b/src/com/android/server/telecom/MissedCallNotifier.java @@ -37,6 +37,8 @@ import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import android.text.TextUtils; +// TODO: Needed for move to system service: import com.android.internal.R; + /** * Creates a notification for calls that the user missed (neither answered nor rejected). * TODO: Make TelephonyManager.clearMissedCalls call into this class. @@ -284,7 +286,8 @@ class MissedCallNotifier extends CallsManagerListenerBase { } // Convert the data to a call object - Call call = new Call(null, null, null, null, null, true, false); + Call call = new Call(mContext, null, null, null, null, null, true, + false); call.setDisconnectCause(new DisconnectCause(DisconnectCause.MISSED)); call.setState(CallState.DISCONNECTED); diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java index 3fbe498b..cd2195c1 100644 --- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java +++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java @@ -31,6 +31,8 @@ import android.telephony.DisconnectCause; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; +// TODO: Needed for move to system service: import com.android.internal.R; + /** * OutgoingCallIntentBroadcaster receives CALL and CALL_PRIVILEGED Intents, and broadcasts the * ACTION_NEW_OUTGOING_CALL intent. ACTION_NEW_OUTGOING_CALL is an ordered broadcast intent which @@ -69,14 +71,17 @@ class NewOutgoingCallIntentBroadcaster { private final CallsManager mCallsManager; private final Call mCall; private final Intent mIntent; + private final Context mContext; + /* * Whether or not the outgoing call intent originated from the default phone application. If * so, it will be allowed to make emergency calls, even with the ACTION_CALL intent. */ private final boolean mIsDefaultOrSystemPhoneApp; - NewOutgoingCallIntentBroadcaster(CallsManager callsManager, Call call, Intent intent, - boolean isDefaultPhoneApp) { + NewOutgoingCallIntentBroadcaster(Context context, CallsManager callsManager, Call call, + Intent intent, boolean isDefaultPhoneApp) { + mContext = context; mCallsManager = callsManager; mCall = call; mIntent = intent; @@ -102,7 +107,7 @@ class NewOutgoingCallIntentBroadcaster { if (resultNumber == null) { Log.v(this, "Call cancelled (null number), returning..."); endEarly = true; - } else if (PhoneNumberUtils.isPotentialLocalEmergencyNumber(context, resultNumber)) { + } else if (PhoneNumberUtils.isPotentialLocalEmergencyNumber(mContext, resultNumber)) { Log.w(this, "Cannot modify outgoing call to emergency number %s.", resultNumber); endEarly = true; } @@ -153,8 +158,6 @@ class NewOutgoingCallIntentBroadcaster { int processIntent() { Log.v(this, "Processing call intent in OutgoingCallIntentBroadcaster."); - final Context context = TelecomApp.getInstance(); - Intent intent = mIntent; String action = intent.getAction(); final Uri handle = intent.getData(); @@ -183,7 +186,7 @@ class NewOutgoingCallIntentBroadcaster { } } - String number = PhoneNumberUtils.getNumberFromIntent(intent, context); + String number = PhoneNumberUtils.getNumberFromIntent(intent, mContext); if (TextUtils.isEmpty(number)) { Log.w(this, "Empty number obtained from the call intent."); return DisconnectCause.NO_PHONE_NUMBER_SUPPLIED; @@ -195,7 +198,7 @@ class NewOutgoingCallIntentBroadcaster { number = PhoneNumberUtils.stripSeparators(number); } - final boolean isPotentialEmergencyNumber = isPotentialEmergencyNumber(context, number); + final boolean isPotentialEmergencyNumber = isPotentialEmergencyNumber(number); Log.v(this, "isPotentialEmergencyNumber = %s", isPotentialEmergencyNumber); rewriteCallIntentAction(intent, isPotentialEmergencyNumber); @@ -209,7 +212,7 @@ class NewOutgoingCallIntentBroadcaster { if (!mIsDefaultOrSystemPhoneApp) { Log.w(this, "Cannot call potential emergency number %s with CALL Intent %s " + "unless caller is system or default dialer.", number, intent); - launchSystemDialer(context, intent.getData()); + launchSystemDialer(intent.getData()); return DisconnectCause.OUTGOING_CANCELED; } else { callImmediately = true; @@ -245,7 +248,7 @@ class NewOutgoingCallIntentBroadcaster { // initiate the call again because of the presence of the EXTRA_ALREADY_CALLED extra. } - broadcastIntent(intent, number, context, !callImmediately); + broadcastIntent(intent, number, !callImmediately); return DisconnectCause.NOT_DISCONNECTED; } @@ -255,14 +258,12 @@ class NewOutgoingCallIntentBroadcaster { * * @param originalCallIntent The original call intent. * @param number Call number that was stored in the original call intent. - * @param context Valid context to send the ordered broadcast using. * @param receiverRequired Whether or not the result from the ordered broadcast should be * processed using a {@link NewOutgoingCallIntentBroadcaster}. */ private void broadcastIntent( Intent originalCallIntent, String number, - Context context, boolean receiverRequired) { Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); if (number != null) { @@ -276,7 +277,7 @@ class NewOutgoingCallIntentBroadcaster { checkAndCopyProviderExtras(originalCallIntent, broadcastIntent); - context.sendOrderedBroadcastAsUser( + mContext.sendOrderedBroadcastAsUser( broadcastIntent, UserHandle.OWNER, PERMISSION, @@ -350,9 +351,9 @@ class NewOutgoingCallIntentBroadcaster { return null; } - private void launchSystemDialer(Context context, Uri handle) { + private void launchSystemDialer(Uri handle) { Intent systemDialerIntent = new Intent(); - final Resources resources = context.getResources(); + final Resources resources = mContext.getResources(); systemDialerIntent.setClassName( resources.getString(R.string.ui_default_package), resources.getString(R.string.dialer_default_class)); @@ -360,7 +361,7 @@ class NewOutgoingCallIntentBroadcaster { systemDialerIntent.setData(handle); systemDialerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Log.v(this, "calling startActivity for default dialer: %s", systemDialerIntent); - context.startActivity(systemDialerIntent); + mContext.startActivity(systemDialerIntent); } /** @@ -373,14 +374,14 @@ class NewOutgoingCallIntentBroadcaster { * still result in an emergency call with some networks), we use * isPotentialLocalEmergencyNumber instead of isLocalEmergencyNumber. * - * @param context Valid context * @param number number to inspect in order to determine whether or not an emergency number * is potentially being dialed * @return True if the handle is potentially an emergency number. */ - private boolean isPotentialEmergencyNumber(Context context, String number) { + private boolean isPotentialEmergencyNumber(String number) { Log.v(this, "Checking restrictions for number : %s", Log.pii(number)); - return (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(context,number); + return (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(mContext, + number); } /** diff --git a/src/com/android/server/telecom/PhoneAccountBroadcastReceiver.java b/src/com/android/server/telecom/PhoneAccountBroadcastReceiver.java index 6152befb..d2516b17 100644 --- a/src/com/android/server/telecom/PhoneAccountBroadcastReceiver.java +++ b/src/com/android/server/telecom/PhoneAccountBroadcastReceiver.java @@ -35,6 +35,16 @@ import java.lang.String; * the enabled state of the accounts is retained. */ public class PhoneAccountBroadcastReceiver extends BroadcastReceiver { + + /** + * The {@link PhoneAccountRegistrar}. + */ + private final PhoneAccountRegistrar mPhoneAccountRegistrar; + + public PhoneAccountBroadcastReceiver(PhoneAccountRegistrar phoneAccountRegistrar) { + mPhoneAccountRegistrar = phoneAccountRegistrar; + } + /** * Receives the intents the class is configured to received. * @@ -61,16 +71,6 @@ public class PhoneAccountBroadcastReceiver extends BroadcastReceiver { * @param packageName The name of the removed package. */ private void handlePackageRemoved(Context context, String packageName) { - TelecomApp telecomApp = TelecomApp.getInstance(); - if (telecomApp == null) { - return; - } - - PhoneAccountRegistrar registrar = telecomApp.getPhoneAccountRegistrar(); - if (registrar == null) { - return; - } - - registrar.clearAccounts(packageName); + mPhoneAccountRegistrar.clearAccounts(packageName); } } diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java index 4e098b42..e6aeac58 100644 --- a/src/com/android/server/telecom/PhoneAccountRegistrar.java +++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java @@ -21,6 +21,8 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; +import android.os.Environment; +import android.os.UserHandle; import android.provider.Settings; import android.telecom.ConnectionService; import android.telecom.PhoneAccount; @@ -33,6 +35,7 @@ import android.text.TextUtils; import android.util.AtomicFile; import android.util.Xml; +// TODO: Needed for move to system service: import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; @@ -94,8 +97,16 @@ public final class PhoneAccountRegistrar { @VisibleForTesting public PhoneAccountRegistrar(Context context, String fileName) { - // TODO: Change file location when Telecom is part of system + // TODO: This file path is subject to change -- it is storing the phone account registry + // state file in the path /data/system/users/0/, which is likely not correct in a + // multi-user setting. + /** UNCOMMENT_FOR_MOVE_TO_SYSTEM_SERVICE + String filePath = Environment.getUserSystemDirectory(UserHandle.myUserId()). + getAbsolutePath(); + mAtomicFile = new AtomicFile(new File(filePath, fileName)); + UNCOMMENT_FOR_MOVE_TO_SYSTEM_SERVICE */ mAtomicFile = new AtomicFile(new File(context.getFilesDir(), fileName)); + mState = new State(); mContext = context; read(); @@ -419,7 +430,7 @@ public final class PhoneAccountRegistrar { * @return {@code True} if the phone account has permission. */ public boolean phoneAccountHasPermission(PhoneAccountHandle phoneAccountHandle) { - PackageManager packageManager = TelecomApp.getInstance().getPackageManager(); + PackageManager packageManager = mContext.getPackageManager(); try { ServiceInfo serviceInfo = packageManager.getServiceInfo( phoneAccountHandle.getComponentName(), 0); diff --git a/src/com/android/server/telecom/QuickResponseUtils.java b/src/com/android/server/telecom/QuickResponseUtils.java index dad2907c..ec77b33e 100644 --- a/src/com/android/server/telecom/QuickResponseUtils.java +++ b/src/com/android/server/telecom/QuickResponseUtils.java @@ -21,6 +21,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Resources; +// TODO: Needed for move to system service: import com.android.internal.R; /** * Utils class that exposes some helper routines to used to manage the QuickResponses @@ -48,7 +49,7 @@ public class QuickResponseUtils { * current SharedPreferences. This is a lazy migration as it happens only when * the QuickResponse settings are viewed or if they are queried via RespondViaSmsManager. */ - public static void maybeMigrateLegacyQuickResponses() { + public static void maybeMigrateLegacyQuickResponses(Context context) { // The algorithm will go as such: // If Telecom QuickResponses exist, we will skip migration because this implies // that a user has already specified their desired QuickResponses and have abandoned any @@ -59,11 +60,9 @@ public class QuickResponseUtils { // function is called. Log.d(LOG_TAG, "maybeMigrateLegacyQuickResponses() - Starting"); - - final Context telecomContext = TelecomApp.getInstance(); - final SharedPreferences prefs = telecomContext.getSharedPreferences( + final SharedPreferences prefs = context.getSharedPreferences( SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - final Resources res = telecomContext.getResources(); + final Resources res = context.getResources(); final boolean responsesExist = prefs.contains(KEY_CANNED_RESPONSE_PREF_1); if (responsesExist) { @@ -84,7 +83,7 @@ public class QuickResponseUtils { // the Telephony package and we'll fall back on using our default values. Context telephonyContext = null; try { - telephonyContext = telecomContext.createPackageContext(PACKAGE_NAME_TELEPHONY, 0); + telephonyContext = context.createPackageContext(PACKAGE_NAME_TELEPHONY, 0); } catch (PackageManager.NameNotFoundException e) { Log.e(LOG_TAG, e, "maybeMigrateLegacyQuickResponses() - Can't find Telephony package."); } diff --git a/src/com/android/server/telecom/RespondViaSmsManager.java b/src/com/android/server/telecom/RespondViaSmsManager.java index 6c054e66..2ac93799 100644 --- a/src/com/android/server/telecom/RespondViaSmsManager.java +++ b/src/com/android/server/telecom/RespondViaSmsManager.java @@ -16,6 +16,7 @@ package com.android.server.telecom; +// TODO: Needed for move to system service: import com.android.internal.R; import com.android.internal.os.SomeArgs; import com.android.internal.telephony.SmsApplication; @@ -47,7 +48,7 @@ public class RespondViaSmsManager extends CallsManagerListenerBase { @Override public void handleMessage(Message msg) { switch (msg.what) { - case MSG_CANNED_TEXT_MESSAGES_READY: + case MSG_CANNED_TEXT_MESSAGES_READY: { SomeArgs args = (SomeArgs) msg.obj; try { Response<Void, List<String>> response = @@ -63,9 +64,18 @@ public class RespondViaSmsManager extends CallsManagerListenerBase { args.recycle(); } break; - case MSG_SHOW_SENT_TOAST: - showMessageSentToast((String) msg.obj); + } + case MSG_SHOW_SENT_TOAST: { + SomeArgs args = (SomeArgs) msg.obj; + try { + String toastMessage = (String) args.arg1; + Context context = (Context) args.arg2; + showMessageSentToast(toastMessage, context); + } finally { + args.recycle(); + } break; + } } } }; @@ -83,8 +93,10 @@ public class RespondViaSmsManager extends CallsManagerListenerBase { * * @param response An object to receive an async reply, which will be called from * the main thread. + * @param context The context. */ - public void loadCannedTextMessages(final Response<Void, List<String>> response) { + public void loadCannedTextMessages(final Response<Void, List<String>> response, + final Context context) { new Thread() { @Override public void run() { @@ -93,11 +105,11 @@ public class RespondViaSmsManager extends CallsManagerListenerBase { // This function guarantees that QuickResponses will be in our // SharedPreferences with the proper values considering there may be // old QuickResponses in Telephony pre L. - QuickResponseUtils.maybeMigrateLegacyQuickResponses(); + QuickResponseUtils.maybeMigrateLegacyQuickResponses(context); - final SharedPreferences prefs = TelecomApp.getInstance().getSharedPreferences( + final SharedPreferences prefs = context.getSharedPreferences( QuickResponseUtils.SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); - final Resources res = TelecomApp.getInstance().getInstance().getResources(); + final Resources res = context.getResources(); final ArrayList<String> textMessages = new ArrayList<>( QuickResponseUtils.NUM_CANNED_RESPONSES); @@ -128,19 +140,21 @@ public class RespondViaSmsManager extends CallsManagerListenerBase { @Override public void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage) { if (rejectWithMessage) { - rejectCallWithMessage(call.getHandle().getSchemeSpecificPart(), textMessage); + + rejectCallWithMessage(call.getContext(), call.getHandle().getSchemeSpecificPart(), + textMessage); } } - private void showMessageSentToast(final String phoneNumber) { + private void showMessageSentToast(final String phoneNumber, final Context context) { // ...and show a brief confirmation to the user (since // otherwise it's hard to be sure that anything actually // happened.) - final Resources res = TelecomApp.getInstance().getResources(); + final Resources res = context.getResources(); final String formatString = res.getString( R.string.respond_via_sms_confirmation_format); final String confirmationMsg = String.format(formatString, phoneNumber); - Toast.makeText(TelecomApp.getInstance(), confirmationMsg, + Toast.makeText(context, confirmationMsg, Toast.LENGTH_LONG).show(); // TODO: If the device is locked, this toast won't actually ever @@ -161,19 +175,23 @@ public class RespondViaSmsManager extends CallsManagerListenerBase { /** * Reject the call with the specified message. If message is null this call is ignored. */ - private void rejectCallWithMessage(String phoneNumber, String textMessage) { + private void rejectCallWithMessage(Context context, String phoneNumber, String textMessage) { if (textMessage != null) { final ComponentName component = - SmsApplication.getDefaultRespondViaMessageApplication( - TelecomApp.getInstance(), true /*updateIfNeeded*/); + SmsApplication.getDefaultRespondViaMessageApplication(context, + true /*updateIfNeeded*/); if (component != null) { // Build and send the intent final Uri uri = Uri.fromParts(Constants.SCHEME_SMSTO, phoneNumber, null); final Intent intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, uri); intent.putExtra(Intent.EXTRA_TEXT, textMessage); - mHandler.obtainMessage(MSG_SHOW_SENT_TOAST, phoneNumber).sendToTarget(); + + SomeArgs args = SomeArgs.obtain(); + args.arg1 = phoneNumber; + args.arg2 = context; + mHandler.obtainMessage(MSG_SHOW_SENT_TOAST, args).sendToTarget(); intent.setComponent(component); - TelecomApp.getInstance().startService(intent); + context.startService(intent); } } } diff --git a/src/com/android/server/telecom/RespondViaSmsSettings.java b/src/com/android/server/telecom/RespondViaSmsSettings.java index 23bf7b29..b537162c 100644 --- a/src/com/android/server/telecom/RespondViaSmsSettings.java +++ b/src/com/android/server/telecom/RespondViaSmsSettings.java @@ -27,6 +27,8 @@ import android.preference.PreferenceActivity; import android.view.Menu; import android.view.MenuItem; +// TODO: Needed for move to system service: import com.android.internal.R; + /** * Helper class to manage the "Respond via SMS Message" feature for incoming calls. */ @@ -52,7 +54,7 @@ public class RespondViaSmsSettings { // This function guarantees that QuickResponses will be in our // SharedPreferences with the proper values considering there may be // old QuickResponses in Telephony pre L. - QuickResponseUtils.maybeMigrateLegacyQuickResponses(); + QuickResponseUtils.maybeMigrateLegacyQuickResponses(this); getPreferenceManager().setSharedPreferencesName( QuickResponseUtils.SHARED_PREFERENCES_NAME); diff --git a/src/com/android/server/telecom/RingbackPlayer.java b/src/com/android/server/telecom/RingbackPlayer.java index dc06c956..e6d703c9 100644 --- a/src/com/android/server/telecom/RingbackPlayer.java +++ b/src/com/android/server/telecom/RingbackPlayer.java @@ -18,7 +18,7 @@ package com.android.server.telecom; import android.telecom.CallState; -import com.google.common.base.Preconditions; +import com.android.internal.util.Preconditions; /** * Plays ringback tones. Ringback is different from other tones because it operates as the current diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java index 34f68295..cf65a115 100644 --- a/src/com/android/server/telecom/Ringer.java +++ b/src/com/android/server/telecom/Ringer.java @@ -49,7 +49,7 @@ final class Ringer extends CallsManagerListenerBase { /** Indicate that we want the pattern to repeat at the step which turns on vibration. */ private static final int VIBRATION_PATTERN_REPEAT = 1; - private final AsyncRingtonePlayer mRingtonePlayer = new AsyncRingtonePlayer(); + private final AsyncRingtonePlayer mRingtonePlayer; /** * Used to keep ordering of unanswered incoming calls. There can easily exist multiple incoming @@ -83,7 +83,8 @@ final class Ringer extends CallsManagerListenerBase { mContext = context; // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure this // vibrator object will be isolated from others. - mVibrator = new SystemVibrator(TelecomApp.getInstance()); + mVibrator = new SystemVibrator(context); + mRingtonePlayer = new AsyncRingtonePlayer(context); } @Override @@ -197,7 +198,7 @@ final class Ringer extends CallsManagerListenerBase { Log.v(this, "startRingingOrCallWaiting, skipping because volume is 0"); } - if (shouldVibrate(TelecomApp.getInstance()) && !mIsVibrating) { + if (shouldVibrate(mContext) && !mIsVibrating) { mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT, VIBRATION_ATTRIBUTES); mIsVibrating = true; diff --git a/src/com/android/server/telecom/ServiceBinder.java b/src/com/android/server/telecom/ServiceBinder.java index 98e7bd0e..fb747f20 100644 --- a/src/com/android/server/telecom/ServiceBinder.java +++ b/src/com/android/server/telecom/ServiceBinder.java @@ -23,7 +23,7 @@ import android.content.ServiceConnection; import android.os.IBinder; import android.os.IInterface; -import com.google.common.base.Preconditions; +import com.android.internal.util.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.Sets; @@ -166,12 +166,13 @@ abstract class ServiceBinder<ServiceInterface extends IInterface> { * * @param serviceAction The intent-action used with {@link Context#bindService}. * @param componentName The component name of the service with which to bind. + * @param context The context. */ - protected ServiceBinder(String serviceAction, ComponentName componentName) { + protected ServiceBinder(String serviceAction, ComponentName componentName, Context context) { Preconditions.checkState(!Strings.isNullOrEmpty(serviceAction)); Preconditions.checkNotNull(componentName); - mContext = TelecomApp.getInstance(); + mContext = context; mServiceAction = serviceAction; mComponentName = componentName; } diff --git a/src/com/android/server/telecom/StatusBarNotifier.java b/src/com/android/server/telecom/StatusBarNotifier.java index 14253a08..c8c3c182 100644 --- a/src/com/android/server/telecom/StatusBarNotifier.java +++ b/src/com/android/server/telecom/StatusBarNotifier.java @@ -19,6 +19,8 @@ package com.android.server.telecom; import android.app.StatusBarManager; import android.content.Context; +// TODO: Needed for move to system service: import com.android.internal.R; + /** * Manages the special status bar notifications used by the phone app. */ diff --git a/src/com/android/server/telecom/TelecomApp.java b/src/com/android/server/telecom/TelecomApp.java index c2e79ebc..b8519c3e 100644 --- a/src/com/android/server/telecom/TelecomApp.java +++ b/src/com/android/server/telecom/TelecomApp.java @@ -17,7 +17,11 @@ package com.android.server.telecom; import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.os.UserHandle; +import android.os.ServiceManager; /** * Top-level Application class for Telecom. @@ -28,6 +32,11 @@ public final class TelecomApp extends Application { private static TelecomApp sInstance; /** + * The Telecom service implementation. + */ + private TelecomServiceImpl mTelecomService; + + /** * Missed call notifier. Exists here so that the instance can be shared with * {@link TelecomBroadcastReceiver}. */ @@ -38,17 +47,55 @@ public final class TelecomApp extends Application { */ private PhoneAccountRegistrar mPhoneAccountRegistrar; + /** + * The calls manager for the Telecom service. + */ + private CallsManager mCallsManager; + + /** + * The Telecom broadcast receiver. + */ + private TelecomBroadcastReceiver mTelecomBroadcastReceiver; + + /** + * The {@link android.telecomm.PhoneAccount} broadcast receiver. + */ + private PhoneAccountBroadcastReceiver mPhoneAccountBroadcastReceiver; + /** {@inheritDoc} */ @Override public void onCreate() { super.onCreate(); sInstance = this; + // Note: This style of initialization mimics what will be performed once Telecom is moved + // to run in the system service. The emphasis is on ensuring that initialization of all + // telecom classes happens in one place without relying on Singleton initialization. mMissedCallNotifier = new MissedCallNotifier(this); mPhoneAccountRegistrar = new PhoneAccountRegistrar(this); + mCallsManager = new CallsManager(this, mMissedCallNotifier, mPhoneAccountRegistrar); + CallsManager.initialize(mCallsManager); + + mTelecomService = new TelecomServiceImpl(mMissedCallNotifier, mPhoneAccountRegistrar, + mCallsManager, this); + ServiceManager.addService(Context.TELECOM_SERVICE, mTelecomService); + mPhoneAccountBroadcastReceiver = new PhoneAccountBroadcastReceiver(mPhoneAccountRegistrar); + mTelecomBroadcastReceiver = new TelecomBroadcastReceiver(mMissedCallNotifier); + if (UserHandle.myUserId() == UserHandle.USER_OWNER) { - TelecomServiceImpl.init(mMissedCallNotifier, mPhoneAccountRegistrar); + //TelecomServiceImpl.init(mMissedCallNotifier, mPhoneAccountRegistrar); } + // Setup broadcast listener for telecom intents. + IntentFilter telecomFilter = new IntentFilter(); + telecomFilter.addAction(TelecomBroadcastReceiver.ACTION_CALL_BACK_FROM_NOTIFICATION); + telecomFilter.addAction(TelecomBroadcastReceiver.ACTION_CALL_BACK_FROM_NOTIFICATION); + telecomFilter.addAction(TelecomBroadcastReceiver.ACTION_SEND_SMS_FROM_NOTIFICATION); + registerReceiver(mTelecomBroadcastReceiver, telecomFilter); + + IntentFilter phoneAccountFilter = new IntentFilter(); + phoneAccountFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED); + phoneAccountFilter.addDataScheme("package"); + registerReceiver(mPhoneAccountBroadcastReceiver, phoneAccountFilter); } public static TelecomApp getInstance() { diff --git a/src/com/android/server/telecom/TelecomBroadcastReceiver.java b/src/com/android/server/telecom/TelecomBroadcastReceiver.java index 36c23fcd..9a777d63 100644 --- a/src/com/android/server/telecom/TelecomBroadcastReceiver.java +++ b/src/com/android/server/telecom/TelecomBroadcastReceiver.java @@ -38,6 +38,12 @@ public final class TelecomBroadcastReceiver extends BroadcastReceiver { static final String ACTION_CLEAR_MISSED_CALLS = "com.android.server.telecom.ACTION_CLEAR_MISSED_CALLS"; + /** The missed call notifier. */ + private final MissedCallNotifier mMissedCallNotifier; + + public TelecomBroadcastReceiver(MissedCallNotifier missedCallNotifier) { + mMissedCallNotifier = missedCallNotifier; + } /** {@inheritDoc} */ @Override @@ -46,13 +52,11 @@ public final class TelecomBroadcastReceiver extends BroadcastReceiver { Log.v(this, "Action received: %s.", action); - MissedCallNotifier missedCallNotifier = TelecomApp.getInstance().getMissedCallNotifier(); - // Send an SMS from the missed call notification. if (ACTION_SEND_SMS_FROM_NOTIFICATION.equals(action)) { // Close the notification shade and the notification itself. closeSystemDialogs(context); - missedCallNotifier.clearMissedCalls(); + mMissedCallNotifier.clearMissedCalls(); Intent callIntent = new Intent(Intent.ACTION_SENDTO, intent.getData()); callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -62,7 +66,7 @@ public final class TelecomBroadcastReceiver extends BroadcastReceiver { } else if (ACTION_CALL_BACK_FROM_NOTIFICATION.equals(action)) { // Close the notification shade and the notification itself. closeSystemDialogs(context); - missedCallNotifier.clearMissedCalls(); + mMissedCallNotifier.clearMissedCalls(); Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData()); callIntent.setFlags( @@ -71,7 +75,7 @@ public final class TelecomBroadcastReceiver extends BroadcastReceiver { // Clear the missed call notification and call log entries. } else if (ACTION_CLEAR_MISSED_CALLS.equals(action)) { - missedCallNotifier.clearMissedCalls(); + mMissedCallNotifier.clearMissedCalls(); } } diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java index 2f5fa688..b41b294b 100644 --- a/src/com/android/server/telecom/TelecomServiceImpl.java +++ b/src/com/android/server/telecom/TelecomServiceImpl.java @@ -37,8 +37,12 @@ import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.TelephonyManager; +// TODO: Needed for move to system service: import com.android.internal.R; import com.android.internal.telecom.ITelecomService; +import com.android.internal.util.IndentingPrintWriter; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.List; /** @@ -48,6 +52,9 @@ public class TelecomServiceImpl extends ITelecomService.Stub { private static final String REGISTER_PROVIDER_OR_SUBSCRIPTION = "com.android.server.telecom.permission.REGISTER_PROVIDER_OR_SUBSCRIPTION"; + /** The context. */ + private Context mContext; + /** ${inheritDoc} */ @Override public IBinder asBinder() { @@ -125,35 +132,19 @@ public class TelecomServiceImpl extends ITelecomService.Stub { private static TelecomServiceImpl sInstance; private final MainThreadHandler mMainThreadHandler = new MainThreadHandler(); - private final CallsManager mCallsManager = CallsManager.getInstance(); + private final CallsManager mCallsManager; private final MissedCallNotifier mMissedCallNotifier; private final PhoneAccountRegistrar mPhoneAccountRegistrar; private final AppOpsManager mAppOpsManager; - private TelecomServiceImpl( - MissedCallNotifier missedCallNotifier, PhoneAccountRegistrar phoneAccountRegistrar) { + public TelecomServiceImpl( + MissedCallNotifier missedCallNotifier, PhoneAccountRegistrar phoneAccountRegistrar, + CallsManager callsManager, Context context) { mMissedCallNotifier = missedCallNotifier; mPhoneAccountRegistrar = phoneAccountRegistrar; - mAppOpsManager = - (AppOpsManager) TelecomApp.getInstance().getSystemService(Context.APP_OPS_SERVICE); - - publish(); - } - - /** - * Initialize the singleton TelecommServiceImpl instance. - * This is only done once, at startup, from TelecommApp.onCreate(). - */ - static TelecomServiceImpl init( - MissedCallNotifier missedCallNotifier, PhoneAccountRegistrar phoneAccountRegistrar) { - synchronized (TelecomServiceImpl.class) { - if (sInstance == null) { - sInstance = new TelecomServiceImpl(missedCallNotifier, phoneAccountRegistrar); - } else { - Log.wtf(TAG, "init() called multiple times! sInstance %s", sInstance); - } - return sInstance; - } + mCallsManager = callsManager; + mContext = context; + mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); } // @@ -341,7 +332,7 @@ public class TelecomServiceImpl extends ITelecomService.Stub { */ @Override public ComponentName getDefaultPhoneApp() { - Resources resources = TelecomApp.getInstance().getResources(); + Resources resources = mContext.getResources(); return new ComponentName( resources.getString(R.string.ui_default_package), resources.getString(R.string.dialer_default_class)); @@ -456,7 +447,7 @@ public class TelecomServiceImpl extends ITelecomService.Stub { Binder.getCallingUid(), phoneAccountHandle.getComponentName().getPackageName()); Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL); - intent.setPackage(TelecomApp.getInstance().getPackageName()); + intent.setPackage(mContext.getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle); if (extras != null) { @@ -464,7 +455,7 @@ public class TelecomServiceImpl extends ITelecomService.Stub { } long token = Binder.clearCallingIdentity(); - TelecomApp.getInstance().startActivityAsUser(intent, UserHandle.CURRENT); + mContext.startActivityAsUser(intent, UserHandle.CURRENT); Binder.restoreCallingIdentity(token); } } @@ -507,8 +498,7 @@ public class TelecomServiceImpl extends ITelecomService.Stub { private void enforcePhoneAccountModificationForPackage(String packageName) { // TODO: Use a new telecomm permission for this instead of reusing modify. - int result = TelecomApp.getInstance().checkCallingOrSelfPermission( - Manifest.permission.MODIFY_PHONE_STATE); + int result = mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They @@ -556,11 +546,11 @@ public class TelecomServiceImpl extends ITelecomService.Stub { } private void enforcePermission(String permission) { - TelecomApp.getInstance().enforceCallingOrSelfPermission(permission, null); + mContext.enforceCallingOrSelfPermission(permission, null); } private void enforceFeature(String feature) { - PackageManager pm = TelecomApp.getInstance().getPackageManager(); + PackageManager pm = mContext.getPackageManager(); if (!pm.hasSystemFeature(feature)) { throw new UnsupportedOperationException( "System does not support feature " + feature); @@ -582,13 +572,7 @@ public class TelecomServiceImpl extends ITelecomService.Stub { } private TelephonyManager getTelephonyManager() { - return (TelephonyManager) - TelecomApp.getInstance().getSystemService(Context.TELEPHONY_SERVICE); - } - - private void publish() { - Log.d(this, "publish: %s", this); - ServiceManager.addService(SERVICE_NAME, this); + return (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); } private MainThreadRequest sendRequestAsync(int command, int arg1) { @@ -622,4 +606,16 @@ public class TelecomServiceImpl extends ITelecomService.Stub { return request.result; } } + + @Override + protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); + final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); + if (mCallsManager != null) { + pw.println("mCallsManager: "); + pw.increaseIndent(); + mCallsManager.dump(pw); + pw.decreaseIndent(); + } + } } diff --git a/src/com/android/server/telecom/Timeouts.java b/src/com/android/server/telecom/Timeouts.java index 4434db47..35f61ae9 100644 --- a/src/com/android/server/telecom/Timeouts.java +++ b/src/com/android/server/telecom/Timeouts.java @@ -16,6 +16,7 @@ package com.android.server.telecom; +import android.content.ContentResolver; import android.provider.Settings; /** @@ -34,13 +35,13 @@ public final class Timeouts { * Returns the timeout value from Settings or the default value if it hasn't been changed. This * method is safe to call from any thread, including the UI thread. * + * @param contentResolver The content resolved. * @param key Settings key to retrieve. * @param defaultValue Default value, in milliseconds. * @return The timeout value from Settings or the default value if it hasn't been changed. */ - private static long get(String key, long defaultValue) { - return Settings.Secure.getLong( - TelecomApp.getInstance().getContentResolver(), PREFIX + key, defaultValue); + private static long get(ContentResolver contentResolver, String key, long defaultValue) { + return Settings.Secure.getLong(contentResolver, PREFIX + key, defaultValue); } /** @@ -48,7 +49,7 @@ public final class Timeouts { * to complete. If the query goes beyond this timeout, the incoming call screen is shown to the * user. */ - public static long getDirectToVoicemailMillis() { - return get("direct_to_voicemail_ms", 500L); + public static long getDirectToVoicemailMillis(ContentResolver contentResolver) { + return get(contentResolver, "direct_to_voicemail_ms", 500L); } } diff --git a/src/com/android/server/telecom/TtyManager.java b/src/com/android/server/telecom/TtyManager.java index 945da5e4..b21f1653 100644 --- a/src/com/android/server/telecom/TtyManager.java +++ b/src/com/android/server/telecom/TtyManager.java @@ -25,6 +25,8 @@ import android.os.UserHandle; import android.provider.Settings; import android.telecom.TelecomManager; +// TODO: Needed for move to system service: import com.android.internal.R; + final class TtyManager implements WiredHeadsetManager.Listener { private final TtyBroadcastReceiver mReceiver = new TtyBroadcastReceiver(); private final Context mContext; |