-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
738 additions
and
1 deletion.
There are no files selected for viewing
129 changes: 129 additions & 0 deletions
129
app/src/main/java/cc/ioctl/nfcdevicehost/activity/base/BaseBottomSheetDialogFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package cc.ioctl.nfcdevicehost.activity.base; | ||
|
||
import android.app.Dialog; | ||
import android.os.Bundle; | ||
import android.view.Gravity; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.view.Window; | ||
import android.view.WindowManager; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.annotation.UiThread; | ||
import androidx.core.view.WindowCompat; | ||
|
||
import com.google.android.material.bottomsheet.BottomSheetBehavior; | ||
import com.google.android.material.bottomsheet.BottomSheetDialog; | ||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment; | ||
import com.google.android.material.shape.MaterialShapeDrawable; | ||
import com.google.android.material.shape.ShapeAppearanceModel; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
|
||
import cc.ioctl.nfcdevicehost.R; | ||
import cc.ioctl.nfcdevicehost.util.ThreadManager; | ||
|
||
public abstract class BaseBottomSheetDialogFragment extends BottomSheetDialogFragment { | ||
|
||
private View mRootView = null; | ||
private Dialog mDialog = null; | ||
private BottomSheetBehavior mBehavior = null; | ||
private final BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() { | ||
@Override | ||
public void onStateChanged(@NonNull View bottomSheet, int newState) { | ||
if (newState == BottomSheetBehavior.STATE_EXPANDED) { | ||
// In the EXPANDED STATE apply a new MaterialShapeDrawable with rounded corners | ||
MaterialShapeDrawable newMaterialShapeDrawable = createMaterialShapeDrawable(bottomSheet); | ||
bottomSheet.setBackground(newMaterialShapeDrawable); | ||
} | ||
} | ||
|
||
@Override | ||
public void onSlide(@NonNull View bottomSheet, float slideOffset) { | ||
// Do nothing | ||
} | ||
}; | ||
|
||
@NonNull | ||
@UiThread | ||
protected abstract View createRootView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, | ||
@Nullable Bundle savedInstanceState); | ||
|
||
@Nullable | ||
@Override | ||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { | ||
mRootView = createRootView(inflater, container, savedInstanceState); | ||
return mRootView; | ||
} | ||
|
||
@NonNull | ||
@Override | ||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { | ||
mDialog = new BottomSheetDialog(requireContext(), getTheme()) { | ||
@Override | ||
public void onAttachedToWindow() { | ||
super.onAttachedToWindow(); | ||
Window window = getWindow(); | ||
WindowCompat.setDecorFitsSystemWindows(window, false); | ||
WindowManager.LayoutParams lp = window.getAttributes(); | ||
lp.gravity = Gravity.BOTTOM; | ||
lp.windowAnimations = R.style.BottomSheetDialogAnimation; | ||
window.setAttributes(lp); | ||
} | ||
}; | ||
return mDialog; | ||
} | ||
|
||
@Override | ||
public void onStart() { | ||
super.onStart(); | ||
if (mBehavior == null) { | ||
mBehavior = BottomSheetBehavior.from((View) mRootView.getParent()); | ||
} | ||
mBehavior.addBottomSheetCallback(mBottomSheetCallback); | ||
// update bottom sheet background with round corners | ||
View bottomSheet = mDialog.getWindow().findViewById(com.google.android.material.R.id.design_bottom_sheet); | ||
ThreadManager.post(() -> { | ||
// I don't know why, but this works, it won't work if you call it directly here | ||
MaterialShapeDrawable newMaterialShapeDrawable = createMaterialShapeDrawable(bottomSheet); | ||
bottomSheet.setBackground(newMaterialShapeDrawable); | ||
}); | ||
} | ||
|
||
@Override | ||
public void onStop() { | ||
super.onStop(); | ||
if (mBehavior != null) { | ||
mBehavior.removeBottomSheetCallback(mBottomSheetCallback); | ||
} | ||
} | ||
|
||
@Override | ||
public void onDestroyView() { | ||
mRootView = null; | ||
super.onDestroyView(); | ||
} | ||
|
||
@NotNull | ||
private MaterialShapeDrawable createMaterialShapeDrawable(@NonNull View bottomSheet) { | ||
// https://stackoverflow.com/questions/43852562/round-corner-for-bottomsheetdialogfragment | ||
// Create a ShapeAppearanceModel with the same shapeAppearanceOverlay used in the style | ||
ShapeAppearanceModel shapeAppearanceModel = | ||
ShapeAppearanceModel.builder(getContext(), 0, R.style.CustomShapeAppearanceBottomSheetDialog) | ||
.build(); | ||
//Create a new MaterialShapeDrawable (you can't use the original MaterialShapeDrawable in the BottoSheet) | ||
MaterialShapeDrawable currentMaterialShapeDrawable = (MaterialShapeDrawable) bottomSheet.getBackground(); | ||
MaterialShapeDrawable newMaterialShapeDrawable = new MaterialShapeDrawable((shapeAppearanceModel)); | ||
//Copy the attributes in the new MaterialShapeDrawable | ||
newMaterialShapeDrawable.initializeElevationOverlay(getContext()); | ||
newMaterialShapeDrawable.setFillColor(currentMaterialShapeDrawable.getFillColor()); | ||
newMaterialShapeDrawable.setTintList(currentMaterialShapeDrawable.getTintList()); | ||
newMaterialShapeDrawable.setElevation(currentMaterialShapeDrawable.getElevation()); | ||
newMaterialShapeDrawable.setStrokeWidth(currentMaterialShapeDrawable.getStrokeWidth()); | ||
newMaterialShapeDrawable.setStrokeColor(currentMaterialShapeDrawable.getStrokeColor()); | ||
return newMaterialShapeDrawable; | ||
} | ||
|
||
} |
123 changes: 123 additions & 0 deletions
123
app/src/main/java/cc/ioctl/nfcdevicehost/activity/ui/dump/HalOperationDialogFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package cc.ioctl.nfcdevicehost.activity.ui.dump; | ||
|
||
import android.os.Bundle; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.AdapterView; | ||
import android.widget.ArrayAdapter; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.annotation.UiThread; | ||
import androidx.appcompat.app.AlertDialog; | ||
|
||
import com.google.android.material.snackbar.Snackbar; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
|
||
import cc.ioctl.nfcdevicehost.R; | ||
import cc.ioctl.nfcdevicehost.activity.base.BaseBottomSheetDialogFragment; | ||
import cc.ioctl.nfcdevicehost.databinding.DialogBsdHalOperationBinding; | ||
import cc.ioctl.nfcdevicehost.ipc.daemon.INciHostDaemon; | ||
import cc.ioctl.nfcdevicehost.ipc.daemon.IpcNativeHandler; | ||
import cc.ioctl.nfcdevicehost.util.Errno; | ||
import cc.ioctl.nfcdevicehost.util.ThreadManager; | ||
|
||
public class HalOperationDialogFragment extends BaseBottomSheetDialogFragment implements AdapterView.OnItemSelectedListener { | ||
|
||
private DialogBsdHalOperationBinding mBinding; | ||
|
||
@NonNull | ||
@Override | ||
protected View createRootView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, | ||
@Nullable Bundle savedInstanceState) { | ||
mBinding = DialogBsdHalOperationBinding.inflate(inflater, container, false); | ||
mBinding.halOperationButtonSubmit.setOnClickListener(v -> submitOperation()); | ||
mBinding.halOperationButtonClose.setOnClickListener(v -> dismiss()); | ||
mBinding.halOperationSpinnerSyscallType.setAdapter(new ArrayAdapter<>(requireContext(), | ||
R.layout.item_spinner_text, R.id.item_spinner_item_textView, new String[]{"WRITE"})); | ||
mBinding.halOperationSpinnerSyscallType.setOnItemSelectedListener(this); | ||
return mBinding.getRoot(); | ||
} | ||
|
||
@UiThread | ||
private void submitOperation() { | ||
String input = mBinding.halOperationEditTextWritePayload.getText().toString(); | ||
String[] inputSplit = input.split("[,\n, |-]"); | ||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
try { | ||
for (String s : inputSplit) { | ||
if (s.isEmpty()) { | ||
continue; | ||
} | ||
int value = Integer.parseInt(s, 16); | ||
baos.write(value); | ||
} | ||
} catch (NumberFormatException e) { | ||
new AlertDialog.Builder(requireContext()) | ||
.setTitle(R.string.ui_dialog_error_title) | ||
.setMessage(requireContext().getString(R.string.ui_dialog_error_message_invalid_input_syntax_v0s, e.getMessage())) | ||
.setCancelable(true) | ||
.setPositiveButton(android.R.string.ok, null) | ||
.show(); | ||
return; | ||
} | ||
byte[] bytes = baos.toByteArray(); | ||
if (bytes.length > 0) { | ||
INciHostDaemon daemon = IpcNativeHandler.peekConnection(); | ||
if (daemon != null && daemon.isHwServiceConnected()) { | ||
ThreadManager.async(() -> { | ||
try { | ||
int result = daemon.deviceDriverWriteRaw(bytes); | ||
ThreadManager.runOnUiThread(() -> { | ||
if (result < 0) { | ||
String errMsg = Errno.getErrnoString(result); | ||
if (errMsg == null) { | ||
errMsg = "Unknown error: " + result; | ||
} | ||
String finalErrMsg = errMsg; | ||
ThreadManager.runOnUiThread(() -> new AlertDialog.Builder(requireContext()) | ||
.setTitle(R.string.ui_dialog_error_title) | ||
.setMessage(finalErrMsg) | ||
.setCancelable(true) | ||
.setPositiveButton(android.R.string.ok, null) | ||
.show()); | ||
} else { | ||
dismiss(); | ||
Snackbar.make(mBinding.getRoot(), | ||
requireContext().getString(R.string.ui_toast_operation_success_v0s, result), | ||
Snackbar.LENGTH_SHORT).show(); | ||
} | ||
}); | ||
} catch (Exception e) { | ||
ThreadManager.runOnUiThread(() -> new AlertDialog.Builder(requireContext()) | ||
.setTitle(R.string.ui_dialog_error_title) | ||
.setMessage(e.getMessage()) | ||
.setCancelable(true) | ||
.setPositiveButton(android.R.string.ok, null) | ||
.show()); | ||
} | ||
}); | ||
} else { | ||
new AlertDialog.Builder(requireContext()) | ||
.setTitle(R.string.ui_dialog_error_title) | ||
.setMessage(R.string.ui_toast_hal_service_not_attached) | ||
.setCancelable(true) | ||
.setPositiveButton(android.R.string.ok, null) | ||
.show(); | ||
dismiss(); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { | ||
|
||
} | ||
|
||
@Override | ||
public void onNothingSelected(AdapterView<?> parent) { | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.