public void parseBorder(ByteBuffer buffer, int width, int height, int rowStride, int pixelStride) { checkNewBorder( findBorder(buffer, width, height, rowStride, pixelStride) ); }
private void checkNewBorder(BorderObject newBorder) { if (mPreviousBorder != null && mPreviousBorder.equals(newBorder)) { ++mConsistentFrames; mInconsistentFrames = 0; } else { ++mInconsistentFrames; if (mInconsistentFrames <= MAX_INCONSISTENT_FRAME_COUNT) { return; } mPreviousBorder = newBorder; mConsistentFrames = 0; } if (mCurrentBorder != null && mCurrentBorder.equals(newBorder)) { mInconsistentFrames = 0; return; } if (!newBorder.isKnown()) { if (mConsistentFrames == MAX_UNKNOWN_FRAME_COUNT) { mCurrentBorder = newBorder; } } else { if (mCurrentBorder == null || !mCurrentBorder.isKnown() || mConsistentFrames == BORDER_CHANGE_FRAME_COUNT) { mCurrentBorder = newBorder; } } }
/** Save scan result to Preferences */ private void saveResult() { Preferences prefs = new Preferences(getApplicationContext()); prefs.putString(R.string.pref_key_host, hostName); prefs.putInt(R.string.pref_key_port, port); }
/** @return whether the activity was initialized */ private boolean initIfConfigured() { // Do we have a valid server config? Preferences preferences = new Preferences(getApplicationContext()); String host = preferences.getString(R.string.pref_key_host, null); int port = preferences.getInt(R.string.pref_key_port, -1); if (host == null || port == -1){ return false; } initActivity(); return true; }
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private boolean prepared() { Preferences prefs = new Preferences(getBaseContext()); String host = prefs.getString(R.string.pref_key_host, null); int port = prefs.getInt(R.string.pref_key_port, -1); String priority = prefs.getString(R.string.pref_key_priority, "50"); mFrameRate = prefs.getInt(R.string.pref_key_framerate); mHorizontalLEDCount = prefs.getInt(R.string.pref_key_x_led); mVerticalLEDCount = prefs.getInt(R.string.pref_key_y_led); mSendAverageColor = prefs.getBoolean(R.string.pref_key_use_avg_color); RECONNECT = prefs.getBoolean(R.string.pref_key_reconnect); int delay = prefs.getInt(R.string.pref_key_reconnect_delay); if (host == null || Objects.equals(host, "0.0.0.0") || Objects.equals(host, "")) { mStartError = getResources().getString(R.string.error_empty_host); return false; } if (port == -1) { mStartError = getResources().getString(R.string.error_empty_port); return false; } if (mHorizontalLEDCount <= 0 || mVerticalLEDCount <= 0) { mStartError = getResources().getString(R.string.error_invalid_led_counts); return false; } mMediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE); mHyperionThread = new HyperionThread(mReceiver, host, port, Integer.parseInt(priority), RECONNECT, delay); mHyperionThread.start(); mStartError = null; return true; }
mMediaProjection = projection; mDensity = density; mFrameRate = options.getFrameRate(); mAvgColor = options.useAverageColor(); int blackThreshold = options.getBlackThreshold(); mBorderProcessor = new BorderProcessor(blackThreshold); int divisor = options.findDivisor(width, height);
mBorderProcessor.parseBorder(buffer, width, height, rowStride, pixelStride); BorderProcessor.BorderObject border = mBorderProcessor.getCurrentBorder(); if (border != null && border.isKnown()) { firstX = border.getHorizontalBorderIndex(); firstY = border.getVerticalBorderIndex();
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void onReceive(Context context, Intent intent) { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { Preferences preferences = new Preferences(context); if (preferences.getBoolean(R.string.pref_key_boot)) { final Intent i = new Intent(context, BootActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION |Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |Intent.FLAG_ACTIVITY_NO_HISTORY); context.startActivity(i); } } } }
public void onClick(View v){ if (v.getId() == R.id.startScanButton){ if (!isScanning){ new HyperionScannerTask(this).execute(); } } else if (v.getId() == R.id.manualSetupButton){ Intent intent = new Intent(this, ManualSetupActivity.class); startActivityForResult(intent, MainActivity.REQUEST_INITIAL_SETUP); } }
if (!isBlack(p1R,p1G,p1B) || !isBlack(p2R,p2G,p2B) || !isBlack(p3R,p3G,p3B)) { firstNonBlackXPixelIndex = x; break; if (!isBlack(p1R,p1G,p1B) || !isBlack(p2R,p2G,p2B) || !isBlack(p3R,p3G,p3B)) { firstNonBlackYPixelIndex = y; break; return new BorderObject(firstNonBlackXPixelIndex, firstNonBlackYPixelIndex);
@Override protected void onProgressUpdate(Float... values) { Log.d("Hyperion scanner", "scan progress: " + values[0]); if(weakListener.get() != null){ weakListener.get().onScannerProgress(values[0]); } }
@Override protected void onPostExecute(String result) { Log.d("Hyperion scanner", "scan result: " + result); if(weakListener.get() != null){ weakListener.get().onScannerCompleted(result); } }
/** * returns the divisor best suited to be used to meet the minimum image packet size * Since we only want to scale using whole numbers, we need to find what common divisors * are available for the given width & height. We will check those divisors to find the smallest * number (that we can divide our screen dimensions by) that would meet the minimum image * packet size required to match the count of the LEDs on the destination hyperion server. * @param width The original width of the device screen * @param height The original height of the device screen * @return int The divisor bes suited to scale the screen dimensions by **/ public int findDivisor(int width, int height) { List<Integer> divisors = getCommonDivisors(width, height); if (DEBUG) Log.d(TAG, "Available Divisors: " + divisors.toString()); ListIterator it = divisors.listIterator(divisors.size()); // iterate backwards since the divisors are listed largest to smallest while (it.hasPrevious()) { int i = (int) it.previous(); // check if the image packet size for this divisor is >= the minimum image packet size // like above we multiply the dimensions together and then by 3 for each byte in RGB if ((width / i) * (height / i) * 3 >= MINIMUM_IMAGE_PACKET_SIZE) return i; } return 1; }
@Override protected String doInBackground(Void... voids) { Log.d("Hyperion scanner", "starting scan"); NetworkScanner networkScanner = new NetworkScanner(); String result; while (networkScanner.hasNextAttempt()){ result = networkScanner.tryNext(); if (result != null){ return result; } publishProgress(networkScanner.getProgress()); } return null; }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) private void startScreenRecord(final Intent intent) { if (DEBUG) Log.v(TAG, "Start screen recorder"); final int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, 0); // get MediaProjection final MediaProjection projection = mMediaProjectionManager.getMediaProjection(resultCode, intent); WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE); if (projection != null && window != null) { _mediaProjection = projection; final DisplayMetrics metrics = new DisplayMetrics(); window.getDefaultDisplay().getRealMetrics(metrics); final int density = metrics.densityDpi; HyperionGrabberOptions options = new HyperionGrabberOptions(mHorizontalLEDCount, mVerticalLEDCount, mFrameRate, mSendAverageColor); if (DEBUG) Log.v(TAG, "Starting the recorder"); mHyperionEncoder = new HyperionScreenEncoder(mHyperionThread.getReceiver(), projection, metrics.widthPixels, metrics.heightPixels, density, options); mHyperionEncoder.sendStatus(); } }
/** Starts the Settings Activity if connection settings are missing * * @return true if setup was started */ private boolean startSetupIfNeeded(){ Preferences preferences = new Preferences(getApplicationContext()); if (TextUtils.isEmpty(preferences.getString(R.string.pref_key_host, null)) || preferences.getInt(R.string.pref_key_port, -1) == -1){ Intent settingsIntent = new Intent(this, SettingsActivity.class); settingsIntent.putExtra(SettingsActivity.EXTRA_SHOW_TOAST_KEY, SettingsActivity.EXTRA_SHOW_TOAST_SETUP_REQUIRED_FOR_QUICK_TILE); settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Use TaskStackBuilder to make sure the MainActivity opens when the SettingsActivity is closed TaskStackBuilder.create(this) .addNextIntentWithParentStack(settingsIntent) .startActivities(); Intent closeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); sendBroadcast(closeIntent); return true; } return false; } }