diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index f184d956..7a0a20f0 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -80,6 +80,8 @@ android:configChanges="orientation|screenSize|keyboardHidden"/> + diff --git a/src/main/java/org/havenapp/main/PreferenceManager.java b/src/main/java/org/havenapp/main/PreferenceManager.java index f4688524..5f4ab7a0 100644 --- a/src/main/java/org/havenapp/main/PreferenceManager.java +++ b/src/main/java/org/havenapp/main/PreferenceManager.java @@ -24,6 +24,8 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; +import org.havenapp.main.sensors.motion.LuminanceMotionDetector; + public class PreferenceManager { @@ -45,7 +47,7 @@ public class PreferenceManager { private static final String ACCELEROMETER_SENSITIVITY="accelerometer_sensibility"; private static final String CAMERA_ACTIVE="camera_active"; public static final String CAMERA="camera"; - private static final String CAMERA_SENSITIVITY="camera_sensitivity"; + public static final String CAMERA_SENSITIVITY="camera_sensitivity"; public static final String CONFIG_MOVEMENT ="config_movement"; private static final String FLASH_ACTIVE="flash_active"; private static final String MICROPHONE_ACTIVE="microphone_active"; @@ -167,13 +169,13 @@ public String getCamera() { return appSharedPrefs.getString(CAMERA, FRONT); } - public void setCameraSensitivity(String sensitivity) { - prefsEditor.putString(CAMERA_SENSITIVITY, sensitivity); + public void setCameraSensitivity(int sensitivity) { + prefsEditor.putInt(CAMERA_SENSITIVITY, sensitivity); prefsEditor.commit(); } - public String getCameraSensitivity() { - return appSharedPrefs.getString(CAMERA_SENSITIVITY, HIGH); + public int getCameraSensitivity() { + return appSharedPrefs.getInt(CAMERA_SENSITIVITY, LuminanceMotionDetector.MOTION_MEDIUM); } public void activateFlash(boolean active) { diff --git a/src/main/java/org/havenapp/main/SettingsFragment.java b/src/main/java/org/havenapp/main/SettingsFragment.java index ace220e0..aad98d6a 100644 --- a/src/main/java/org/havenapp/main/SettingsFragment.java +++ b/src/main/java/org/havenapp/main/SettingsFragment.java @@ -28,6 +28,7 @@ import org.havenapp.main.service.SignalSender; import org.havenapp.main.service.WebServer; import org.havenapp.main.ui.AccelConfigureActivity; +import org.havenapp.main.ui.CameraConfigureActivity; import org.havenapp.main.ui.MicrophoneConfigureActivity; import java.io.File; @@ -108,6 +109,12 @@ public void onCreatePreferencesFix(Bundle bundle, String s) { findPreference(PreferenceManager.REGISTER_SIGNAL).setSummary(R.string.register_signal_desc); } + Preference prefCameraSensitivity = findPreference(PreferenceManager.CAMERA_SENSITIVITY); + prefCameraSensitivity.setOnPreferenceClickListener(preference -> { + startActivity(new Intent(mActivity, CameraConfigureActivity.class)); + return true; + }); + Preference prefConfigMovement = findPreference(PreferenceManager.CONFIG_MOVEMENT); prefConfigMovement.setOnPreferenceClickListener(preference -> { startActivity(new Intent(mActivity, AccelConfigureActivity.class)); diff --git a/src/main/java/org/havenapp/main/sensors/media/MotionAsyncTask.java b/src/main/java/org/havenapp/main/sensors/media/MotionAsyncTask.java index 54692925..c8773244 100644 --- a/src/main/java/org/havenapp/main/sensors/media/MotionAsyncTask.java +++ b/src/main/java/org/havenapp/main/sensors/media/MotionAsyncTask.java @@ -49,6 +49,8 @@ public class MotionAsyncTask extends Thread { private Bitmap newBitmap; private Bitmap rawBitmap; private boolean hasChanged; + + private IMotionDetector detector; public interface MotionListener { public void onProcess(Bitmap oldBitmap, @@ -77,6 +79,12 @@ public MotionAsyncTask( } + public void setMotionSensitivity (int motionSensitivity) + { + this.motionSensitivity = motionSensitivity; + detector.setThreshold(motionSensitivity); + } + @Override public void run() { int[] newPicLuma = ImageCodec.N21toLuma(rawNewPic, width, height); @@ -85,7 +93,7 @@ public void run() { lastBitmap = newBitmap; } else { int[] oldPicLuma = ImageCodec.N21toLuma(rawOldPic, width, height); - IMotionDetector detector = new LuminanceMotionDetector(); + detector = new LuminanceMotionDetector(); detector.setThreshold(motionSensitivity); List changedPixels = detector.detectMotion(oldPicLuma, newPicLuma, width, height); diff --git a/src/main/java/org/havenapp/main/sensors/motion/LuminanceMotionDetector.java b/src/main/java/org/havenapp/main/sensors/motion/LuminanceMotionDetector.java index de53473e..5b2cd60a 100644 --- a/src/main/java/org/havenapp/main/sensors/motion/LuminanceMotionDetector.java +++ b/src/main/java/org/havenapp/main/sensors/motion/LuminanceMotionDetector.java @@ -33,21 +33,8 @@ public class LuminanceMotionDetector implements IMotionDetector { * @param thresh sensitivity identifier */ public void setThreshold(int thresh) { - switch(thresh) { - case MOTION_LOW: - VALUE_THRESHOLD = 60; - NUMBER_THRESHOLD = 20000; - break; - case MOTION_MEDIUM: - VALUE_THRESHOLD = 50; - NUMBER_THRESHOLD = 10000; - break; - case MOTION_HIGH: - VALUE_THRESHOLD = 20; - NUMBER_THRESHOLD = 2000; - break; - } - + NUMBER_THRESHOLD = thresh; + VALUE_THRESHOLD = thresh/1000; } /* diff --git a/src/main/java/org/havenapp/main/sensors/motion/Preview.java b/src/main/java/org/havenapp/main/sensors/motion/Preview.java index d03bc568..524ccb69 100644 --- a/src/main/java/org/havenapp/main/sensors/motion/Preview.java +++ b/src/main/java/org/havenapp/main/sensors/motion/Preview.java @@ -106,6 +106,7 @@ public void onServiceDisconnected(ComponentName arg0) { private SurfaceHolder mHolder; private Camera camera; private Context context; + private MotionAsyncTask task; public Preview (Context context) { super(context); @@ -116,23 +117,12 @@ public Preview (Context context) { mHolder.addCallback(this); prefs = new PreferenceManager(context); - /* - * Set sensitivity value - */ - switch (prefs.getCameraSensitivity()) { - case "Medium": - motionSensitivity = LuminanceMotionDetector.MOTION_MEDIUM; - Log.i("CameraFragment", "Sensitivity set to Medium"); - break; - case "Low": - motionSensitivity = LuminanceMotionDetector.MOTION_LOW; - Log.i("CameraFragment", "Sensitivity set to Low"); - break; - default: - motionSensitivity = LuminanceMotionDetector.MOTION_HIGH; - Log.i("CameraFragment", "Sensitivity set to High"); - break; - } + motionSensitivity = prefs.getCameraSensitivity(); + } + + public void setMotionSensitivity (int motionSensitivity) + { + this.motionSensitivity = motionSensitivity; } public void addListener(MotionAsyncTask.MotionListener listener) { @@ -257,7 +247,7 @@ public void onPreviewFrame(byte[] data, Camera cam) { Log.i("Preview", "Processing new image"); Preview.this.lastTimestamp = now; - MotionAsyncTask task = new MotionAsyncTask( + task = new MotionAsyncTask( lastPic, data, size.width, diff --git a/src/main/java/org/havenapp/main/service/MonitorService.java b/src/main/java/org/havenapp/main/service/MonitorService.java index f83def5a..c6aab0ed 100644 --- a/src/main/java/org/havenapp/main/service/MonitorService.java +++ b/src/main/java/org/havenapp/main/service/MonitorService.java @@ -283,9 +283,6 @@ public synchronized void alert(int alertType, String path) { StringBuilder alertMessage = new StringBuilder(); alertMessage.append(getString(R.string.intrusion_detected,eventTrigger.getStringType(this))); - // removing toast, but we should have some visual feedback for testing on the monitor screen -// Toast.makeText(this,alertMessage.toString(),Toast.LENGTH_SHORT).show(); - if (mPrefs.getSignalUsername() != null) { //since this is a secure channel, we can add the Onion address diff --git a/src/main/java/org/havenapp/main/ui/CameraConfigureActivity.java b/src/main/java/org/havenapp/main/ui/CameraConfigureActivity.java new file mode 100644 index 00000000..c513bcef --- /dev/null +++ b/src/main/java/org/havenapp/main/ui/CameraConfigureActivity.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2017 Nathanial Freitas + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.havenapp.main.ui; + +import android.Manifest; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Camera; +import android.os.Bundle; +import android.os.CountDownTimer; +import android.os.Environment; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.wdullaer.materialdatetimepicker.time.TimePickerDialog; + +import org.havenapp.main.PreferenceManager; +import org.havenapp.main.R; +import org.havenapp.main.SettingsActivity; +import org.havenapp.main.service.MonitorService; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + + +public class CameraConfigureActivity extends AppCompatActivity { + + private PreferenceManager preferences = null; + + private boolean mIsMonitoring = false; + private boolean mIsInitializedLayout = false; + + private CameraFragment mFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + boolean permsNeeded = askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 1); + + if (!permsNeeded) + initLayout(); + } + + private void initLayout() { + preferences = new PreferenceManager(getApplicationContext()); + setContentView(R.layout.activity_camera_configure); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + setTitle(""); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mFragment = (CameraFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_camera); + + findViewById(R.id.btnCameraSwitch).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + switchCamera(); + } + }); + + SeekBar sBar = ((SeekBar)findViewById(R.id.seekCameraSensitivity)); + sBar.setProgress(preferences.getCameraSensitivity()); + sBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int i, boolean b) { + mFragment.setMotionSensitivity(i); + preferences.setCameraSensitivity(i); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + + } + }); + + mIsInitializedLayout = true; + } + + private void switchCamera() { + + String camera = preferences.getCamera(); + if (camera.equals(PreferenceManager.FRONT)) + preferences.setCamera(PreferenceManager.BACK); + else if (camera.equals(PreferenceManager.BACK)) + preferences.setCamera(PreferenceManager.FRONT); + + ((CameraFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_camera)).resetCamera(); + + } + + + + private void initMonitor() { + + mIsMonitoring = true; + //ensure folder exists and will not be scanned by the gallery app + + try { + File fileImageDir = new File(Environment.getExternalStorageDirectory(), preferences.getImagePath()); + fileImageDir.mkdirs(); + new FileOutputStream(new File(fileImageDir, ".nomedia")).write(0); + } catch (IOException e) { + Log.e("Monitor", "unable to init media storage directory", e); + } + + //Do something after 100ms + startService(new Intent(CameraConfigureActivity.this, MonitorService.class)); + + } + + /** + * Closes the monitor activity and unset session properties + */ + private void close() { + + stopService(new Intent(this, MonitorService.class)); + if (preferences != null) { + preferences.unsetAccessToken(); + preferences.unsetDelegatedAccessToken(); + preferences.unsetPhoneId(); + } + finish(); + + } + + @Override + public boolean onOptionsItemSelected (MenuItem item) { + switch (item.getItemId()){ + case android.R.id.home: + close(); + break; + } + return true; + } + + /** + * When user closes the activity + */ + @Override + public void onBackPressed() { + close(); + } + + @Override + public void onResume() { + super.onResume(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + switch (requestCode) { + case 1: + askForPermission(Manifest.permission.CAMERA, 2); + break; + case 2: + initLayout(); + break; + } + + } + + + private boolean askForPermission(String permission, Integer requestCode) { + if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { + + // Should we show an explanation? + if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { + + //This is called if user has denied the permission before + //In this case I am just asking the permission again + ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode); + + } else { + + ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode); + } + return true; + } else { + return false; + } + } + +} diff --git a/src/main/java/org/havenapp/main/ui/CameraFragment.java b/src/main/java/org/havenapp/main/ui/CameraFragment.java index 753a5c4e..26e79e7b 100644 --- a/src/main/java/org/havenapp/main/ui/CameraFragment.java +++ b/src/main/java/org/havenapp/main/ui/CameraFragment.java @@ -28,8 +28,6 @@ public final class CameraFragment extends Fragment { private Preview preview; - -// private ImageView oldImage; private ImageView newImage; @Override @@ -40,6 +38,11 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, } + public void setMotionSensitivity (int threshold) + { + preview.setMotionSensitivity(threshold); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -70,7 +73,7 @@ private void initCamera () PreferenceManager prefs = new PreferenceManager(getActivity()); - if (!prefs.getCameraSensitivity().equals(PreferenceManager.OFF)) { + if (prefs.getCameraActivation()) { //Uncomment to see the camera preview = new Preview(getActivity()); diff --git a/src/main/res/layout/activity_camera_configure.xml b/src/main/res/layout/activity_camera_configure.xml new file mode 100644 index 00000000..0108cdaa --- /dev/null +++ b/src/main/res/layout/activity_camera_configure.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index ea87c969..123d7dcd 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -122,10 +122,11 @@ Enter a phone number to send a test alert notification message to Test notifications... Service Address - Password + Password (Required) Signal Number (Local) Notification Number (Remote) Sensors Notifications + Camera Sensitivity diff --git a/src/main/res/xml/settings.xml b/src/main/res/xml/settings.xml index f042d9d8..f671a885 100644 --- a/src/main/res/xml/settings.xml +++ b/src/main/res/xml/settings.xml @@ -14,6 +14,10 @@ android:summary="%s" android:title="@string/camera_prompt" /> + +