1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.telecom; 18 19 import android.content.Context; 20 import android.content.pm.PackageManager; 21 import android.content.pm.UserInfo; 22 import android.media.AudioManager; 23 import android.media.RingtoneManager; 24 import android.media.Ringtone; 25 import android.net.Uri; 26 import android.os.UserHandle; 27 import android.os.UserManager; 28 import android.provider.Settings; 29 import android.telecom.PhoneAccount; 30 import android.text.TextUtils; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.internal.telephony.CallerInfo; 34 35 import java.util.List; 36 37 /** 38 * Uses the incoming {@link Call}'s ringtone URI (obtained by the Contact Lookup) to obtain a 39 * {@link Ringtone} from the {@link RingtoneManager} that can be played by the system during an 40 * incoming call. If the ringtone URI is null, use the default Ringtone for the active user. 41 */ 42 @VisibleForTesting 43 public class RingtoneFactory { 44 45 private final Context mContext; 46 private final CallsManager mCallsManager; 47 RingtoneFactory(CallsManager callsManager, Context context)48 public RingtoneFactory(CallsManager callsManager, Context context) { 49 mContext = context; 50 mCallsManager = callsManager; 51 } 52 getRingtone(Call incomingCall)53 public Ringtone getRingtone(Call incomingCall) { 54 // Use the default ringtone of the work profile if the contact is a work profile contact. 55 Context userContext = isWorkContact(incomingCall) ? 56 getWorkProfileContextForUser(mCallsManager.getCurrentUserHandle()) : 57 getContextForUserHandle(mCallsManager.getCurrentUserHandle()); 58 Uri ringtoneUri = incomingCall.getRingtone(); 59 Ringtone ringtone = null; 60 61 if(ringtoneUri != null && userContext != null) { 62 // Ringtone URI is explicitly specified. First, try to create a Ringtone with that. 63 ringtone = RingtoneManager.getRingtone(userContext, ringtoneUri); 64 } 65 if(ringtone == null) { 66 // Contact didn't specify ringtone or custom Ringtone creation failed. Get default 67 // ringtone for user or profile. 68 ringtone = RingtoneManager.getRingtone( 69 hasDefaultRingtoneForUser(userContext) ? userContext : mContext, 70 Settings.System.DEFAULT_RINGTONE_URI); 71 } 72 if (ringtone != null) { 73 ringtone.setStreamType(AudioManager.STREAM_RING); 74 } 75 return ringtone; 76 } 77 getWorkProfileContextForUser(UserHandle userHandle)78 private Context getWorkProfileContextForUser(UserHandle userHandle) { 79 // UserManager.getEnabledProfiles returns the enabled profiles along with the user's handle 80 // itself (so we must filter out the user). 81 List<UserInfo> profiles = UserManager.get(mContext).getEnabledProfiles( 82 userHandle.getIdentifier()); 83 UserInfo workprofile = null; 84 int managedProfileCount = 0; 85 for (UserInfo profile : profiles) { 86 UserHandle profileUserHandle = profile.getUserHandle(); 87 if (profileUserHandle != userHandle && profile.isManagedProfile()) { 88 managedProfileCount++; 89 workprofile = profile; 90 } 91 } 92 // There may be many different types of profiles, so only count Managed (Work) Profiles. 93 if(managedProfileCount == 1) { 94 return getContextForUserHandle(workprofile.getUserHandle()); 95 } 96 // There are multiple managed profiles for the associated user and we do not have enough 97 // info to determine which profile is the work profile. Just use the default. 98 return null; 99 } 100 getContextForUserHandle(UserHandle userHandle)101 private Context getContextForUserHandle(UserHandle userHandle) { 102 if(userHandle == null) { 103 return null; 104 } 105 try { 106 return mContext.createPackageContextAsUser(mContext.getPackageName(), 0, userHandle); 107 } catch (PackageManager.NameNotFoundException e) { 108 Log.w("RingtoneFactory", "Package name not found: " + e.getMessage()); 109 } 110 return null; 111 } 112 hasDefaultRingtoneForUser(Context userContext)113 private boolean hasDefaultRingtoneForUser(Context userContext) { 114 if(userContext == null) { 115 return false; 116 } 117 return !TextUtils.isEmpty(Settings.System.getString(userContext.getContentResolver(), 118 Settings.System.RINGTONE)); 119 } 120 isWorkContact(Call incomingCall)121 private boolean isWorkContact(Call incomingCall) { 122 CallerInfo contactCallerInfo = incomingCall.getCallerInfo(); 123 return (contactCallerInfo != null) && 124 (contactCallerInfo.userType == CallerInfo.USER_TYPE_WORK); 125 } 126 } 127