am 93826c7e: am f2c5ce5d: am a42cf680: Merge "Camera: Add support for notifying NFC stack when camera is active" into mnc-dr-dev
* commit '93826c7ebd3d5c6d6372a8bc6050d276727f7464': Camera: Add support for notifying NFC stack when camera is active
This commit is contained in:
@@ -19,6 +19,8 @@ package android.hardware;
|
||||
/**
|
||||
* Binder interface for the camera service proxy running in system_server.
|
||||
*
|
||||
* Keep in sync with frameworks/av/include/camera/ICameraServiceProxy.h
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface ICameraServiceProxy
|
||||
@@ -27,4 +29,9 @@ interface ICameraServiceProxy
|
||||
* Ping the service proxy to update the valid users for the camera service.
|
||||
*/
|
||||
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.hardware.ICameraService;
|
||||
import android.hardware.ICameraServiceProxy;
|
||||
import android.nfc.INfcAdapter;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Binder;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserManager;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.Slog;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.server.ServiceThread;
|
||||
import com.android.server.SystemService;
|
||||
@@ -44,8 +48,10 @@ import java.util.Set;
|
||||
*
|
||||
* @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 boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* 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 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
|
||||
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 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() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
@@ -102,6 +129,14 @@ public class CameraService extends SystemService implements Handler.Callback {
|
||||
public void pingForUserUpdate() {
|
||||
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) {
|
||||
@@ -110,6 +145,9 @@ public class CameraService extends SystemService implements Handler.Callback {
|
||||
mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, /*allowTo*/false);
|
||||
mHandlerThread.start();
|
||||
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
|
||||
@@ -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) {
|
||||
Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
|
||||
mLastUser = userHandle;
|
||||
if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
|
||||
// Some user handles have been added or removed, update mediaserver.
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
if (notifyMediaserver(USER_SWITCHED, mEnabledCameraUsers)) {
|
||||
if (notifyMediaserverLocked(USER_SWITCHED, mEnabledCameraUsers)) {
|
||||
retries = 0;
|
||||
}
|
||||
}
|
||||
@@ -199,19 +256,27 @@ public class CameraService extends SystemService implements Handler.Callback {
|
||||
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
|
||||
// process.
|
||||
IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
|
||||
if (cameraServiceBinder == null) {
|
||||
Slog.w(TAG, "Could not notify mediaserver, camera service not available.");
|
||||
return false; // Camera service not active, cannot evict user clients.
|
||||
if (mCameraServiceRaw == null) {
|
||||
IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
|
||||
if (cameraServiceBinder == null) {
|
||||
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 {
|
||||
cameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
|
||||
mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Could not notify mediaserver, remote exception: " + e);
|
||||
// Not much we can do if camera service is dead.
|
||||
@@ -220,6 +285,44 @@ public class CameraService extends SystemService implements Handler.Callback {
|
||||
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) {
|
||||
int len = c.size();
|
||||
int[] ret = new int[len];
|
||||
@@ -229,4 +332,15 @@ public class CameraService extends SystemService implements Handler.Callback {
|
||||
}
|
||||
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