Merge "VDM demo: all repohooks fixed for client/" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
5ea9f410ed
@@ -47,25 +47,25 @@ final class AudioPlayer implements Consumer<RemoteEvent> {
|
|||||||
SAMPLE_RATE, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
|
SAMPLE_RATE, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
|
||||||
private static final int AUDIOTRACK_BUFFER_SIZE = 4 * MIN_AUDIOTRACK_BUFFER_SIZE;
|
private static final int AUDIOTRACK_BUFFER_SIZE = 4 * MIN_AUDIOTRACK_BUFFER_SIZE;
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object mLock = new Object();
|
||||||
private AudioTrack audioTrack;
|
private AudioTrack mAudioTrack;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AudioPlayer() {}
|
AudioPlayer() {}
|
||||||
|
|
||||||
private void startPlayback() {
|
private void startPlayback() {
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
if (audioTrack != null) {
|
if (mAudioTrack != null) {
|
||||||
Log.w(TAG, "Received startPlayback command without stopping the playback first");
|
Log.w(TAG, "Received startPlayback command without stopping the playback first");
|
||||||
stopPlayback();
|
stopPlayback();
|
||||||
}
|
}
|
||||||
audioTrack =
|
mAudioTrack =
|
||||||
new AudioTrack.Builder()
|
new AudioTrack.Builder()
|
||||||
.setAudioFormat(AUDIO_FORMAT)
|
.setAudioFormat(AUDIO_FORMAT)
|
||||||
.setAudioAttributes(AUDIO_ATTRIBUTES)
|
.setAudioAttributes(AUDIO_ATTRIBUTES)
|
||||||
.setBufferSizeInBytes(AUDIOTRACK_BUFFER_SIZE)
|
.setBufferSizeInBytes(AUDIOTRACK_BUFFER_SIZE)
|
||||||
.build();
|
.build();
|
||||||
audioTrack.play();
|
mAudioTrack.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,14 +76,14 @@ final class AudioPlayer implements Consumer<RemoteEvent> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int bytesWritten = 0;
|
int bytesWritten = 0;
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
if (audioTrack == null) {
|
if (mAudioTrack == null) {
|
||||||
Log.e(TAG, "Received audio frame, but audio track was not initialized yet");
|
Log.e(TAG, "Received audio frame, but audio track was not initialized yet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bytesToWrite > 0) {
|
while (bytesToWrite > 0) {
|
||||||
int ret = audioTrack.write(data, bytesWritten, bytesToWrite);
|
int ret = mAudioTrack.write(data, bytesWritten, bytesToWrite);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
Log.e(TAG, "AudioTrack.write returned error code " + ret);
|
Log.e(TAG, "AudioTrack.write returned error code " + ret);
|
||||||
}
|
}
|
||||||
@@ -94,13 +94,13 @@ final class AudioPlayer implements Consumer<RemoteEvent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void stopPlayback() {
|
private void stopPlayback() {
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
if (audioTrack == null) {
|
if (mAudioTrack == null) {
|
||||||
Log.w(TAG, "Received stopPlayback command for already stopped playback");
|
Log.w(TAG, "Received stopPlayback command for already stopped playback");
|
||||||
} else {
|
} else {
|
||||||
audioTrack.stop();
|
mAudioTrack.stop();
|
||||||
audioTrack.release();
|
mAudioTrack.release();
|
||||||
audioTrack = null;
|
mAudioTrack = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
/** Recycler view that can resize a child dynamically. */
|
/** Recycler view that can resize a child dynamically. */
|
||||||
public final class ClientView extends RecyclerView {
|
public final class ClientView extends RecyclerView {
|
||||||
private boolean isResizing = false;
|
private boolean mIsResizing = false;
|
||||||
private Consumer<Rect> resizeDoneCallback = null;
|
private Consumer<Rect> mResizeDoneCallback = null;
|
||||||
private Drawable resizingRect = null;
|
private Drawable mResizingRect = null;
|
||||||
private Rect resizingBounds = new Rect();
|
private final Rect mResizingBounds = new Rect();
|
||||||
private float resizeOffsetX = 0;
|
private float mResizeOffsetX = 0;
|
||||||
private float resizeOffsetY = 0;
|
private float mResizeOffsetY = 0;
|
||||||
|
|
||||||
public ClientView(Context context) {
|
public ClientView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@@ -53,48 +53,44 @@ public final class ClientView extends RecyclerView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
resizingRect = getContext().getResources().getDrawable(R.drawable.resize_rect);
|
mResizingRect = getContext().getResources().getDrawable(R.drawable.resize_rect, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startResizing(View viewToResize, MotionEvent origin, Consumer<Rect> callback) {
|
void startResizing(View viewToResize, MotionEvent origin, Consumer<Rect> callback) {
|
||||||
isResizing = true;
|
mIsResizing = true;
|
||||||
resizeDoneCallback = callback;
|
mResizeDoneCallback = callback;
|
||||||
viewToResize.getGlobalVisibleRect(resizingBounds);
|
viewToResize.getGlobalVisibleRect(mResizingBounds);
|
||||||
resizingRect.setBounds(resizingBounds);
|
mResizingRect.setBounds(mResizingBounds);
|
||||||
getRootView().getOverlay().add(resizingRect);
|
getRootView().getOverlay().add(mResizingRect);
|
||||||
resizeOffsetX = origin.getRawX() - resizingBounds.right;
|
mResizeOffsetX = origin.getRawX() - mResizingBounds.right;
|
||||||
resizeOffsetY = origin.getRawY() - resizingBounds.top;
|
mResizeOffsetY = origin.getRawY() - mResizingBounds.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopResizing() {
|
private void stopResizing() {
|
||||||
if (!isResizing) {
|
if (!mIsResizing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
isResizing = false;
|
mIsResizing = false;
|
||||||
resizeOffsetX = resizeOffsetY = 0;
|
mResizeOffsetX = mResizeOffsetY = 0;
|
||||||
getRootView().getOverlay().clear();
|
getRootView().getOverlay().clear();
|
||||||
if (resizeDoneCallback != null) {
|
if (mResizeDoneCallback != null) {
|
||||||
resizeDoneCallback.accept(resizingBounds);
|
mResizeDoneCallback.accept(mResizingBounds);
|
||||||
resizeDoneCallback = null;
|
mResizeDoneCallback = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||||
if (!isResizing) {
|
if (!mIsResizing) {
|
||||||
return super.dispatchTouchEvent(ev);
|
return super.dispatchTouchEvent(ev);
|
||||||
}
|
}
|
||||||
switch (ev.getAction()) {
|
switch (ev.getAction()) {
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP -> stopResizing();
|
||||||
stopResizing();
|
case MotionEvent.ACTION_MOVE -> {
|
||||||
break;
|
mResizingBounds.right = (int) (ev.getRawX() - mResizeOffsetX);
|
||||||
case MotionEvent.ACTION_MOVE:
|
mResizingBounds.top = (int) (ev.getRawY() - mResizeOffsetY);
|
||||||
resizingBounds.right = (int) (ev.getRawX() - resizeOffsetX);
|
mResizingRect.setBounds(mResizingBounds);
|
||||||
resizingBounds.top = (int) (ev.getRawY() - resizeOffsetY);
|
}
|
||||||
resizingRect.setBounds(resizingBounds);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||||
|
|
||||||
@@ -46,34 +47,35 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
||||||
private static final String TAG = "VdmClient";
|
private static final String TAG = "VdmClient";
|
||||||
|
|
||||||
private static final AtomicInteger nextDisplayIndex = new AtomicInteger(1);
|
private static final AtomicInteger sNextDisplayIndex = new AtomicInteger(1);
|
||||||
|
|
||||||
// Simple list of all active displays.
|
// Simple list of all active displays.
|
||||||
private final List<RemoteDisplay> displayRepository =
|
private final List<RemoteDisplay> mDisplayRepository =
|
||||||
Collections.synchronizedList(new ArrayList<>());
|
Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
private final RemoteIo remoteIo;
|
private final RemoteIo mRemoteIo;
|
||||||
private final ClientView recyclerView;
|
private final ClientView mRecyclerView;
|
||||||
private final InputManager inputManager;
|
private final InputManager mInputManager;
|
||||||
|
|
||||||
DisplayAdapter(ClientView recyclerView, RemoteIo remoteIo, InputManager inputManager) {
|
DisplayAdapter(ClientView recyclerView, RemoteIo remoteIo, InputManager inputManager) {
|
||||||
this.recyclerView = recyclerView;
|
mRecyclerView = recyclerView;
|
||||||
this.remoteIo = remoteIo;
|
mRemoteIo = remoteIo;
|
||||||
this.inputManager = inputManager;
|
mInputManager = inputManager;
|
||||||
setHasStableIds(true);
|
setHasStableIds(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDisplay(boolean homeSupported) {
|
void addDisplay(boolean homeSupported) {
|
||||||
Log.i(TAG, "Adding display " + nextDisplayIndex);
|
Log.i(TAG, "Adding display " + sNextDisplayIndex);
|
||||||
displayRepository.add(new RemoteDisplay(nextDisplayIndex.getAndIncrement(), homeSupported));
|
mDisplayRepository.add(
|
||||||
notifyItemInserted(displayRepository.size() - 1);
|
new RemoteDisplay(sNextDisplayIndex.getAndIncrement(), homeSupported));
|
||||||
|
notifyItemInserted(mDisplayRepository.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeDisplay(int displayId) {
|
void removeDisplay(int displayId) {
|
||||||
Log.i(TAG, "Removing display " + displayId);
|
Log.i(TAG, "Removing display " + displayId);
|
||||||
for (int i = 0; i < displayRepository.size(); ++i) {
|
for (int i = 0; i < mDisplayRepository.size(); ++i) {
|
||||||
if (displayId == displayRepository.get(i).getDisplayId()) {
|
if (displayId == mDisplayRepository.get(i).getDisplayId()) {
|
||||||
displayRepository.remove(i);
|
mDisplayRepository.remove(i);
|
||||||
notifyItemRemoved(i);
|
notifyItemRemoved(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -97,24 +99,25 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
|
|
||||||
void clearDisplays() {
|
void clearDisplays() {
|
||||||
Log.i(TAG, "Clearing all displays");
|
Log.i(TAG, "Clearing all displays");
|
||||||
int size = displayRepository.size();
|
int size = mDisplayRepository.size();
|
||||||
displayRepository.clear();
|
mDisplayRepository.clear();
|
||||||
notifyItemRangeRemoved(0, size);
|
notifyItemRangeRemoved(0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DisplayHolder getDisplayHolder(int displayId) {
|
private DisplayHolder getDisplayHolder(int displayId) {
|
||||||
for (int i = 0; i < displayRepository.size(); ++i) {
|
for (int i = 0; i < mDisplayRepository.size(); ++i) {
|
||||||
if (displayId == displayRepository.get(i).getDisplayId()) {
|
if (displayId == mDisplayRepository.get(i).getDisplayId()) {
|
||||||
return (DisplayHolder) recyclerView.findViewHolderForAdapterPosition(i);
|
return (DisplayHolder) mRecyclerView.findViewHolderForAdapterPosition(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public DisplayHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public DisplayHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
// Disable recycling so layout changes are not present in new displays.
|
// Disable recycling so layout changes are not present in new displays.
|
||||||
recyclerView.getRecycledViewPool().setMaxRecycledViews(viewType, 0);
|
mRecyclerView.getRecycledViewPool().setMaxRecycledViews(viewType, 0);
|
||||||
View view =
|
View view =
|
||||||
LayoutInflater.from(parent.getContext())
|
LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.display_fragment, parent, false);
|
.inflate(R.layout.display_fragment, parent, false);
|
||||||
@@ -133,12 +136,12 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getItemId(int position) {
|
public long getItemId(int position) {
|
||||||
return displayRepository.get(position).getDisplayId();
|
return mDisplayRepository.get(position).getDisplayId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return displayRepository.size();
|
return mDisplayRepository.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DisplayHolder extends ViewHolder {
|
public class DisplayHolder extends ViewHolder {
|
||||||
@@ -216,8 +219,8 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
void close() {
|
void close() {
|
||||||
if (displayController != null) {
|
if (displayController != null) {
|
||||||
Log.i(TAG, "Closing DisplayHolder for display " + displayId);
|
Log.i(TAG, "Closing DisplayHolder for display " + displayId);
|
||||||
inputManager.removeFocusListener(focusListener);
|
mInputManager.removeFocusListener(focusListener);
|
||||||
inputManager.removeFocusableDisplay(displayId);
|
mInputManager.removeFocusableDisplay(displayId);
|
||||||
displayController.close();
|
displayController.close();
|
||||||
displayController = null;
|
displayController = null;
|
||||||
}
|
}
|
||||||
@@ -225,7 +228,7 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
void onBind(int position) {
|
void onBind(int position) {
|
||||||
RemoteDisplay remoteDisplay = displayRepository.get(position);
|
RemoteDisplay remoteDisplay = mDisplayRepository.get(position);
|
||||||
displayId = remoteDisplay.getDisplayId();
|
displayId = remoteDisplay.getDisplayId();
|
||||||
Log.v(
|
Log.v(
|
||||||
TAG,
|
TAG,
|
||||||
@@ -244,9 +247,9 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
displayFocusIndicator.setBackground(null);
|
displayFocusIndicator.setBackground(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
inputManager.addFocusListener(focusListener);
|
mInputManager.addFocusListener(focusListener);
|
||||||
|
|
||||||
displayController = new DisplayController(displayId, remoteIo);
|
displayController = new DisplayController(displayId, mRemoteIo);
|
||||||
Log.v(TAG, "Creating new DisplayController for display " + displayId);
|
Log.v(TAG, "Creating new DisplayController for display " + displayId);
|
||||||
|
|
||||||
setDisplayTitle("");
|
setDisplayTitle("");
|
||||||
@@ -256,12 +259,12 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
v -> ((DisplayAdapter) getBindingAdapter()).removeDisplay(displayId));
|
v -> ((DisplayAdapter) getBindingAdapter()).removeDisplay(displayId));
|
||||||
|
|
||||||
View backButton = itemView.findViewById(R.id.display_back);
|
View backButton = itemView.findViewById(R.id.display_back);
|
||||||
backButton.setOnClickListener(v -> inputManager.sendBack(displayId));
|
backButton.setOnClickListener(v -> mInputManager.sendBack(displayId));
|
||||||
|
|
||||||
View homeButton = itemView.findViewById(R.id.display_home);
|
View homeButton = itemView.findViewById(R.id.display_home);
|
||||||
if (remoteDisplay.isHomeSupported()) {
|
if (remoteDisplay.isHomeSupported()) {
|
||||||
homeButton.setVisibility(View.VISIBLE);
|
homeButton.setVisibility(View.VISIBLE);
|
||||||
homeButton.setOnClickListener(v -> inputManager.sendHome(displayId));
|
homeButton.setOnClickListener(v -> mInputManager.sendHome(displayId));
|
||||||
} else {
|
} else {
|
||||||
homeButton.setVisibility(View.GONE);
|
homeButton.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
@@ -283,7 +286,7 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
resizeButton.setOnTouchListener(
|
resizeButton.setOnTouchListener(
|
||||||
(v, event) -> {
|
(v, event) -> {
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
recyclerView.startResizing(
|
mRecyclerView.startResizing(
|
||||||
textureView, event, DisplayHolder.this::resizeDisplay);
|
textureView, event, DisplayHolder.this::resizeDisplay);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -294,7 +297,7 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
(v, event) -> {
|
(v, event) -> {
|
||||||
if (event.getDevice().supportsSource(InputDevice.SOURCE_TOUCHSCREEN)) {
|
if (event.getDevice().supportsSource(InputDevice.SOURCE_TOUCHSCREEN)) {
|
||||||
textureView.getParent().requestDisallowInterceptTouchEvent(true);
|
textureView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||||
inputManager.sendInputEvent(
|
mInputManager.sendInputEvent(
|
||||||
InputDeviceType.DEVICE_TYPE_TOUCHSCREEN, event, displayId);
|
InputDeviceType.DEVICE_TYPE_TOUCHSCREEN, event, displayId);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -302,19 +305,19 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
textureView.setSurfaceTextureListener(
|
textureView.setSurfaceTextureListener(
|
||||||
new TextureView.SurfaceTextureListener() {
|
new TextureView.SurfaceTextureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceTextureUpdated(SurfaceTexture texture) {}
|
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture texture) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceTextureAvailable(
|
public void onSurfaceTextureAvailable(
|
||||||
SurfaceTexture texture, int width, int height) {
|
@NonNull SurfaceTexture texture, int width, int height) {
|
||||||
Log.v(TAG, "Setting surface for display " + displayId);
|
Log.v(TAG, "Setting surface for display " + displayId);
|
||||||
inputManager.addFocusableDisplay(displayId);
|
mInputManager.addFocusableDisplay(displayId);
|
||||||
surface = new Surface(texture);
|
surface = new Surface(texture);
|
||||||
displayController.setSurface(surface, width, height);
|
displayController.setSurface(surface, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
|
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture texture) {
|
||||||
Log.v(TAG, "onSurfaceTextureDestroyed for display " + displayId);
|
Log.v(TAG, "onSurfaceTextureDestroyed for display " + displayId);
|
||||||
if (displayController != null) {
|
if (displayController != null) {
|
||||||
displayController.pause();
|
displayController.pause();
|
||||||
@@ -324,7 +327,7 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceTextureSizeChanged(
|
public void onSurfaceTextureSizeChanged(
|
||||||
SurfaceTexture texture, int width, int height) {
|
@NonNull SurfaceTexture texture, int width, int height) {
|
||||||
Log.v(TAG, "onSurfaceTextureSizeChanged for display " + displayId);
|
Log.v(TAG, "onSurfaceTextureSizeChanged for display " + displayId);
|
||||||
textureView.setRotation(0);
|
textureView.setRotation(0);
|
||||||
rotateButton.setEnabled(true);
|
rotateButton.setEnabled(true);
|
||||||
@@ -336,7 +339,7 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
|| !event.getDevice().supportsSource(InputDevice.SOURCE_MOUSE)) {
|
|| !event.getDevice().supportsSource(InputDevice.SOURCE_MOUSE)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inputManager.sendInputEventToFocusedDisplay(
|
mInputManager.sendInputEventToFocusedDisplay(
|
||||||
InputDeviceType.DEVICE_TYPE_MOUSE, event);
|
InputDeviceType.DEVICE_TYPE_MOUSE, event);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -345,20 +348,20 @@ final class DisplayAdapter extends RecyclerView.Adapter<DisplayHolder> {
|
|||||||
|
|
||||||
private static class RemoteDisplay {
|
private static class RemoteDisplay {
|
||||||
// Local ID, not corresponding to the displayId of the relevant Display on the host device.
|
// Local ID, not corresponding to the displayId of the relevant Display on the host device.
|
||||||
private final int displayId;
|
private final int mDisplayId;
|
||||||
private final boolean homeSupported;
|
private final boolean mHomeSupported;
|
||||||
|
|
||||||
RemoteDisplay(int displayId, boolean homeSupported) {
|
RemoteDisplay(int displayId, boolean homeSupported) {
|
||||||
this.displayId = displayId;
|
mDisplayId = displayId;
|
||||||
this.homeSupported = homeSupported;
|
mHomeSupported = homeSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getDisplayId() {
|
int getDisplayId() {
|
||||||
return displayId;
|
return mDisplayId;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isHomeSupported() {
|
boolean isHomeSupported() {
|
||||||
return homeSupported;
|
return mHomeSupported;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,71 +27,71 @@ import com.example.android.vdmdemo.common.VideoManager;
|
|||||||
final class DisplayController {
|
final class DisplayController {
|
||||||
private static final int DPI = 300;
|
private static final int DPI = 300;
|
||||||
|
|
||||||
private final int displayId;
|
private final int mDisplayId;
|
||||||
private final RemoteIo remoteIo;
|
private final RemoteIo mRemoteIo;
|
||||||
|
|
||||||
private VideoManager videoManager = null;
|
private VideoManager mVideoManager = null;
|
||||||
|
|
||||||
private int dpi = DPI;
|
private int mDpi = DPI;
|
||||||
private RemoteEvent displayCapabilities;
|
private RemoteEvent mDisplayCapabilities;
|
||||||
|
|
||||||
DisplayController(int displayId, RemoteIo remoteIo) {
|
DisplayController(int displayId, RemoteIo remoteIo) {
|
||||||
this.displayId = displayId;
|
mDisplayId = displayId;
|
||||||
this.remoteIo = remoteIo;
|
mRemoteIo = remoteIo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDpi(int dpi) {
|
void setDpi(int dpi) {
|
||||||
this.dpi = dpi;
|
mDpi = dpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getDpi() {
|
int getDpi() {
|
||||||
return dpi;
|
return mDpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
remoteIo.sendMessage(
|
mRemoteIo.sendMessage(
|
||||||
RemoteEvent.newBuilder()
|
RemoteEvent.newBuilder()
|
||||||
.setDisplayId(displayId)
|
.setDisplayId(mDisplayId)
|
||||||
.setStopStreaming(StopStreaming.newBuilder())
|
.setStopStreaming(StopStreaming.newBuilder())
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
if (videoManager != null) {
|
if (mVideoManager != null) {
|
||||||
videoManager.stop();
|
mVideoManager.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pause() {
|
void pause() {
|
||||||
if (videoManager == null) {
|
if (mVideoManager == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
videoManager.stop();
|
mVideoManager.stop();
|
||||||
videoManager = null;
|
mVideoManager = null;
|
||||||
|
|
||||||
remoteIo.sendMessage(
|
mRemoteIo.sendMessage(
|
||||||
RemoteEvent.newBuilder()
|
RemoteEvent.newBuilder()
|
||||||
.setDisplayId(displayId)
|
.setDisplayId(mDisplayId)
|
||||||
.setStopStreaming(StopStreaming.newBuilder().setPause(true))
|
.setStopStreaming(StopStreaming.newBuilder().setPause(true))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendDisplayCapabilities() {
|
void sendDisplayCapabilities() {
|
||||||
remoteIo.sendMessage(displayCapabilities);
|
mRemoteIo.sendMessage(mDisplayCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSurface(Surface surface, int width, int height) {
|
void setSurface(Surface surface, int width, int height) {
|
||||||
if (videoManager != null) {
|
if (mVideoManager != null) {
|
||||||
videoManager.stop();
|
mVideoManager.stop();
|
||||||
}
|
}
|
||||||
videoManager = VideoManager.createDecoder(displayId, remoteIo);
|
mVideoManager = VideoManager.createDecoder(mDisplayId, mRemoteIo);
|
||||||
videoManager.startDecoding(surface, width, height);
|
mVideoManager.startDecoding(surface, width, height);
|
||||||
displayCapabilities =
|
mDisplayCapabilities =
|
||||||
RemoteEvent.newBuilder()
|
RemoteEvent.newBuilder()
|
||||||
.setDisplayId(displayId)
|
.setDisplayId(mDisplayId)
|
||||||
.setDisplayCapabilities(
|
.setDisplayCapabilities(
|
||||||
DisplayCapabilities.newBuilder()
|
DisplayCapabilities.newBuilder()
|
||||||
.setViewportWidth(width)
|
.setViewportWidth(width)
|
||||||
.setViewportHeight(height)
|
.setViewportHeight(height)
|
||||||
.setDensityDpi(dpi))
|
.setDensityDpi(mDpi))
|
||||||
.build();
|
.build();
|
||||||
sendDisplayCapabilities();
|
sendDisplayCapabilities();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public final class DpadFragment extends Hilt_DpadFragment {
|
|||||||
R.id.dpad_center, R.id.dpad_down, R.id.dpad_left, R.id.dpad_up, R.id.dpad_right
|
R.id.dpad_center, R.id.dpad_down, R.id.dpad_left, R.id.dpad_up, R.id.dpad_right
|
||||||
};
|
};
|
||||||
|
|
||||||
@Inject InputManager inputManager;
|
@Inject InputManager mInputManager;
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
@@ -87,7 +87,7 @@ public final class DpadFragment extends Hilt_DpadFragment {
|
|||||||
Log.w(TAG, "onDpadButtonClick: Method called from a non Dpad button");
|
Log.w(TAG, "onDpadButtonClick: Method called from a non Dpad button");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inputManager.sendInputEventToFocusedDisplay(
|
mInputManager.sendInputEventToFocusedDisplay(
|
||||||
InputDeviceType.DEVICE_TYPE_DPAD,
|
InputDeviceType.DEVICE_TYPE_DPAD,
|
||||||
new KeyEvent(
|
new KeyEvent(
|
||||||
/* downTime= */ System.currentTimeMillis(),
|
/* downTime= */ System.currentTimeMillis(),
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.view.Surface;
|
|||||||
import android.view.TextureView;
|
import android.view.TextureView;
|
||||||
|
|
||||||
import androidx.activity.OnBackPressedCallback;
|
import androidx.activity.OnBackPressedCallback;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.view.WindowCompat;
|
import androidx.core.view.WindowCompat;
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
@@ -48,25 +49,22 @@ import javax.inject.Inject;
|
|||||||
*/
|
*/
|
||||||
@AndroidEntryPoint(AppCompatActivity.class)
|
@AndroidEntryPoint(AppCompatActivity.class)
|
||||||
public class ImmersiveActivity extends Hilt_ImmersiveActivity {
|
public class ImmersiveActivity extends Hilt_ImmersiveActivity {
|
||||||
private static final String TAG = "VdmImmersiveActivity";
|
|
||||||
|
|
||||||
// Approximately, see
|
// Approximately, see
|
||||||
// https://developer.android.com/reference/android/util/DisplayMetrics#density
|
// https://developer.android.com/reference/android/util/DisplayMetrics#density
|
||||||
private static final float DIP_TO_DPI = 160f;
|
private static final float DIP_TO_DPI = 160f;
|
||||||
|
|
||||||
@Inject ConnectionManager connectionManager;
|
@Inject ConnectionManager mConnectionManager;
|
||||||
@Inject RemoteIo remoteIo;
|
@Inject RemoteIo mRemoteIo;
|
||||||
@Inject VirtualSensorController sensorController;
|
@Inject VirtualSensorController mSensorController;
|
||||||
@Inject AudioPlayer audioPlayer;
|
@Inject AudioPlayer mAudioPlayer;
|
||||||
@Inject InputManager inputManager;
|
@Inject InputManager mInputManager;
|
||||||
|
|
||||||
private DisplayController displayController;
|
private DisplayController mDisplayController;
|
||||||
private final Consumer<RemoteEvent> remoteEventConsumer = this::processRemoteEvent;
|
private final Consumer<RemoteEvent> mRemoteEventConsumer = this::processRemoteEvent;
|
||||||
|
|
||||||
private final ConnectionManager.ConnectionCallback connectionCallback =
|
private final ConnectionManager.ConnectionCallback mConnectionCallback =
|
||||||
new ConnectionManager.ConnectionCallback() {
|
new ConnectionManager.ConnectionCallback() {
|
||||||
@Override
|
|
||||||
public void onConnected(String remoteDeviceName) {}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnected() {
|
public void onDisconnected() {
|
||||||
@@ -91,20 +89,20 @@ public class ImmersiveActivity extends Hilt_ImmersiveActivity {
|
|||||||
new OnBackPressedCallback(true) {
|
new OnBackPressedCallback(true) {
|
||||||
@Override
|
@Override
|
||||||
public void handleOnBackPressed() {
|
public void handleOnBackPressed() {
|
||||||
inputManager.sendBack(DEFAULT_DISPLAY);
|
mInputManager.sendBack(DEFAULT_DISPLAY);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getOnBackPressedDispatcher().addCallback(this, callback);
|
getOnBackPressedDispatcher().addCallback(this, callback);
|
||||||
|
|
||||||
displayController = new DisplayController(DEFAULT_DISPLAY, remoteIo);
|
mDisplayController = new DisplayController(DEFAULT_DISPLAY, mRemoteIo);
|
||||||
displayController.setDpi((int) (getResources().getDisplayMetrics().density * DIP_TO_DPI));
|
mDisplayController.setDpi((int) (getResources().getDisplayMetrics().density * DIP_TO_DPI));
|
||||||
|
|
||||||
TextureView textureView = findViewById(R.id.immersive_surface_view);
|
TextureView textureView = findViewById(R.id.immersive_surface_view);
|
||||||
textureView.setOnTouchListener(
|
textureView.setOnTouchListener(
|
||||||
(v, event) -> {
|
(v, event) -> {
|
||||||
if (event.getDevice().supportsSource(InputDevice.SOURCE_TOUCHSCREEN)) {
|
if (event.getDevice().supportsSource(InputDevice.SOURCE_TOUCHSCREEN)) {
|
||||||
textureView.getParent().requestDisallowInterceptTouchEvent(true);
|
textureView.getParent().requestDisallowInterceptTouchEvent(true);
|
||||||
inputManager.sendInputEvent(
|
mInputManager.sendInputEvent(
|
||||||
InputDeviceType.DEVICE_TYPE_TOUCHSCREEN, event, DEFAULT_DISPLAY);
|
InputDeviceType.DEVICE_TYPE_TOUCHSCREEN, event, DEFAULT_DISPLAY);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -112,53 +110,53 @@ public class ImmersiveActivity extends Hilt_ImmersiveActivity {
|
|||||||
textureView.setSurfaceTextureListener(
|
textureView.setSurfaceTextureListener(
|
||||||
new TextureView.SurfaceTextureListener() {
|
new TextureView.SurfaceTextureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceTextureUpdated(SurfaceTexture texture) {}
|
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture texture) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceTextureAvailable(
|
public void onSurfaceTextureAvailable(
|
||||||
SurfaceTexture texture, int width, int height) {
|
@NonNull SurfaceTexture texture, int width, int height) {
|
||||||
displayController.setSurface(new Surface(texture), width, height);
|
mDisplayController.setSurface(new Surface(texture), width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
|
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture texture) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceTextureSizeChanged(
|
public void onSurfaceTextureSizeChanged(
|
||||||
SurfaceTexture texture, int width, int height) {}
|
@NonNull SurfaceTexture texture, int width, int height) {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
connectionManager.addConnectionCallback(connectionCallback);
|
mConnectionManager.addConnectionCallback(mConnectionCallback);
|
||||||
remoteIo.addMessageConsumer(audioPlayer);
|
mRemoteIo.addMessageConsumer(mAudioPlayer);
|
||||||
remoteIo.addMessageConsumer(remoteEventConsumer);
|
mRemoteIo.addMessageConsumer(mRemoteEventConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
connectionManager.removeConnectionCallback(connectionCallback);
|
mConnectionManager.removeConnectionCallback(mConnectionCallback);
|
||||||
remoteIo.removeMessageConsumer(audioPlayer);
|
mRemoteIo.removeMessageConsumer(mAudioPlayer);
|
||||||
remoteIo.removeMessageConsumer(remoteEventConsumer);
|
mRemoteIo.removeMessageConsumer(mRemoteEventConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
displayController.close();
|
mDisplayController.close();
|
||||||
sensorController.close();
|
mSensorController.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processRemoteEvent(RemoteEvent event) {
|
private void processRemoteEvent(RemoteEvent event) {
|
||||||
if (event.hasStopStreaming() && !event.getStopStreaming().getPause()) {
|
if (event.hasStopStreaming() && !event.getStopStreaming().getPause()) {
|
||||||
finish();
|
finish();
|
||||||
} else if (event.hasStartStreaming()) {
|
} else if (event.hasStartStreaming()) {
|
||||||
displayController.sendDisplayCapabilities();
|
mDisplayController.sendDisplayCapabilities();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,14 +164,17 @@ public class ImmersiveActivity extends Hilt_ImmersiveActivity {
|
|||||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||||
int keyCode = event.getKeyCode();
|
int keyCode = event.getKeyCode();
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
case KeyEvent.KEYCODE_VOLUME_UP:
|
case KeyEvent.KEYCODE_VOLUME_UP -> {
|
||||||
inputManager.sendHome(DEFAULT_DISPLAY);
|
mInputManager.sendHome(DEFAULT_DISPLAY);
|
||||||
return true;
|
return true;
|
||||||
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
}
|
||||||
|
case KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
||||||
finish();
|
finish();
|
||||||
return true;
|
return true;
|
||||||
default:
|
}
|
||||||
|
default -> {
|
||||||
return super.dispatchKeyEvent(event);
|
return super.dispatchKeyEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,57 +47,57 @@ import javax.inject.Singleton;
|
|||||||
final class InputManager {
|
final class InputManager {
|
||||||
private static final String TAG = "InputManager";
|
private static final String TAG = "InputManager";
|
||||||
|
|
||||||
private final RemoteIo remoteIo;
|
private final RemoteIo mRemoteIo;
|
||||||
private final Settings settings;
|
private final Settings mSettings;
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
@GuardedBy("lock")
|
@GuardedBy("mLock")
|
||||||
private int focusedDisplayId = Display.INVALID_DISPLAY;
|
private int mFocusedDisplayId = Display.INVALID_DISPLAY;
|
||||||
|
|
||||||
@GuardedBy("lock")
|
@GuardedBy("mLock")
|
||||||
private boolean isTrackingFocus = false;
|
private boolean mIsTrackingFocus = false;
|
||||||
|
|
||||||
interface FocusListener {
|
interface FocusListener {
|
||||||
void onFocusChange(int focusedDisplayId);
|
void onFocusChange(int focusedDisplayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("lock")
|
@GuardedBy("mLock")
|
||||||
private final List<FocusListener> focusListeners = new ArrayList<>();
|
private final List<FocusListener> mFocusListeners = new ArrayList<>();
|
||||||
|
|
||||||
@GuardedBy("lock")
|
@GuardedBy("mLock")
|
||||||
private final Set<Integer> focusableDisplays = new HashSet<>();
|
private final Set<Integer> mFocusableDisplays = new HashSet<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
InputManager(RemoteIo remoteIo, Settings settings) {
|
InputManager(RemoteIo remoteIo, Settings settings) {
|
||||||
this.remoteIo = remoteIo;
|
mRemoteIo = remoteIo;
|
||||||
this.settings = settings;
|
mSettings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFocusListener(FocusListener focusListener) {
|
void addFocusListener(FocusListener focusListener) {
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
focusListeners.add(focusListener);
|
mFocusListeners.add(focusListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeFocusListener(FocusListener focusListener) {
|
void removeFocusListener(FocusListener focusListener) {
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
focusListeners.remove(focusListener);
|
mFocusListeners.remove(focusListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFocusableDisplay(int displayId) {
|
void addFocusableDisplay(int displayId) {
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
if (focusableDisplays.add(displayId)) {
|
if (mFocusableDisplays.add(displayId)) {
|
||||||
setFocusedDisplayId(displayId);
|
setFocusedDisplayId(displayId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeFocusableDisplay(int displayId) {
|
void removeFocusableDisplay(int displayId) {
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
focusableDisplays.remove(Integer.valueOf(displayId));
|
mFocusableDisplays.remove(displayId);
|
||||||
if (displayId == focusedDisplayId) {
|
if (displayId == mFocusedDisplayId) {
|
||||||
setFocusedDisplayId(updateFocusedDisplayId());
|
setFocusedDisplayId(updateFocusedDisplayId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,21 +105,21 @@ final class InputManager {
|
|||||||
|
|
||||||
void updateFocusTracking() {
|
void updateFocusTracking() {
|
||||||
boolean shouldTrackFocus =
|
boolean shouldTrackFocus =
|
||||||
settings.dpadEnabled
|
mSettings.dpadEnabled
|
||||||
|| settings.navTouchpadEnabled
|
|| mSettings.navTouchpadEnabled
|
||||||
|| settings.externalKeyboardEnabled
|
|| mSettings.externalKeyboardEnabled
|
||||||
|| settings.externalMouseEnabled;
|
|| mSettings.externalMouseEnabled;
|
||||||
|
|
||||||
List<FocusListener> listenersToNotify = Collections.emptyList();
|
final List<FocusListener> listenersToNotify;
|
||||||
int focusedDisplayIdToNotify = Display.INVALID_DISPLAY;
|
int focusedDisplayIdToNotify = Display.INVALID_DISPLAY;
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
if (shouldTrackFocus != isTrackingFocus) {
|
if (shouldTrackFocus != mIsTrackingFocus) {
|
||||||
isTrackingFocus = shouldTrackFocus;
|
mIsTrackingFocus = shouldTrackFocus;
|
||||||
}
|
}
|
||||||
if (isTrackingFocus) {
|
if (mIsTrackingFocus) {
|
||||||
focusedDisplayIdToNotify = focusedDisplayId;
|
focusedDisplayIdToNotify = mFocusedDisplayId;
|
||||||
}
|
}
|
||||||
listenersToNotify = new ArrayList<>(focusListeners);
|
listenersToNotify = new ArrayList<>(mFocusListeners);
|
||||||
}
|
}
|
||||||
for (FocusListener focusListener : listenersToNotify) {
|
for (FocusListener focusListener : listenersToNotify) {
|
||||||
focusListener.onFocusChange(focusedDisplayIdToNotify);
|
focusListener.onFocusChange(focusedDisplayIdToNotify);
|
||||||
@@ -152,30 +152,30 @@ final class InputManager {
|
|||||||
*/
|
*/
|
||||||
public void sendInputEventToFocusedDisplay(InputDeviceType deviceType, InputEvent inputEvent) {
|
public void sendInputEventToFocusedDisplay(InputDeviceType deviceType, InputEvent inputEvent) {
|
||||||
int targetDisplay;
|
int targetDisplay;
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
if (!isTrackingFocus || focusedDisplayId == Display.INVALID_DISPLAY) {
|
if (!mIsTrackingFocus || mFocusedDisplayId == Display.INVALID_DISPLAY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
targetDisplay = focusedDisplayId;
|
targetDisplay = mFocusedDisplayId;
|
||||||
}
|
}
|
||||||
switch (deviceType) {
|
switch (deviceType) {
|
||||||
case DEVICE_TYPE_NAVIGATION_TOUCHPAD:
|
case DEVICE_TYPE_NAVIGATION_TOUCHPAD:
|
||||||
if (!settings.navTouchpadEnabled) {
|
if (!mSettings.navTouchpadEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEVICE_TYPE_DPAD:
|
case DEVICE_TYPE_DPAD:
|
||||||
if (!settings.dpadEnabled) {
|
if (!mSettings.dpadEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEVICE_TYPE_MOUSE:
|
case DEVICE_TYPE_MOUSE:
|
||||||
if (!settings.externalMouseEnabled) {
|
if (!mSettings.externalMouseEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEVICE_TYPE_KEYBOARD:
|
case DEVICE_TYPE_KEYBOARD:
|
||||||
if (!settings.externalKeyboardEnabled) {
|
if (!mSettings.externalKeyboardEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -206,7 +206,7 @@ final class InputManager {
|
|||||||
|
|
||||||
void sendHome(int displayId) {
|
void sendHome(int displayId) {
|
||||||
setFocusedDisplayId(displayId);
|
setFocusedDisplayId(displayId);
|
||||||
remoteIo.sendMessage(
|
mRemoteIo.sendMessage(
|
||||||
RemoteEvent.newBuilder()
|
RemoteEvent.newBuilder()
|
||||||
.setDisplayId(displayId)
|
.setDisplayId(displayId)
|
||||||
.setHomeEvent(RemoteHomeEvent.newBuilder())
|
.setHomeEvent(RemoteHomeEvent.newBuilder())
|
||||||
@@ -296,7 +296,7 @@ final class InputManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void sendInputEvent(RemoteInputEvent inputEvent, int displayId) {
|
private void sendInputEvent(RemoteInputEvent inputEvent, int displayId) {
|
||||||
remoteIo.sendMessage(
|
mRemoteIo.sendMessage(
|
||||||
RemoteEvent.newBuilder().setDisplayId(displayId).setInputEvent(inputEvent).build());
|
RemoteEvent.newBuilder().setDisplayId(displayId).setInputEvent(inputEvent).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,21 +305,21 @@ final class InputManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int updateFocusedDisplayId() {
|
private int updateFocusedDisplayId() {
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
if (focusableDisplays.contains(focusedDisplayId)) {
|
if (mFocusableDisplays.contains(mFocusedDisplayId)) {
|
||||||
return focusedDisplayId;
|
return mFocusedDisplayId;
|
||||||
}
|
}
|
||||||
return Iterables.getFirst(focusableDisplays, Display.INVALID_DISPLAY);
|
return Iterables.getFirst(mFocusableDisplays, Display.INVALID_DISPLAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFocusedDisplayId(int displayId) {
|
private void setFocusedDisplayId(int displayId) {
|
||||||
List<FocusListener> listenersToNotify = Collections.emptyList();
|
List<FocusListener> listenersToNotify = Collections.emptyList();
|
||||||
synchronized (lock) {
|
synchronized (mLock) {
|
||||||
if (displayId != focusedDisplayId) {
|
if (displayId != mFocusedDisplayId) {
|
||||||
focusedDisplayId = displayId;
|
mFocusedDisplayId = displayId;
|
||||||
if (isTrackingFocus) {
|
if (mIsTrackingFocus) {
|
||||||
listenersToNotify = new ArrayList<>(focusListeners);
|
listenersToNotify = new ArrayList<>(mFocusListeners);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,45 +49,45 @@ import javax.inject.Inject;
|
|||||||
@AndroidEntryPoint(AppCompatActivity.class)
|
@AndroidEntryPoint(AppCompatActivity.class)
|
||||||
public class MainActivity extends Hilt_MainActivity {
|
public class MainActivity extends Hilt_MainActivity {
|
||||||
|
|
||||||
@Inject RemoteIo remoteIo;
|
@Inject RemoteIo mRemoteIo;
|
||||||
@Inject ConnectionManager connectionManager;
|
@Inject ConnectionManager mConnectionManager;
|
||||||
@Inject InputManager inputManager;
|
@Inject InputManager mInputManager;
|
||||||
@Inject VirtualSensorController sensorController;
|
@Inject VirtualSensorController mSensorController;
|
||||||
@Inject AudioPlayer audioPlayer;
|
@Inject AudioPlayer mAudioPlayer;
|
||||||
@Inject Settings settings;
|
@Inject Settings mSettings;
|
||||||
|
|
||||||
private final Consumer<RemoteEvent> remoteEventConsumer = this::processRemoteEvent;
|
private final Consumer<RemoteEvent> mRemoteEventConsumer = this::processRemoteEvent;
|
||||||
private DisplayAdapter displayAdapter;
|
private DisplayAdapter mDisplayAdapter;
|
||||||
private final InputManager.FocusListener focusListener = this::onDisplayFocusChange;
|
private final InputManager.FocusListener mFocusListener = this::onDisplayFocusChange;
|
||||||
|
|
||||||
private final ConnectionManager.ConnectionCallback connectionCallback =
|
private final ConnectionManager.ConnectionCallback mConnectionCallback =
|
||||||
new ConnectionManager.ConnectionCallback() {
|
new ConnectionManager.ConnectionCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnecting(String remoteDeviceName) {
|
public void onConnecting(String remoteDeviceName) {
|
||||||
connectionManager.stopAdvertising();
|
mConnectionManager.stopAdvertising();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnected(String remoteDeviceName) {
|
public void onConnected(String remoteDeviceName) {
|
||||||
remoteIo.sendMessage(
|
mRemoteIo.sendMessage(
|
||||||
RemoteEvent.newBuilder()
|
RemoteEvent.newBuilder()
|
||||||
.setDeviceCapabilities(
|
.setDeviceCapabilities(
|
||||||
DeviceCapabilities.newBuilder()
|
DeviceCapabilities.newBuilder()
|
||||||
.setDeviceName(Build.MODEL)
|
.setDeviceName(Build.MODEL)
|
||||||
.addAllSensorCapabilities(
|
.addAllSensorCapabilities(
|
||||||
(sensorController
|
(mSensorController
|
||||||
.getSensorCapabilities())))
|
.getSensorCapabilities())))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnected() {
|
public void onDisconnected() {
|
||||||
if (displayAdapter != null) {
|
if (mDisplayAdapter != null) {
|
||||||
runOnUiThread(displayAdapter::clearDisplays);
|
runOnUiThread(mDisplayAdapter::clearDisplays);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionManager.startAdvertising();
|
mConnectionManager.startAdvertising();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -104,36 +104,36 @@ public class MainActivity extends Hilt_MainActivity {
|
|||||||
displaysView.setLayoutManager(
|
displaysView.setLayoutManager(
|
||||||
new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
|
new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
|
||||||
displaysView.setItemAnimator(null);
|
displaysView.setItemAnimator(null);
|
||||||
displayAdapter = new DisplayAdapter(displaysView, remoteIo, inputManager);
|
mDisplayAdapter = new DisplayAdapter(displaysView, mRemoteIo, mInputManager);
|
||||||
displaysView.setAdapter(displayAdapter);
|
displaysView.setAdapter(mDisplayAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
connectionManager.addConnectionCallback(connectionCallback);
|
mConnectionManager.addConnectionCallback(mConnectionCallback);
|
||||||
connectionManager.startAdvertising();
|
mConnectionManager.startAdvertising();
|
||||||
inputManager.addFocusListener(focusListener);
|
mInputManager.addFocusListener(mFocusListener);
|
||||||
remoteIo.addMessageConsumer(audioPlayer);
|
mRemoteIo.addMessageConsumer(mAudioPlayer);
|
||||||
remoteIo.addMessageConsumer(remoteEventConsumer);
|
mRemoteIo.addMessageConsumer(mRemoteEventConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
inputManager.removeFocusListener(focusListener);
|
mInputManager.removeFocusListener(mFocusListener);
|
||||||
connectionManager.removeConnectionCallback(connectionCallback);
|
mConnectionManager.removeConnectionCallback(mConnectionCallback);
|
||||||
connectionManager.stopAdvertising();
|
mConnectionManager.stopAdvertising();
|
||||||
remoteIo.removeMessageConsumer(remoteEventConsumer);
|
mRemoteIo.removeMessageConsumer(mRemoteEventConsumer);
|
||||||
remoteIo.removeMessageConsumer(audioPlayer);
|
mRemoteIo.removeMessageConsumer(mAudioPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
displayAdapter.clearDisplays();
|
mDisplayAdapter.clearDisplays();
|
||||||
connectionManager.disconnect();
|
mConnectionManager.disconnect();
|
||||||
sensorController.close();
|
mSensorController.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -142,7 +142,7 @@ public class MainActivity extends Hilt_MainActivity {
|
|||||||
|| !event.getDevice().supportsSource(InputDevice.SOURCE_KEYBOARD)) {
|
|| !event.getDevice().supportsSource(InputDevice.SOURCE_KEYBOARD)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inputManager.sendInputEventToFocusedDisplay(InputDeviceType.DEVICE_TYPE_KEYBOARD, event);
|
mInputManager.sendInputEventToFocusedDisplay(InputDeviceType.DEVICE_TYPE_KEYBOARD, event);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,18 +153,11 @@ public class MainActivity extends Hilt_MainActivity {
|
|||||||
for (int i = 0; i < menu.size(); ++i) {
|
for (int i = 0; i < menu.size(); ++i) {
|
||||||
MenuItem item = menu.getItem(i);
|
MenuItem item = menu.getItem(i);
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.enable_dpad:
|
case R.id.enable_dpad -> item.setChecked(mSettings.dpadEnabled);
|
||||||
item.setChecked(settings.dpadEnabled);
|
case R.id.enable_nav_touchpad -> item.setChecked(mSettings.navTouchpadEnabled);
|
||||||
break;
|
case R.id.enable_external_keyboard -> item.setChecked(
|
||||||
case R.id.enable_nav_touchpad:
|
mSettings.externalKeyboardEnabled);
|
||||||
item.setChecked(settings.navTouchpadEnabled);
|
case R.id.enable_external_mouse -> item.setChecked(mSettings.externalMouseEnabled);
|
||||||
break;
|
|
||||||
case R.id.enable_external_keyboard:
|
|
||||||
item.setChecked(settings.externalKeyboardEnabled);
|
|
||||||
break;
|
|
||||||
case R.id.enable_external_mouse:
|
|
||||||
item.setChecked(settings.externalMouseEnabled);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -175,23 +168,17 @@ public class MainActivity extends Hilt_MainActivity {
|
|||||||
item.setChecked(!item.isChecked());
|
item.setChecked(!item.isChecked());
|
||||||
|
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.enable_dpad:
|
case R.id.enable_dpad -> mSettings.dpadEnabled = item.isChecked();
|
||||||
settings.dpadEnabled = item.isChecked();
|
case R.id.enable_nav_touchpad -> mSettings.navTouchpadEnabled = item.isChecked();
|
||||||
break;
|
case R.id.enable_external_keyboard ->
|
||||||
case R.id.enable_nav_touchpad:
|
mSettings.externalKeyboardEnabled = item.isChecked();
|
||||||
settings.navTouchpadEnabled = item.isChecked();
|
case R.id.enable_external_mouse -> mSettings.externalMouseEnabled = item.isChecked();
|
||||||
break;
|
default -> {
|
||||||
case R.id.enable_external_keyboard:
|
|
||||||
settings.externalKeyboardEnabled = item.isChecked();
|
|
||||||
break;
|
|
||||||
case R.id.enable_external_mouse:
|
|
||||||
settings.externalMouseEnabled = item.isChecked();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inputManager.updateFocusTracking();
|
mInputManager.updateFocusTracking();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,27 +189,27 @@ public class MainActivity extends Hilt_MainActivity {
|
|||||||
} else {
|
} else {
|
||||||
runOnUiThread(
|
runOnUiThread(
|
||||||
() ->
|
() ->
|
||||||
displayAdapter.addDisplay(
|
mDisplayAdapter.addDisplay(
|
||||||
event.getStartStreaming().getHomeEnabled()));
|
event.getStartStreaming().getHomeEnabled()));
|
||||||
}
|
}
|
||||||
} else if (event.hasStopStreaming()) {
|
} else if (event.hasStopStreaming()) {
|
||||||
runOnUiThread(() -> displayAdapter.removeDisplay(event.getDisplayId()));
|
runOnUiThread(() -> mDisplayAdapter.removeDisplay(event.getDisplayId()));
|
||||||
} else if (event.hasDisplayRotation()) {
|
} else if (event.hasDisplayRotation()) {
|
||||||
runOnUiThread(() -> displayAdapter.rotateDisplay(event));
|
runOnUiThread(() -> mDisplayAdapter.rotateDisplay(event));
|
||||||
} else if (event.hasDisplayChangeEvent()) {
|
} else if (event.hasDisplayChangeEvent()) {
|
||||||
runOnUiThread(() -> displayAdapter.processDisplayChange(event));
|
runOnUiThread(() -> mDisplayAdapter.processDisplayChange(event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDisplayFocusChange(int displayId) {
|
private void onDisplayFocusChange(int displayId) {
|
||||||
findViewById(R.id.dpad_fragment_container)
|
findViewById(R.id.dpad_fragment_container)
|
||||||
.setVisibility(
|
.setVisibility(
|
||||||
settings.dpadEnabled && displayId != Display.INVALID_DISPLAY
|
mSettings.dpadEnabled && displayId != Display.INVALID_DISPLAY
|
||||||
? View.VISIBLE
|
? View.VISIBLE
|
||||||
: View.GONE);
|
: View.GONE);
|
||||||
findViewById(R.id.nav_touchpad_fragment_container)
|
findViewById(R.id.nav_touchpad_fragment_container)
|
||||||
.setVisibility(
|
.setVisibility(
|
||||||
settings.navTouchpadEnabled && displayId != Display.INVALID_DISPLAY
|
mSettings.navTouchpadEnabled && displayId != Display.INVALID_DISPLAY
|
||||||
? View.VISIBLE
|
? View.VISIBLE
|
||||||
: View.GONE);
|
: View.GONE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import javax.inject.Inject;
|
|||||||
@AndroidEntryPoint(Fragment.class)
|
@AndroidEntryPoint(Fragment.class)
|
||||||
public final class NavTouchpadFragment extends Hilt_NavTouchpadFragment {
|
public final class NavTouchpadFragment extends Hilt_NavTouchpadFragment {
|
||||||
|
|
||||||
@Inject InputManager inputManager;
|
@Inject InputManager mInputManager;
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
@@ -46,7 +46,7 @@ public final class NavTouchpadFragment extends Hilt_NavTouchpadFragment {
|
|||||||
TextView navTouchpad = view.findViewById(R.id.nav_touchpad);
|
TextView navTouchpad = view.findViewById(R.id.nav_touchpad);
|
||||||
navTouchpad.setOnTouchListener(
|
navTouchpad.setOnTouchListener(
|
||||||
(v, event) -> {
|
(v, event) -> {
|
||||||
inputManager.sendInputEventToFocusedDisplay(
|
mInputManager.sendInputEventToFocusedDisplay(
|
||||||
InputDeviceType.DEVICE_TYPE_NAVIGATION_TOUCHPAD, event);
|
InputDeviceType.DEVICE_TYPE_NAVIGATION_TOUCHPAD, event);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ import javax.inject.Singleton;
|
|||||||
/** Settings known to the VDM Demo Client application */
|
/** Settings known to the VDM Demo Client application */
|
||||||
@Singleton
|
@Singleton
|
||||||
final class Settings {
|
final class Settings {
|
||||||
boolean dpadEnabled = false;
|
public boolean dpadEnabled = false;
|
||||||
boolean navTouchpadEnabled = false;
|
public boolean navTouchpadEnabled = false;
|
||||||
boolean externalKeyboardEnabled = false;
|
public boolean externalKeyboardEnabled = false;
|
||||||
boolean externalMouseEnabled = false;
|
public boolean externalMouseEnabled = false;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Settings() {}
|
Settings() {}
|
||||||
|
|||||||
@@ -43,17 +43,17 @@ import javax.inject.Inject;
|
|||||||
@ActivityScoped
|
@ActivityScoped
|
||||||
final class VirtualSensorController implements AutoCloseable {
|
final class VirtualSensorController implements AutoCloseable {
|
||||||
|
|
||||||
private final RemoteIo remoteIo;
|
private final RemoteIo mRemoteIo;
|
||||||
private final Consumer<RemoteEvent> remoteEventConsumer = this::processRemoteEvent;
|
private final Consumer<RemoteEvent> mRemoteEventConsumer = this::processRemoteEvent;
|
||||||
private final SensorManager sensorManager;
|
private final SensorManager mSensorManager;
|
||||||
private final HandlerThread listenerThread;
|
private final HandlerThread mListenerThread;
|
||||||
private final Handler handler;
|
private final Handler mHandler;
|
||||||
|
|
||||||
private final SensorEventListener sensorEventListener =
|
private final SensorEventListener sensorEventListener =
|
||||||
new SensorEventListener() {
|
new SensorEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
remoteIo.sendMessage(
|
mRemoteIo.sendMessage(
|
||||||
RemoteEvent.newBuilder()
|
RemoteEvent.newBuilder()
|
||||||
.setSensorEvent(
|
.setSensorEvent(
|
||||||
RemoteSensorEvent.newBuilder()
|
RemoteSensorEvent.newBuilder()
|
||||||
@@ -68,25 +68,25 @@ final class VirtualSensorController implements AutoCloseable {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
VirtualSensorController(@ApplicationContext Context context, RemoteIo remoteIo) {
|
VirtualSensorController(@ApplicationContext Context context, RemoteIo remoteIo) {
|
||||||
this.sensorManager = context.getSystemService(SensorManager.class);
|
mSensorManager = context.getSystemService(SensorManager.class);
|
||||||
this.remoteIo = remoteIo;
|
mRemoteIo = remoteIo;
|
||||||
|
|
||||||
listenerThread = new HandlerThread("VirtualSensorListener");
|
mListenerThread = new HandlerThread("VirtualSensorListener");
|
||||||
listenerThread.start();
|
mListenerThread.start();
|
||||||
handler = new Handler(listenerThread.getLooper());
|
mHandler = new Handler(mListenerThread.getLooper());
|
||||||
|
|
||||||
remoteIo.addMessageConsumer(remoteEventConsumer);
|
remoteIo.addMessageConsumer(mRemoteEventConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
sensorManager.unregisterListener(sensorEventListener);
|
mSensorManager.unregisterListener(sensorEventListener);
|
||||||
listenerThread.quitSafely();
|
mListenerThread.quitSafely();
|
||||||
remoteIo.removeMessageConsumer(remoteEventConsumer);
|
mRemoteIo.removeMessageConsumer(mRemoteEventConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SensorCapabilities> getSensorCapabilities() {
|
public List<SensorCapabilities> getSensorCapabilities() {
|
||||||
return sensorManager.getSensorList(Sensor.TYPE_ALL).stream()
|
return mSensorManager.getSensorList(Sensor.TYPE_ALL).stream()
|
||||||
.map(
|
.map(
|
||||||
sensor ->
|
sensor ->
|
||||||
SensorCapabilities.newBuilder()
|
SensorCapabilities.newBuilder()
|
||||||
@@ -107,19 +107,19 @@ final class VirtualSensorController implements AutoCloseable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SensorConfiguration config = remoteEvent.getSensorConfiguration();
|
SensorConfiguration config = remoteEvent.getSensorConfiguration();
|
||||||
Sensor sensor = sensorManager.getDefaultSensor(config.getSensorType());
|
Sensor sensor = mSensorManager.getDefaultSensor(config.getSensorType());
|
||||||
if (sensor == null) {
|
if (sensor == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (config.getEnabled()) {
|
if (config.getEnabled()) {
|
||||||
sensorManager.registerListener(
|
mSensorManager.registerListener(
|
||||||
sensorEventListener,
|
sensorEventListener,
|
||||||
sensor,
|
sensor,
|
||||||
config.getSamplingPeriodUs(),
|
config.getSamplingPeriodUs(),
|
||||||
config.getBatchReportingLatencyUs(),
|
config.getBatchReportingLatencyUs(),
|
||||||
handler);
|
mHandler);
|
||||||
} else {
|
} else {
|
||||||
sensorManager.unregisterListener(sensorEventListener, sensor);
|
mSensorManager.unregisterListener(sensorEventListener, sensor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user