blob: bde1f2f5882a40ca28c4c63143c038646c4991c2 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.process_launcher;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
import java.lang.reflect.Method;
/**
* Class of static helper methods to call Context.bindService variants.
*/
final class BindService {
private static Method sBindServiceAsUserMethod;
// Note that handler is not guaranteed to be used, and client still need to correctly handle
// callbacks on the UI thread.
static boolean doBindService(Context context, Intent intent, ServiceConnection connection,
int flags, Handler handler) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return bindServiceByCall(context, intent, connection, flags);
}
try {
return bindServiceByReflection(context, intent, connection, flags, handler);
} catch (ReflectiveOperationException e) {
return bindServiceByCall(context, intent, connection, flags);
}
}
private static boolean bindServiceByCall(
Context context, Intent intent, ServiceConnection connection, int flags) {
return context.bindService(intent, connection, flags);
}
@TargetApi(Build.VERSION_CODES.N)
private static boolean bindServiceByReflection(Context context, Intent intent,
ServiceConnection connection, int flags, Handler handler)
throws ReflectiveOperationException {
if (sBindServiceAsUserMethod == null) {
sBindServiceAsUserMethod =
Context.class.getDeclaredMethod("bindServiceAsUser", Intent.class,
ServiceConnection.class, int.class, Handler.class, UserHandle.class);
}
// No need for null checks or worry about infinite looping here. Otherwise a regular calls
// into the ContextWrapper would lead to problems as well.
while (context instanceof ContextWrapper) {
context = ((ContextWrapper) context).getBaseContext();
}
return (Boolean) sBindServiceAsUserMethod.invoke(
context, intent, connection, flags, handler, Process.myUserHandle());
}
private BindService() {}
}