Merge "Camera: Add support for notifying NFC stack when camera is active" into mnc-dr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a42cf680a5
@@ -19,6 +19,8 @@ package android.hardware;
|
|||||||
/**
|
/**
|
||||||
* Binder interface for the camera service proxy running in system_server.
|
* Binder interface for the camera service proxy running in system_server.
|
||||||
*
|
*
|
||||||
|
* Keep in sync with frameworks/av/include/camera/ICameraServiceProxy.h
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
interface ICameraServiceProxy
|
interface ICameraServiceProxy
|
||||||
@@ -27,4 +29,9 @@ interface ICameraServiceProxy
|
|||||||
* Ping the service proxy to update the valid users for the camera service.
|
* Ping the service proxy to update the valid users for the camera service.
|
||||||
*/
|
*/
|
||||||
oneway void pingForUserUpdate();
|
oneway void pingForUserUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the status of a camera device
|
||||||
|
*/
|
||||||
|
oneway void notifyCameraState(String cameraId, int newCameraState);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,17 @@ import android.content.IntentFilter;
|
|||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.hardware.ICameraService;
|
import android.hardware.ICameraService;
|
||||||
import android.hardware.ICameraServiceProxy;
|
import android.hardware.ICameraServiceProxy;
|
||||||
|
import android.nfc.INfcAdapter;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.os.SystemProperties;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
|
||||||
import com.android.server.ServiceThread;
|
import com.android.server.ServiceThread;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
@@ -44,8 +48,10 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class CameraService extends SystemService implements Handler.Callback {
|
public class CameraService extends SystemService
|
||||||
|
implements Handler.Callback, IBinder.DeathRecipient {
|
||||||
private static final String TAG = "CameraService_proxy";
|
private static final String TAG = "CameraService_proxy";
|
||||||
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This must match the ICameraService.aidl definition
|
* This must match the ICameraService.aidl definition
|
||||||
@@ -58,6 +64,16 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
public static final int NO_EVENT = 0; // NOOP
|
public static final int NO_EVENT = 0; // NOOP
|
||||||
public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle
|
public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle
|
||||||
|
|
||||||
|
// State arguments to use with the notifyCameraState call from camera service:
|
||||||
|
public static final int CAMERA_STATE_OPEN = 0;
|
||||||
|
public static final int CAMERA_STATE_ACTIVE = 1;
|
||||||
|
public static final int CAMERA_STATE_IDLE = 2;
|
||||||
|
public static final int CAMERA_STATE_CLOSED = 3;
|
||||||
|
|
||||||
|
// Flags arguments to NFC adapter to enable/disable NFC
|
||||||
|
public static final int DISABLE_POLLING_FLAGS = 0x1000;
|
||||||
|
public static final int ENABLE_POLLING_FLAGS = 0x0000;
|
||||||
|
|
||||||
// Handler message codes
|
// Handler message codes
|
||||||
private static final int MSG_SWITCH_USER = 1;
|
private static final int MSG_SWITCH_USER = 1;
|
||||||
|
|
||||||
@@ -72,6 +88,17 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
private Set<Integer> mEnabledCameraUsers;
|
private Set<Integer> mEnabledCameraUsers;
|
||||||
private int mLastUser;
|
private int mLastUser;
|
||||||
|
|
||||||
|
private ICameraService mCameraServiceRaw;
|
||||||
|
|
||||||
|
private final ArraySet<String> mActiveCameraIds = new ArraySet<>();
|
||||||
|
|
||||||
|
private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc";
|
||||||
|
private static final String NFC_SERVICE_BINDER_NAME = "nfc";
|
||||||
|
private static final IBinder nfcInterfaceToken = new Binder();
|
||||||
|
|
||||||
|
private final boolean mNotifyNfc;
|
||||||
|
private int mActiveCameraCount = 0;
|
||||||
|
|
||||||
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@@ -102,6 +129,14 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
public void pingForUserUpdate() {
|
public void pingForUserUpdate() {
|
||||||
notifySwitchWithRetries(30);
|
notifySwitchWithRetries(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyCameraState(String cameraId, int newCameraState) {
|
||||||
|
String state = cameraStateToString(newCameraState);
|
||||||
|
if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " state now " + state);
|
||||||
|
|
||||||
|
updateActivityCount(cameraId, newCameraState);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public CameraService(Context context) {
|
public CameraService(Context context) {
|
||||||
@@ -110,6 +145,9 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, /*allowTo*/false);
|
mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, /*allowTo*/false);
|
||||||
mHandlerThread.start();
|
mHandlerThread.start();
|
||||||
mHandler = new Handler(mHandlerThread.getLooper(), this);
|
mHandler = new Handler(mHandlerThread.getLooper(), this);
|
||||||
|
|
||||||
|
mNotifyNfc = SystemProperties.getInt(NFC_NOTIFICATION_PROP, 0) > 0;
|
||||||
|
if (DEBUG) Slog.v(TAG, "Notify NFC behavior is " + (mNotifyNfc ? "active" : "disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -161,13 +199,32 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the death of the native camera service
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void binderDied() {
|
||||||
|
if (DEBUG) Slog.w(TAG, "Native camera service has died");
|
||||||
|
synchronized(mLock) {
|
||||||
|
mCameraServiceRaw = null;
|
||||||
|
|
||||||
|
// All cameras reset to idle on camera service death
|
||||||
|
boolean wasEmpty = mActiveCameraIds.isEmpty();
|
||||||
|
mActiveCameraIds.clear();
|
||||||
|
|
||||||
|
if ( mNotifyNfc && !wasEmpty ) {
|
||||||
|
notifyNfcService(/*enablePolling*/ true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void switchUserLocked(int userHandle) {
|
private void switchUserLocked(int userHandle) {
|
||||||
Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
|
Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
|
||||||
mLastUser = userHandle;
|
mLastUser = userHandle;
|
||||||
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
|
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
|
||||||
// Some user handles have been added or removed, update mediaserver.
|
// Some user handles have been added or removed, update mediaserver.
|
||||||
mEnabledCameraUsers = currentUserHandles;
|
mEnabledCameraUsers = currentUserHandles;
|
||||||
notifyMediaserver(USER_SWITCHED, currentUserHandles);
|
notifyMediaserverLocked(USER_SWITCHED, currentUserHandles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +244,7 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
if (mEnabledCameraUsers == null) {
|
if (mEnabledCameraUsers == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (notifyMediaserver(USER_SWITCHED, mEnabledCameraUsers)) {
|
if (notifyMediaserverLocked(USER_SWITCHED, mEnabledCameraUsers)) {
|
||||||
retries = 0;
|
retries = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,19 +256,27 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
RETRY_DELAY_TIME);
|
RETRY_DELAY_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean notifyMediaserver(int eventType, Set<Integer> updatedUserHandles) {
|
private boolean notifyMediaserverLocked(int eventType, Set<Integer> updatedUserHandles) {
|
||||||
// Forward the user switch event to the native camera service running in the mediaserver
|
// Forward the user switch event to the native camera service running in the mediaserver
|
||||||
// process.
|
// process.
|
||||||
IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
|
if (mCameraServiceRaw == null) {
|
||||||
if (cameraServiceBinder == null) {
|
IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
|
||||||
Slog.w(TAG, "Could not notify mediaserver, camera service not available.");
|
if (cameraServiceBinder == null) {
|
||||||
return false; // Camera service not active, cannot evict user clients.
|
Slog.w(TAG, "Could not notify mediaserver, camera service not available.");
|
||||||
|
return false; // Camera service not active, cannot evict user clients.
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.w(TAG, "Could not link to death of native camera service");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
|
mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.w(TAG, "Could not notify mediaserver, remote exception: " + e);
|
Slog.w(TAG, "Could not notify mediaserver, remote exception: " + e);
|
||||||
// Not much we can do if camera service is dead.
|
// Not much we can do if camera service is dead.
|
||||||
@@ -220,6 +285,44 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateActivityCount(String cameraId, int newCameraState) {
|
||||||
|
synchronized(mLock) {
|
||||||
|
boolean wasEmpty = mActiveCameraIds.isEmpty();
|
||||||
|
switch (newCameraState) {
|
||||||
|
case CAMERA_STATE_OPEN:
|
||||||
|
break;
|
||||||
|
case CAMERA_STATE_ACTIVE:
|
||||||
|
mActiveCameraIds.add(cameraId);
|
||||||
|
break;
|
||||||
|
case CAMERA_STATE_IDLE:
|
||||||
|
case CAMERA_STATE_CLOSED:
|
||||||
|
mActiveCameraIds.remove(cameraId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
boolean isEmpty = mActiveCameraIds.isEmpty();
|
||||||
|
if ( mNotifyNfc && (wasEmpty != isEmpty) ) {
|
||||||
|
notifyNfcService(isEmpty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyNfcService(boolean enablePolling) {
|
||||||
|
|
||||||
|
IBinder nfcServiceBinder = getBinderService(NFC_SERVICE_BINDER_NAME);
|
||||||
|
if (nfcServiceBinder == null) {
|
||||||
|
Slog.w(TAG, "Could not connect to NFC service to notify it of camera state");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
INfcAdapter nfcAdapterRaw = INfcAdapter.Stub.asInterface(nfcServiceBinder);
|
||||||
|
int flags = enablePolling ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
|
||||||
|
if (DEBUG) Slog.v(TAG, "Setting NFC reader mode to flags " + flags);
|
||||||
|
try {
|
||||||
|
nfcAdapterRaw.setReaderMode(nfcInterfaceToken, null, flags, null);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.w(TAG, "Could not notify NFC service, remote exception: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static int[] toArray(Collection<Integer> c) {
|
private static int[] toArray(Collection<Integer> c) {
|
||||||
int len = c.size();
|
int len = c.size();
|
||||||
int[] ret = new int[len];
|
int[] ret = new int[len];
|
||||||
@@ -229,4 +332,15 @@ public class CameraService extends SystemService implements Handler.Callback {
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String cameraStateToString(int newCameraState) {
|
||||||
|
switch (newCameraState) {
|
||||||
|
case CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN";
|
||||||
|
case CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE";
|
||||||
|
case CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE";
|
||||||
|
case CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED";
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return "CAMERA_STATE_UNKNOWN";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user