android Bluetooth开机启动流程分析

/ android / 没有评论 / 1054浏览

用到的代码文件

frameworks/base/services/core/java/
com/android/server/BluetoothManagerService.java
com/android/server/SystemServiceManager.java
com/android/server/BluetoothService.java
com/android/server/SystemService.java

frameworks/base/services/java/
com/android/server/SystemServer.java

frameworks/base/core/java/
android/os/ServiceManager.java
com/android/internal/os/BinderInternal.java
android/provider/Settings.java
在Settings类中定义的内部类:
Global.java
NameValueCache.java

代码执行流程图

android bluetooth 查看原图

蓝牙开机启动流程

下面的代码是以android N(api 24)为基础。

本文基于高通(Qualcomm)平台基线。

com.android.server.SystemServer.java中开启一系列的服务。
下面进入SystemServer类中的startOtherServices()方法。

private SystemServiceManager mSystemServiceManager;

/**
 * Starts a miscellaneous grab bag of stuff that has yet to be refactored
 * and organized.
 */
private void startOtherServices() {
        .......
        // Skip Bluetooth if we have an emulator kernel
        // TODO: Use a more reliable check to see if this 
        // product should
        // support Bluetooth - see bug 988521
        if (isEmulator) {
            Slog.i(TAG, "No Bluetooth Service (emulator)");
        } else if (mFactoryTestMode 
                      == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            Slog.i(TAG, "No Bluetooth Service (factory test)");
        } else if (!context.getPackageManager().hasSystemFeature
                   (PackageManager.FEATURE_BLUETOOTH)) {
            Slog.i(TAG, 
              "No Bluetooth Service (Bluetooth Hardware Not Present)");
        } else if (disableBluetooth) {
            Slog.i(TAG, "Bluetooth Service disabled by config");
        } else {
            mSystemServiceManager.startService(BluetoothService.class);
        }
        .......
}

下面进入SystemServiceManager类中的startService()方法。

// Services that should receive lifecycle events.
private final ArrayList<SystemService> mServices = 
                          new ArrayList<SystemService>();

public <T extends SystemService> T startService(
    Class<T> serviceClass) {
    try {
        final String name = serviceClass.getName();
        Slog.i(TAG, "Starting " + name);
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " 
                + name);

        // Create the service.
        if (!SystemService.class.isAssignableFrom(serviceClass)) {
            throw new RuntimeException("Failed to create " + name
                    + ": service must extend " 
                    + SystemService.class.getName());
        }
        final T service;
        try {
            Constructor<T> constructor = serviceClass
                    .getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
            throw new RuntimeException("Failed to create service " 
                    + name
                    + ": service could not be instantiated", ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException("Failed to create service " 
                    + name
                    + ": service must have a public constructor" 
                    + " with a Context argument", ex);
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException("Failed to create service " 
                    + name
                    + ": service must have a public constructor" 
                    + " with a Context argument", ex);
        } catch (InvocationTargetException ex) {
            throw new RuntimeException("Failed to create service " 
                    + name
                    + ": service constructor threw an exception",
                             ex);
        }

        // Register it.
        mServices.add(service);

        // Start it.
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " 
                    + name
                    + ": onStart threw an exception", ex);
        }
        return service;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}

下面进入BluetoothService类的onStart()方法。
可以看见这是一个空方法,因此在SystemServer启动的onStart阶段不是真正意义上的启动蓝牙。

@Override
public void onStart() {

}

下面继续看SystemServer类中的startOtherServices()方法。
发现有下面有下面两句代码。

private void startOtherServices() {
    ......
    mSystemServiceManager
        .startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
    mSystemServiceManager
        .startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
    ......
}

下面看下SystemServiceManager类中的startBootPhase()方法。
可以看见遍历mServices对象,分别调用其中的SystemService类的onBootPhase()方法。
我们的BluetoothService也是继承自SystemService类。

public void startBootPhase(final int phase) {
    if (phase <= mCurrentPhase) {
        throw new IllegalArgumentException(
            "Next phase must be larger than previous");
    }
    mCurrentPhase = phase;

    Slog.i(TAG, "Starting phase " + mCurrentPhase);
    try {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " 
                + phase);
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
            try {
                service.onBootPhase(mCurrentPhase);
            } catch (Exception ex) {
                throw new RuntimeException(
                        "Failed to boot service "
                        + service.getClass().getName()
                        + ": onBootPhase threw an "
                        + "exception during phase "
                        + mCurrentPhase, ex);
            }
        }
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}

mBluetoothManagerService就是我们真正意义上的BluetoothManagerService类。
它的初始化是在BluetoothService类的构造方法中。
下面我们去看下BluetoothService类的onBootPhase()方法。
可以发现只有在PHASE_SYSTEM_SERVICES_READY和PHASE_ACTIVITY_MANAGER_READY这两个 阶段BluetoothService才干正事。

private BluetoothManagerService mBluetoothManagerService;

@Override
public void onBootPhase(int phase) {
    if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
        publishBinderService(
                BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,
                mBluetoothManagerService);
    } else if (phase == SystemService
                .PHASE_ACTIVITY_MANAGER_READY) {
        mBluetoothManagerService.handleOnBootPhase();
    }
}

下面看下publishBinderService()方法。
这里执行的是BluetoothService类的父类SystemService类中的publishBinderService()方法。

/**
 * Publish the service so it is accessible to 
 * other services and apps.
 */
protected final void publishBinderService(String name, 
        IBinder service) {
    publishBinderService(name, service, false);
}

protected final void publishBinderService(String name, 
        IBinder service,
        boolean allowIsolated) {
    /*
      * 最终进入这里
      */
    ServiceManager.addService(name, service, allowIsolated);
}

下面进入ServiceManager类中的addService()方法。

/**
 * Place a new @a service called @a name into the service
 * manager.
 *
 * @param name the name of the new service
 * @param service the service object
 * @param allowIsolated set to true to allow 
 * isolated sandboxed processes
 * to access this service
 *
 *  allowIsolated设置为true允许隔离的沙盒中的进程访问它。
 *  我们当前传递的是false那么就不允许。
 */
public static void addService(String name, IBinder service, 
        boolean allowIsolated) {
    try {
        getIServiceManager().addService(name, service, 
            allowIsolated);
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
}

下面看下ServiceManager类中的getIServiceManager()方法。
可以看下我们在这个方法中拿到的是IServiceManager对象。

private static IServiceManager sServiceManager;

private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }

    // Find the service manager
    sServiceManager = ServiceManagerNative.asInterface(
        BinderInternal.getContextObject());
    return sServiceManager;
}

下载关注下这句代码“BinderInternal.getContextObject()”。
下面进入BinderInternal类中的getContextObject()方法。
可以看见这个一个native方法。
根据方法的注释我们可以理解通过这个方法可以拿到整个System系统级别的上下文对象。
使用这个对象可以获得其它的Service。这里的service不是我们应用组件中的service,而是我们 android系统的各项服务,如WindowManagerService,ActivityManagerService等等。

/**
 * Return the global "context object" of the system.  
 * This is usually an implementation of IServiceManager, 
 * which you can use to find other services.
 */
public static final native IBinder getContextObject();

下面进入ServiceManagerNative类中的asInterface()方法。
这里最终返回的是ServiceManagerProxy对象。
ServiceManagerProxy类是定义在ServiceManagerNative类中的内部类。

static public IServiceManager asInterface(IBinder obj)
{
    if (obj == null) {
        return null;
    }
    IServiceManager in =
        (IServiceManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }

    return new ServiceManagerProxy(obj);
}

因此在ServiceManager类中的addService()方法中最终调用的是ServiceManagerProxy类的 addService()方法。
下面是ServiceManagerProxy类中的addService()方法。

public void addService(String name, IBinder service, 
        boolean allowIsolated)
        throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    data.writeString(name);
    data.writeStrongBinder(service);
    data.writeInt(allowIsolated ? 1 : 0);
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    reply.recycle();
    data.recycle();
}

可以看见进行Binder通信了。就不继续往下最终native层代码了。
这里最终的结果是SystemService类中的publishBinderService()方法将BluetoothManagerService对象添加到native层中的Binder管理的内存中。当有其它地方需要这个服务的时候就从native层中Binder管理的 内存中取出这个服务。

现在BluetoothService类中onBootPhase()方法PHASE_SYSTEM_SERVICES_READY阶段就完成了。
那什么时候执行PHASE_ACTIVITY_MANAGER_READY这个阶段呢?
答案还是在SystemServer类的startOtherServices()方法中。

private void startOtherServices() {
    ......
    // We now tell the activity manager it is okay to run 
    // third party code.  It will call back into us once it
    // has gotten to the state where third party code can 
    // really run (but before it has actually
    // started launching the initial applications), 
    // for us to complete our
    // initialization.
    mActivityManagerService.systemReady(new Runnable() {
        @Override
        public void run() {
            Slog.i(TAG, "Making services ready");
            /**
              * 进入这里
              */
            mSystemServiceManager.startBootPhase(
                SystemService.PHASE_ACTIVITY_MANAGER_READY);
            ......
            mSystemServiceManager.startBootPhase(
                SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
            ......
        }
    });
    ......
}

根据上面的分析这里最终还是会调用到BluetoothService类中的onBootPhase()方法。

@Override
public void onBootPhase(int phase) {
    if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
        publishBinderService(
                BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,
                mBluetoothManagerService);
    } else if (phase == SystemService
                  .PHASE_ACTIVITY_MANAGER_READY) {
        /*
          * 终于开始启动了......
          */
        mBluetoothManagerService.handleOnBootPhase();
    }
}

进入BluetoothManagerService类的的handleOnBootPhase()方法。

/**
 * Send enable message and set adapter name and address. 
 * Called when the boot phase becomes
 * PHASE_SYSTEM_SERVICES_READY.
 */
public void handleOnBootPhase() {
    if (DBG) Slog.d(TAG, "Bluetooth boot completed");
    if (mEnableExternal 
        && isBluetoothPersistedStateOnBluetooth()) {
        /*
          * 如果这个if条件判断为true,那么就发送消息自动启动BT。
          */
        if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth.");
        sendEnableMsg(mQuietEnableExternal);
    } else if (!isNameAndAddressSet()) {
        if (DBG) Slog.d(TAG, 
            "Getting adapter name and address");
        Message getMsg = mHandler
                .obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
        mHandler.sendMessage(getMsg);
    }
}

下面进入BluetoothManagerService类的isBluetoothPersistedStateOnBluetooth()方法。

/**
 *  Returns true if the Bluetooth saved state 
 * is BLUETOOTH_ON_BLUETOOTH
 */
private final boolean isBluetoothPersistedStateOnBluetooth() {
    //android.app.ContextImpl$ApplicationContentResolver
    Log.d(TAG,"mContentResolver: "
        +mContentResolver.getClass().getName());
    return Settings.Global.getInt(mContentResolver,
            Settings.Global.BLUETOOTH_ON, 0) 
                == BLUETOOTH_ON_BLUETOOTH;
}

下面进入Global类中的getInt()方法。

/**
 * Whether bluetooth is enabled/disabled
 * 0=disabled. 1=enabled.
 */
public static final String BLUETOOTH_ON = "bluetooth_on";

public static int getInt(ContentResolver cr, 
        String name, int def) {
    String v = getString(cr, name);
    try {
        return v != null ? Integer.parseInt(v) : def;
    } catch (NumberFormatException e) {
        return def;
    }
}

接着进入Global类中的getString()方法。

public static String getString(ContentResolver resolver, 
        String name) {
    return getStringForUser(resolver, 
            name, UserHandle.myUserId());
}

接着进入Global类中的getStringForUser()方法。

 /*
  * 该对象定义在Global类中。
  */
// Populated lazily, guarded by class object:
private static NameValueCache sNameValueCache 
        = new NameValueCache(
            CONTENT_URI,
            CALL_METHOD_GET_GLOBAL,
            CALL_METHOD_PUT_GLOBAL);

/** @hide */
public static String getStringForUser(ContentResolver resolver, 
        String name,
        int userHandle) {
    Log.d("Settings.Global","userHandle: "+userHandle);// 0
    if (MOVED_TO_SECURE.contains(name)) {// -> false
        Log.w(TAG, "Setting " 
            + name 
            + " has moved from android.provider.Settings.Global"
            + " to android.provider.Settings.Secure, "
            + "returning read-only value.");
        return Secure.getStringForUser(resolver, 
                name, userHandle);
    }
    /**
      * 进入这里
      */
    return sNameValueCache.getStringForUser(resolver, 
          name, userHandle);
}

下面进入NameValueCache类中的getStringForUser()方法。

// Must synchronize on 'this' to access 
// mValues and mValuesVersion.
private final HashMap<String, String> mValues 
        = new HashMap<String, String>();

public String getStringForUser(ContentResolver cr, 
        String name, final int userHandle) {
    final boolean isSelf = (userHandle 
            == UserHandle.myUserId());
    if (isSelf) { // -> true
        synchronized (NameValueCache.this) {
            // -> true
            if (mGenerationTracker != null) {
                // -> false
                if (mGenerationTracker.isGenerationChanged()) { 
                    if (DEBUG) {
                        Log.i(TAG, "Generation changed for type:"
                                + mUri.getPath() + " in package:"
                                + cr.getPackageName() +" and user:" 
                                + userHandle);
                    }
                    mValues.clear();
                } else if (mValues.containsKey(name)) { // -> true
                    /*
                     * 从这里进行的返回
                     */
                    return mValues.get(name);
                }
            }
        }
    } else {
        if (LOCAL_LOGV) Log.v(TAG, "get setting for user " 
                + userHandle
                + " by user " + UserHandle.myUserId()
                + " so skipping cache");
    }

    ......(省略一大段代码)
}

下面进入BluetoothManagerService类中的sendEnableMsg()方法。

private void sendEnableMsg(boolean quietMode) {
    mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,
                         quietMode ? 1 : 0, 0));
}

下面进入MESSAGE_ENABLE对应的消息处理case。

private class BluetoothHandler extends Handler {
    boolean mGetNameAddressOnly = false;

    public BluetoothHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
     ......
        case MESSAGE_ENABLE:
            mHandler.removeMessages(
                    MESSAGE_RESTART_BLUETOOTH_SERVICE);
            mEnable = true;

            // Use service interface to get the exact state
            try {
                mBluetoothLock.readLock().lock();
                if (mBluetooth != null) { // ->false
                    int state = mBluetooth.getState();
                    if (state 
                          == BluetoothAdapter.STATE_BLE_ON) {
                        Log.d(TAG, "BT is in BLE_ON State");
                        mBluetooth.onLeServiceUp();
                        break;
                    }
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "", e);
            } finally {
                mBluetoothLock.readLock().unlock();
            }

            mQuietEnable = (msg.arg1 == 1);
            //false
            Log.d(TAG, "mQuietEnable: "+mQuietEnable);
            if (mBluetooth == null) {
                /**
                  * 进入这里
                  */
                handleEnable(mQuietEnable);
            } else {
                //
                // We need to wait until transitioned to 
                // STATE_OFF and
                // the previous Bluetooth process has exited. 
                // The waiting period has three components:
                // (a) Wait until the local state is STATE_OFF. 
                // This is accomplished by 
                // "waitForOnOff(false, true)".
                // (b) Wait until the STATE_OFF state is updated 
                //     to all components.
                // (c) Wait until the Bluetooth process exits, 
                //     and ActivityManager detects it.
                // The waiting for (b) and (c) is accomplished by
                // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
                // message. On slower devices, that delay needs 
                // to be on the order
                // of (2 * SERVICE_RESTART_TIME_MS).
                //
                waitForOnOff(false, true);
                Message restartMsg = mHandler.obtainMessage(
                        MESSAGE_RESTART_BLUETOOTH_SERVICE);
                mHandler.sendMessageDelayed(restartMsg,
                        2 * SERVICE_RESTART_TIME_MS);
            }
            break;
    }

}

下面进入BluetoothManagerService类中的handleEnable()方法。

private void handleEnable(boolean quietMode) {
    Log.d(TAG,"quietMode: "+quietMode);//false
    mQuietEnable = quietMode;

    try {
        mBluetoothLock.writeLock().lock();
        /**
          * mBinding这个变量的意思就是是否与蓝牙进程进行了绑定
          */
        Log.d(TAG,"mBinding: "+mBinding);//false
        //->true
        if ((mBluetooth == null) && (!mBinding)) { 
            //Start bind timeout and bind
            Message timeoutMsg=mHandler
                .obtainMessage(MESSAGE_TIMEOUT_BIND);
            mHandler.sendMessageDelayed(timeoutMsg,
                TIMEOUT_BIND_MS);
            Intent i = new Intent(IBluetooth
                .class.getName());
            /**
              * 进入这里 执行绑定
              */
            if (!doBind(i, mConnection,
                    Context.BIND_AUTO_CREATE 
                    | Context.BIND_IMPORTANT,
                    UserHandle.CURRENT)) {
                Log.d(TAG,"doBind return false");
                mHandler.removeMessages(
                    MESSAGE_TIMEOUT_BIND);
            } else {
                mBinding = true;
            }
        } else if (mBluetooth != null) {
            //Enable bluetooth
            try {
                if (!mQuietEnable) {
                    if(!mBluetooth.enable()) {
                        Log.d(TAG,
                            "IBluetooth.enable() "
                            + "returned false");
                    }
                }
                else {
                    if(!mBluetooth.enableNoAutoConnect()) {
                        Log.d(TAG,
                            "IBluetooth.enableNoAutoConnect()"
                            + " returned false");
                    }
                }
            } catch (RemoteException e) {
                Slog.e(TAG,"Unable to call enable()",e);
            }
        }
    } finally {
        mBluetoothLock.writeLock().unlock();
    }
}

下面进入BluetoothManagerService类中的doBind()方法。

boolean doBind(Intent intent, ServiceConnection conn, 
    int flags, UserHandle user) {
    ComponentName comp = intent
        .resolveSystemService(mContext.getPackageManager(), 
        0);
    intent.setComponent(comp);
    if (comp == null || !mContext.bindServiceAsUser(intent, 
        conn, flags, user)) {
        Slog.e(TAG, "Fail to bind to: " + intent);
        return false;
    }
    return true;
}

下面看下BluetoothServiceConnection的具体实现。

private class BluetoothServiceConnection 
        implements ServiceConnection {
        
    public void onServiceConnected(ComponentName className, 
        IBinder service) {
        if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " 
        + className.getClassName());
        Message msg = mHandler
            .obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
        // TBD if (className.getClassName()
        //    .equals(IBluetooth.class.getName())) {
        //我们绑定的是这个
        if (className.getClassName()
            .equals(
              "com.android.bluetooth.btservice.AdapterService"
              )) {
            msg.arg1 = SERVICE_IBLUETOOTH;
            // } else if (className.getClassName()
                .equals(IBluetoothGatt.class.getName())) {
        } else if (className.getClassName()
            .equals("com.android.bluetooth.gatt.GattService")) {
            msg.arg1 = SERVICE_IBLUETOOTHGATT;
        } else {
            Slog.e(TAG, "Unknown service connected: " 
            + className.getClassName());
            return;
        }
        msg.obj = service;
        boolean sent = mHandler.sendMessage(msg);
        if (sent && (msg.arg1 == SERVICE_IBLUETOOTH))
            mIBluetoothConnectedMsgQueued++;
    }
    ......
}

下看来查看对应Message MESSAGE_BLUETOOTH_SERVICE_CONNECTED的具体实现。

  ......
  case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
  {
      if (DBG) Slog.d(TAG,
          "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " 
          + msg.arg1);

      IBinder service = (IBinder) msg.obj;
      try {
          mBluetoothLock.writeLock().lock();
          // -> false
          if (msg.arg1 == SERVICE_IBLUETOOTHGATT) { 
              Log.d(TAG,"type is SERVICE_IBLUETOOTHGATT");
              mBluetoothGatt = IBluetoothGatt
                      .Stub.asInterface(service);
              onBluetoothGattServiceUp();
              break;
          } // else must be SERVICE_IBLUETOOTH

          mIBluetoothConnectedMsgQueued--;

          //Remove timeout
          mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);

          mBinding = false;
          mBluetoothBinder = service;
          mBluetooth = IBluetooth.Stub.asInterface(service);

          if (!isNameAndAddressSet()) { // -> false
              Log.d(TAG,"isNameAndAddressSet() return false");
              Message getMsg = mHandler
                  .obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
              mHandler.sendMessage(getMsg);
              if (mGetNameAddressOnly) return;
          }

          try {
              boolean enableHciSnoopLog = (Settings.Secure
                      .getInt(mContentResolver,
                  Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);
              //false
              Log.d(TAG,"enableHciSnoopLog: "+enableHciSnoopLog);
              if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) {
                  Log.e(TAG,
                  "IBluetooth.configHciSnoopLog return false");
              }
          } catch (RemoteException e) {
              Slog.e(TAG,"Unable to call configHciSnoopLog", e);
          }

          //Register callback object
          try {
               /*
                * 注册蓝牙state状态改变的回调
                */
              mBluetooth.registerCallback(mBluetoothCallback);
          } catch (RemoteException re) {
              Slog.e(TAG, 
                  "Unable to register BluetoothCallback",
                  re);
          }
          //Inform BluetoothAdapter instances that
          //service is up
          sendBluetoothServiceUpCallback();
          // -> false
          Log.d(TAG,"mQuietEnable: "+mQuietEnable); 
          //Do enable request
          try {
              if (mQuietEnable == false) {
                  /**
                    * 进入这里 启动蓝牙
                    */
                  if(!mBluetooth.enable()) {
                      Slog.e(TAG,
                          "IBluetooth.enable() returned false");
                  }
              }
              else
              {
                  if(!mBluetooth.enableNoAutoConnect()) {
                      Log.e(TAG,
                          "IBluetooth.enableNoAutoConnect()"
                          + " returned false");
                  }
              }
          } catch (RemoteException e) {
              Slog.e(TAG,"Unable to call enable()",e);
          }
      } finally {
          mBluetoothLock.writeLock().unlock();
      }

      if (!mEnable) {
          waitForOnOff(true, false);
          handleDisable();
          waitForOnOff(false, false);
      }
      break;
  }
  ......

下面主要看一下Global类中sNameValueCache对象的构造过程。 这个变量是static的,所以整个内存中只有一份,因此充当缓存的角色。

private static NameValueCache sNameValueCache = new NameValueCache(
            CONTENT_URI,
            CALL_METHOD_GET_GLOBAL,
            CALL_METHOD_PUT_GLOBAL);

//定义在Global类中
public static final Uri CONTENT_URI = Uri.parse("content://" 
        + AUTHORITY + "/global");

/*
  * 下面三个变量定义在Settings类中
  */
public static final String AUTHORITY = "settings";
public static final String CALL_METHOD_PUT_GLOBAL= "PUT_global";
public static final String CALL_METHOD_GET_GLOBAL = "GET_global";