public KeyguardServiceDelegate(Context context, LockPatternUtils lockPatternUtils) {
   Intent intent = new Intent();
   intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
   mScrim = createScrim(context);
   if (!context.bindServiceAsUser(
       intent, mKeyguardConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
     if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
   } else {
     if (DEBUG) Log.v(TAG, "*** Keyguard started");
   }
 }
 public void bindService(Context context) {
   Intent intent = new Intent();
   intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
   if (!context.bindServiceAsUser(
       intent, mKeyguardConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
     Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
     mKeyguardState.showing = false;
     mKeyguardState.showingAndNotOccluded = false;
     mKeyguardState.secure = false;
     mKeyguardState.deviceHasKeyguard = false;
     hideScrim();
   } else {
     if (DEBUG) Log.v(TAG, "*** Keyguard started");
   }
 }
  /** @hide */
  @WorkerThread
  public static KeyChainConnection bindAsUser(@NonNull Context context, UserHandle user)
      throws InterruptedException {
    if (context == null) {
      throw new NullPointerException("context == null");
    }
    ensureNotOnMainThread(context);
    final BlockingQueue<IKeyChainService> q = new LinkedBlockingQueue<IKeyChainService>(1);
    ServiceConnection keyChainServiceConnection =
        new ServiceConnection() {
          volatile boolean mConnectedAtLeastOnce = false;

          @Override
          public void onServiceConnected(ComponentName name, IBinder service) {
            if (!mConnectedAtLeastOnce) {
              mConnectedAtLeastOnce = true;
              try {
                q.put(IKeyChainService.Stub.asInterface(service));
              } catch (InterruptedException e) {
                // will never happen, since the queue starts with one available slot
              }
            }
          }

          @Override
          public void onServiceDisconnected(ComponentName name) {}
        };
    Intent intent = new Intent(IKeyChainService.class.getName());
    ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
    intent.setComponent(comp);
    boolean isBound =
        context.bindServiceAsUser(
            intent, keyChainServiceConnection, Context.BIND_AUTO_CREATE, user);
    if (!isBound) {
      throw new AssertionError("could not bind to KeyChainService");
    }
    return new KeyChainConnection(context, keyChainServiceConnection, q.take());
  }
  /** Version of registerService that takes the name of a service component to bind to. */
  private void registerService(final ComponentName name, final int userid) {
    if (DEBUG) Slog.v(TAG, "registerService: " + name + " u=" + userid);

    synchronized (mMutex) {
      final String servicesBindingTag = name.toString() + "/" + userid;
      if (mServicesBinding.contains(servicesBindingTag)) {
        // stop registering this thing already! we're working on it
        return;
      }
      mServicesBinding.add(servicesBindingTag);

      final int N = mServices.size();
      for (int i = N - 1; i >= 0; i--) {
        final ManagedServiceInfo info = mServices.get(i);
        if (name.equals(info.component) && info.userid == userid) {
          // cut old connections
          if (DEBUG) Slog.v(TAG, "    disconnecting old " + getCaption() + ": " + info.service);
          removeServiceLocked(i);
          if (info.connection != null) {
            mContext.unbindService(info.connection);
          }
        }
      }

      Intent intent = new Intent(mConfig.serviceInterface);
      intent.setComponent(name);

      intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mConfig.clientLabel);

      final PendingIntent pendingIntent =
          PendingIntent.getActivity(mContext, 0, new Intent(mConfig.settingsAction), 0);
      intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);

      ApplicationInfo appInfo = null;
      try {
        appInfo = mContext.getPackageManager().getApplicationInfo(name.getPackageName(), 0);
      } catch (PackageManager.NameNotFoundException e) {
        // Ignore if the package doesn't exist we won't be able to bind to the service.
      }
      final int targetSdkVersion =
          appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;

      try {
        if (DEBUG) Slog.v(TAG, "binding: " + intent);
        if (!mContext.bindServiceAsUser(
            intent,
            new ServiceConnection() {
              IInterface mService;

              @Override
              public void onServiceConnected(ComponentName name, IBinder binder) {
                boolean added = false;
                ManagedServiceInfo info = null;
                synchronized (mMutex) {
                  mServicesBinding.remove(servicesBindingTag);
                  try {
                    mService = asInterface(binder);
                    info =
                        newServiceInfo(
                            mService, name, userid, false /*isSystem*/, this, targetSdkVersion);
                    binder.linkToDeath(info, 0);
                    added = mServices.add(info);
                  } catch (RemoteException e) {
                    // already dead
                  }
                }
                if (added) {
                  onServiceAdded(info);
                }
              }

              @Override
              public void onServiceDisconnected(ComponentName name) {
                Slog.v(TAG, getCaption() + " connection lost: " + name);
              }
            },
            Context.BIND_AUTO_CREATE,
            new UserHandle(userid))) {
          mServicesBinding.remove(servicesBindingTag);
          Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent);
          return;
        }
      } catch (SecurityException ex) {
        Slog.e(TAG, "Unable to bind " + getCaption() + " service: " + intent, ex);
        return;
      }
    }
  }