1 /* 2 * Copyright (C) 2012 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.bluetooth.btservice; 18 19 import android.annotation.SuppressLint; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.ContextWrapper; 23 import android.content.pm.PackageManager; 24 import android.os.IBinder; 25 import android.util.Log; 26 27 import com.android.bluetooth.Utils; 28 29 /** Base class for a background service that runs a Bluetooth profile */ 30 public abstract class ProfileService extends ContextWrapper { 31 32 public interface IProfileServiceBinder extends IBinder { cleanup()33 void cleanup(); 34 } 35 36 private final IProfileServiceBinder mBinder; 37 private final String mName; 38 private boolean mAvailable = false; 39 private volatile boolean mTestModeEnabled = false; 40 getName()41 public String getName() { 42 return getClass().getSimpleName(); 43 } 44 isAvailable()45 public boolean isAvailable() { 46 return mAvailable; 47 } 48 setAvailable(boolean available)49 public void setAvailable(boolean available) { 50 mAvailable = available; 51 } 52 isTestModeEnabled()53 protected boolean isTestModeEnabled() { 54 return mTestModeEnabled; 55 } 56 57 /** 58 * Called in ProfileService constructor to init binder interface for this profile service. 59 * 60 * @return initialized binder interface for this profile service. 61 */ initBinder()62 protected abstract IProfileServiceBinder initBinder(); 63 64 /** Called when this object is no longer needed and is being discarded. */ cleanup()65 public abstract void cleanup(); 66 67 /** 68 * @param testModeEnabled if the profile should enter or exit a testing mode 69 */ setTestModeEnabled(boolean testModeEnabled)70 protected void setTestModeEnabled(boolean testModeEnabled) { 71 mTestModeEnabled = testModeEnabled; 72 } 73 ProfileService(Context ctx)74 protected ProfileService(Context ctx) { 75 super(ctx); 76 mName = getName(); 77 Log.d(mName, "Service created"); 78 mBinder = initBinder(); 79 } 80 81 /** return the binder of the profile */ getBinder()82 public IProfileServiceBinder getBinder() { 83 return mBinder; 84 } 85 86 /** 87 * Set the availability of an owned/managed component (Service, Activity, Provider, etc.) using 88 * a string class name assumed to be in the Bluetooth package. 89 * 90 * <p>It's expected that profiles can have a set of components that they may use to provide 91 * features or interact with other services/the user. Profiles are expected to enable those 92 * components when they start, and disable them when they stop. 93 * 94 * @param className The class name of the owned component residing in the Bluetooth package 95 * @param enable True to enable the component, False to disable it 96 */ setComponentAvailable(String className, boolean enable)97 protected void setComponentAvailable(String className, boolean enable) { 98 Log.d(mName, "setComponentAvailable(className=" + className + ", enable=" + enable + ")"); 99 if (className == null) { 100 return; 101 } 102 ComponentName component = new ComponentName(getPackageName(), className); 103 setComponentAvailable(component, enable); 104 } 105 106 /** 107 * Set the availability of an owned/managed component (Service, Activity, Provider, etc.) 108 * 109 * <p>It's expected that profiles can have a set of components that they may use to provide 110 * features or interact with other services/the user. Profiles are expected to enable those 111 * components when they start, and disable them when they stop. 112 * 113 * @param component The component name of owned component 114 * @param enable True to enable the component, False to disable it 115 */ setComponentAvailable(ComponentName component, boolean enable)116 protected void setComponentAvailable(ComponentName component, boolean enable) { 117 // Test should not set components available for the device 118 if (Utils.isInstrumentationTestMode()) { 119 Log.w(mName, "Skip call to setComponentAvailable(" + component + ", " + enable + ")"); 120 return; 121 } 122 Log.d(mName, "setComponentAvailable(" + component + ", " + enable + ")"); 123 if (component == null) { 124 return; 125 } 126 getPackageManager() 127 .setComponentEnabledSetting( 128 component, 129 enable 130 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 131 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 132 PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS); 133 } 134 135 /** 136 * Support dumping profile-specific information for dumpsys 137 * 138 * @param sb StringBuilder from the profile. 139 */ 140 // Suppressed since this is called from framework 141 @SuppressLint("AndroidFrameworkRequiresPermission") dump(StringBuilder sb)142 public void dump(StringBuilder sb) { 143 sb.append("\nProfile: "); 144 sb.append(mName); 145 sb.append("\n"); 146 } 147 148 /** 149 * Append an indented String for adding dumpsys support to subclasses. 150 * 151 * @param sb StringBuilder from the profile. 152 * @param s String to indent and append. 153 */ println(StringBuilder sb, String s)154 public static void println(StringBuilder sb, String s) { 155 sb.append(" "); 156 sb.append(s); 157 sb.append("\n"); 158 } 159 } 160