diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..03b5efc
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,51 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 25
+ buildToolsVersion "25.0.2"
+ defaultConfig {
+ applicationId "ca.mudar.rotationquicksetting"
+ minSdkVersion 24
+ targetSdkVersion 25
+ versionCode 10
+ versionName "0.5-alpha"
+
+ resConfigs "en", "fr"
+ }
+ buildTypes {
+ release {
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+
+ ext.enableCrashlytics = true
+ }
+
+ debug {
+ applicationIdSuffix ".d"
+ versionNameSuffix "-build-" + getDate()
+ minifyEnabled false
+
+ ext.enableCrashlytics = false
+ }
+
+ debugCrashlytics.initWith(buildTypes.debug)
+ debugCrashlytics {
+ applicationIdSuffix ""
+
+ buildConfigField "boolean", "USE_CRASHLYTICS", "true"
+ ext.enableCrashlytics = true
+ }
+ }
+}
+
+def static getDate() {
+ new Date().format('ddMMMyyyy.HHmm')
+}
+
+ext.supportLibVersion = '25.3.1'
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile "com.android.support:appcompat-v7:$supportLibVersion"
+ compile "com.android.support:design:$supportLibVersion"
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..147347b
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/mudar/android-sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..2273e8d
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/ca/mudar/rotationquicksetting/Const.java b/app/src/main/java/ca/mudar/rotationquicksetting/Const.java
new file mode 100644
index 0000000..d37ae39
--- /dev/null
+++ b/app/src/main/java/ca/mudar/rotationquicksetting/Const.java
@@ -0,0 +1,21 @@
+package ca.mudar.rotationquicksetting;
+
+/**
+ * Created by mudar on 10/05/17.
+ */
+
+public class Const {
+
+ /**
+ * SharedPreferences
+ */
+ public static final String APP_PREFS_NAME = "orientation_tile_prefs";
+
+ public interface PrefsNames {
+ String REVERSE_PORT = "prefs_reverse_port";
+ String REVERSE_LAND = "prefs_reverse_land";
+ String AUTO_ROTATE = "prefs_auto_rotate";
+ String PERMISSION_GRANTED = "prefs_permission_granted";
+ String ABOUT = "prefs_about";
+ }
+}
diff --git a/app/src/main/java/ca/mudar/rotationquicksetting/data/UserPrefs.java b/app/src/main/java/ca/mudar/rotationquicksetting/data/UserPrefs.java
new file mode 100644
index 0000000..bf9c236
--- /dev/null
+++ b/app/src/main/java/ca/mudar/rotationquicksetting/data/UserPrefs.java
@@ -0,0 +1,59 @@
+package ca.mudar.rotationquicksetting.data;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import ca.mudar.rotationquicksetting.Const;
+import ca.mudar.rotationquicksetting.Const.PrefsNames;
+import ca.mudar.rotationquicksetting.R;
+
+/**
+ * Created by mudar on 10/05/17.
+ */
+
+public class UserPrefs {
+
+ private static UserPrefs instance;
+ private SharedPreferences mPrefs;
+ private SharedPreferences.Editor mPrefsEditor;
+
+ private UserPrefs(Context context) {
+ mPrefs = context.getSharedPreferences(Const.APP_PREFS_NAME, Context.MODE_PRIVATE);
+ }
+
+ public static UserPrefs getInstance(Context context) {
+ if (instance == null) {
+ instance = new UserPrefs(context);
+ }
+ return instance;
+ }
+
+ private SharedPreferences.Editor edit() {
+ if (mPrefsEditor == null) {
+ mPrefsEditor = mPrefs.edit();
+ }
+
+ return mPrefsEditor;
+ }
+
+ public static void setDefaults(Context context) {
+ PreferenceManager.setDefaultValues(context,
+ Const.APP_PREFS_NAME,
+ Context.MODE_PRIVATE,
+ R.xml.prefs_defaults,
+ false);
+ }
+
+ public boolean isReversePortrait() {
+ return mPrefs.getBoolean(PrefsNames.REVERSE_PORT, false);
+ }
+
+ public boolean isReverseLandscape() {
+ return mPrefs.getBoolean(PrefsNames.REVERSE_LAND, false);
+ }
+
+ public boolean hasAutoRotate() {
+ return mPrefs.getBoolean(PrefsNames.AUTO_ROTATE, false);
+ }
+}
diff --git a/app/src/main/java/ca/mudar/rotationquicksetting/service/QuickSettingsService.java b/app/src/main/java/ca/mudar/rotationquicksetting/service/QuickSettingsService.java
new file mode 100644
index 0000000..a43cf13
--- /dev/null
+++ b/app/src/main/java/ca/mudar/rotationquicksetting/service/QuickSettingsService.java
@@ -0,0 +1,182 @@
+package ca.mudar.rotationquicksetting.service;
+
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.content.ContextCompat;
+import android.util.Log;
+import android.view.WindowManager;
+
+import ca.mudar.rotationquicksetting.R;
+import ca.mudar.rotationquicksetting.data.UserPrefs;
+import ca.mudar.rotationquicksetting.utils.OrientationUtils;
+
+/**
+ * Created by mudar on 07/05/17.
+ */
+
+public class QuickSettingsService extends TileService {
+ private final static String TAG = "QuickSettingsService";
+
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.i(TAG, "onCreate: ");
+ }
+
+ @Override
+ public void onStartListening() {
+ super.onStartListening();
+ Log.i(TAG, "onStartListening: ");
+
+ try {
+ updateQuickSettingsTile(getCurrentOrientation(UserPrefs.getInstance(getApplicationContext()).hasAutoRotate()),
+ Settings.System.canWrite(getApplicationContext()));
+ } catch (Settings.SettingNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onStopListening() {
+ super.onStopListening();
+ Log.i(TAG, "onStopListening: ");
+ }
+
+ @Override
+ public void onClick() {
+ Log.i(TAG, "onClick: ");
+
+ if (Settings.System.canWrite(getApplicationContext())) {
+ try {
+ final int newOrientation = toggleOrientation();
+ updateQuickSettingsTile(newOrientation, true);
+ } catch (Settings.SettingNotFoundException e) {
+ e.printStackTrace();
+ }
+ } else {
+ showPermissionNotification();
+ }
+ }
+
+ private void updateQuickSettingsTile(int orientation, boolean canWriteSettings) throws Settings.SettingNotFoundException {
+ Log.d(TAG, "updateQuickSettingsTile() called with: orientation = [" + orientation + "]");
+ final Tile tile = getQsTile();
+ tile.setState(canWriteSettings ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
+
+ if (OrientationUtils.isLandscape(orientation)) {
+ tile.setIcon(Icon.createWithResource(getApplicationContext(), R.drawable.ic_screen_landscape));
+ tile.setLabel(getString(R.string.tile_label_land));
+ } else if (OrientationUtils.isPortrait(orientation)) {
+ tile.setIcon(Icon.createWithResource(getApplicationContext(), R.drawable.ic_screen_portrait));
+ tile.setLabel(getString(R.string.tile_label_port));
+ } else {
+ tile.setIcon(Icon.createWithResource(getApplicationContext(), R.drawable.ic_screen_rotation));
+ tile.setLabel(getString(R.string.tile_label_auto_rotate));
+ }
+
+ tile.updateTile();
+ }
+
+ /**
+ * Toggles current location, and returns the new value.
+ * Requires a prior check of Settings.System.canWrite()
+ *
+ * @return new rotation
+ */
+ private int toggleOrientation() throws Settings.SettingNotFoundException {
+ Log.i(TAG, "toggleOrientation: ");
+ final ContentResolver contentResolver = getContentResolver();
+ final UserPrefs userPrefs = UserPrefs.getInstance(getApplicationContext());
+
+ if (userPrefs.hasAutoRotate() &&
+ Settings.System.getInt(contentResolver, Settings.System.ACCELEROMETER_ROTATION) == 0) {
+ // Enable auto-rotation
+ Log.e(TAG, "Enable auto-rotation");
+ Settings.System.putInt(contentResolver, Settings.System.ACCELEROMETER_ROTATION, 1);
+ return OrientationUtils.ROTATION_AUTO;
+ }
+
+ final int oldOrientation = getCurrentOrientation(false);
+ final int newOrientation = OrientationUtils.getOppositeOrientation(oldOrientation, userPrefs);
+
+ Settings.System.putInt(contentResolver, Settings.System.ACCELEROMETER_ROTATION, 0);
+ Settings.System.putInt(contentResolver, Settings.System.USER_ROTATION, newOrientation);
+
+ return newOrientation;
+ }
+
+ private int getCurrentOrientation(boolean includeAutoRotate) throws Settings.SettingNotFoundException {
+ Log.i(TAG, "getCurrentOrientation: ");
+ final ContentResolver contentResolver = getContentResolver();
+ final boolean hasAccelerometer = (Settings.System
+ .getInt(contentResolver, Settings.System.ACCELEROMETER_ROTATION) == 1);
+
+ if (hasAccelerometer && includeAutoRotate) {
+ return OrientationUtils.ROTATION_AUTO;
+ }
+
+ return hasAccelerometer ? getAccelerometerOrientation() : getUserOrientation();
+ }
+
+ private int getUserOrientation() throws Settings.SettingNotFoundException {
+ Log.i(TAG, "getUserOrientation: ");
+ return Settings.System.getInt(getContentResolver(), Settings.System.USER_ROTATION);
+ }
+
+ private int getAccelerometerOrientation() throws Settings.SettingNotFoundException {
+ Log.i(TAG, "getAccelerometerOrientation: ");
+ final WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
+ return windowManager.getDefaultDisplay().getRotation();
+ }
+
+ /**
+ * Create and show a simple notification containing the received GCM message.
+ */
+ private void showPermissionNotification() {
+ final Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
+ Uri.parse("package:" + getPackageName()));
+
+ final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
+ 0,
+ intent,
+ PendingIntent.FLAG_ONE_SHOT);
+
+ final Resources res = getApplicationContext().getResources();
+ final String contentTitle = res.getString(R.string.notify_permissions_title);
+ final String contentText = res.getString(R.string.notify_permissions_text);
+
+ final Drawable drawable = ContextCompat.getDrawable(getApplicationContext(), R.mipmap.ic_launcher);
+ final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
+
+ final NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext())
+ .setSmallIcon(R.drawable.ic_screen_lock_rotation)
+ .setLargeIcon(bitmap)
+ .setColor(getColor(R.color.app_notification))
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setOngoing(true)
+ .setShowWhen(false)
+ .setAutoCancel(true)
+ .setPriority(NotificationCompat.PRIORITY_MAX)
+ .setCategory(NotificationCompat.CATEGORY_MESSAGE)
+ .setContentIntent(pendingIntent);
+
+ ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE))
+ .notify(0, builder.build());
+ }
+
+}
diff --git a/app/src/main/java/ca/mudar/rotationquicksetting/ui/AboutBottomSheetFragment.java b/app/src/main/java/ca/mudar/rotationquicksetting/ui/AboutBottomSheetFragment.java
new file mode 100644
index 0000000..694c351
--- /dev/null
+++ b/app/src/main/java/ca/mudar/rotationquicksetting/ui/AboutBottomSheetFragment.java
@@ -0,0 +1,58 @@
+package ca.mudar.rotationquicksetting.ui;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.design.widget.BottomSheetDialogFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import ca.mudar.rotationquicksetting.R;
+
+/**
+ * Created by mudar on 16/05/17.
+ */
+
+public class AboutBottomSheetFragment extends BottomSheetDialogFragment implements View.OnClickListener {
+ public static AboutBottomSheetFragment newInstance() {
+ return new AboutBottomSheetFragment();
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.fragment_about, container, false);
+
+ setupListeners(view);
+
+ return view;
+ }
+
+ @Override
+ public void onClick(View v) {
+ final int id = v.getId();
+
+ if (id == R.id.about_credits) {
+ showWebsite(R.string.url_mudar_ca);
+ } else if (id == R.id.about_source_code) {
+ showWebsite(R.string.url_github);
+ } else if (id == R.id.about_rate_app) {
+ showWebsite(R.string.url_playstore);
+ }
+ }
+
+ private void setupListeners(View view) {
+ view.findViewById(R.id.about_credits).setOnClickListener(this);
+ view.findViewById(R.id.about_source_code).setOnClickListener(this);
+ view.findViewById(R.id.about_rate_app).setOnClickListener(this);
+ }
+
+ private void showWebsite(@StringRes int website) {
+ final Intent viewIntent = new Intent(Intent.ACTION_VIEW);
+ viewIntent.setData(Uri.parse(getResources().getString(website)));
+ startActivity(viewIntent);
+ }
+}
diff --git a/app/src/main/java/ca/mudar/rotationquicksetting/ui/MainActivity.java b/app/src/main/java/ca/mudar/rotationquicksetting/ui/MainActivity.java
new file mode 100644
index 0000000..82b6893
--- /dev/null
+++ b/app/src/main/java/ca/mudar/rotationquicksetting/ui/MainActivity.java
@@ -0,0 +1,42 @@
+package ca.mudar.rotationquicksetting.ui;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+import ca.mudar.rotationquicksetting.data.UserPrefs;
+
+/**
+ * Created by mudar on 10/05/17.
+ */
+
+public class MainActivity extends AppCompatActivity implements
+ SettingsFragment.SettingsAboutCallback {
+ private final static String FRAGMENT_TAG_SETTINGS = "f_settings";
+ private final static String FRAGMENT_TAG_ABOUT = "f_about";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set default preferences
+ UserPrefs.setDefaults(getApplicationContext());
+
+ if (savedInstanceState == null) {
+ final Fragment fragment = SettingsFragment.newInstance();
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, fragment, FRAGMENT_TAG_SETTINGS)
+ .commit();
+ }
+ }
+
+ /**
+ * Implements SettingsFragment.SettingsAboutCallback
+ * Shows about the About BottomSheetDialogFragment
+ */
+ @Override
+ public void onShowAbout() {
+ final AboutBottomSheetFragment bottomSheet = AboutBottomSheetFragment.newInstance();
+ bottomSheet.show(getSupportFragmentManager(), FRAGMENT_TAG_ABOUT);
+ }
+}
diff --git a/app/src/main/java/ca/mudar/rotationquicksetting/ui/SettingsFragment.java b/app/src/main/java/ca/mudar/rotationquicksetting/ui/SettingsFragment.java
new file mode 100644
index 0000000..caef5f4
--- /dev/null
+++ b/app/src/main/java/ca/mudar/rotationquicksetting/ui/SettingsFragment.java
@@ -0,0 +1,194 @@
+package ca.mudar.rotationquicksetting.ui;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.design.widget.Snackbar;
+import android.support.v4.content.ContextCompat;
+import android.util.Log;
+import android.view.View;
+
+import ca.mudar.rotationquicksetting.BuildConfig;
+import ca.mudar.rotationquicksetting.Const;
+import ca.mudar.rotationquicksetting.Const.PrefsNames;
+import ca.mudar.rotationquicksetting.R;
+
+import static android.content.ContentValues.TAG;
+import static ca.mudar.rotationquicksetting.utils.OrientationUtils.ROTATION_LAND;
+import static ca.mudar.rotationquicksetting.utils.OrientationUtils.ROTATION_LAND_REVERSE;
+import static ca.mudar.rotationquicksetting.utils.OrientationUtils.ROTATION_PORT;
+import static ca.mudar.rotationquicksetting.utils.OrientationUtils.ROTATION_PORT_REVERSE;
+
+/**
+ * Created by mudar on 10/05/17.
+ */
+
+public class SettingsFragment extends PreferenceFragment implements
+ SharedPreferences.OnSharedPreferenceChangeListener,
+ Preference.OnPreferenceClickListener {
+
+ public static SettingsFragment newInstance() {
+ return new SettingsFragment();
+ }
+
+ private SharedPreferences mSharedPrefs;
+ private Preference mPermissionGranted;
+ private SettingsAboutCallback mListener;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
+ if (context instanceof SettingsAboutCallback) {
+ mListener = (SettingsAboutCallback) context;
+ }
+ }
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+
+ final PreferenceManager pm = this.getPreferenceManager();
+ pm.setSharedPreferencesName(Const.APP_PREFS_NAME);
+ pm.setSharedPreferencesMode(Context.MODE_PRIVATE);
+
+ addPreferencesFromResource(R.xml.prefs_settings);
+ mPermissionGranted = findPreference(PrefsNames.PERMISSION_GRANTED);
+
+ mSharedPrefs = pm.getSharedPreferences();
+
+ mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
+
+ mPermissionGranted.setOnPreferenceClickListener(this);
+ findPreference(PrefsNames.ABOUT).setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ setupSummaries();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ /**
+ * Remove the listener
+ */
+ if (mSharedPrefs != null) {
+ mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ }
+ }
+
+ /**
+ * Implements SharedPreferences.OnSharedPreferenceChangeListener
+ *
+ * @param sharedPreferences
+ * @param key
+ */
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (PrefsNames.REVERSE_PORT.equals(key)) {
+ showTryRotationSnackbar(sharedPreferences.getBoolean(key, false) ?
+ ROTATION_PORT_REVERSE : ROTATION_PORT);
+ } else if (PrefsNames.REVERSE_LAND.equals(key)) {
+ showTryRotationSnackbar(sharedPreferences.getBoolean(key, false) ?
+ ROTATION_LAND_REVERSE : ROTATION_LAND);
+ }
+ }
+
+ /**
+ * Implements Preference.OnPreferenceClickListener
+ *
+ * @param preference
+ * @return
+ */
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ final String key = preference.getKey();
+ if (PrefsNames.PERMISSION_GRANTED.equals(key)) {
+ final Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
+ Uri.parse("package:" + getContext().getPackageName()));
+ startActivity(intent);
+ return true;
+ } else if (PrefsNames.ABOUT.equals(key) && mListener != null) {
+ Log.i(TAG, "onPreferenceClick: ABOUT");
+ mListener.onShowAbout();
+ return true;
+ }
+
+ return false;
+ }
+
+ private void setupSummaries() {
+ mPermissionGranted.setSummary(getPermissionGrantedSummary());
+
+ findPreference(PrefsNames.ABOUT).setSummary(getString(
+ R.string.prefs_version_title, BuildConfig.VERSION_NAME));
+ }
+
+ @StringRes
+ private int getPermissionGrantedSummary() {
+ return Settings.System.canWrite(getContext()) ?
+ R.string.prefs_permission_granted_on : R.string.prefs_permission_granted_off;
+ }
+
+ private void setOrientation(int orientation) {
+ if (!Settings.System.canWrite(getContext())) {
+ return;
+ }
+
+ final ContentResolver contentResolver = getContext().getContentResolver();
+ Settings.System.putInt(contentResolver, Settings.System.ACCELEROMETER_ROTATION, 0);
+ Settings.System.putInt(contentResolver, Settings.System.USER_ROTATION, orientation);
+ }
+
+ private void showTryRotationSnackbar(final int orientation) {
+ if (getView() == null || !Settings.System.canWrite(getContext())) {
+ return;
+ }
+
+ @StringRes int message;
+ switch (orientation) {
+ case ROTATION_PORT:
+ message = R.string.snackbar_try_rotation_port;
+ break;
+ case ROTATION_PORT_REVERSE:
+ message = R.string.snackbar_try_rotation_port_reverse;
+ break;
+ case ROTATION_LAND:
+ message = R.string.snackbar_try_rotation_land;
+ break;
+ case ROTATION_LAND_REVERSE:
+ message = R.string.snackbar_try_rotation_land_reverse;
+ break;
+ default:
+ return;
+ }
+ Snackbar.make(getView(), message, Snackbar.LENGTH_LONG)
+ .setAction(R.string.btn_try_it, new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ setOrientation(orientation);
+ }
+ })
+ .setActionTextColor(ContextCompat.getColor(getContext(), R.color.snackbar_action_text))
+ .show();
+ }
+
+ public interface SettingsAboutCallback {
+ public void onShowAbout();
+ }
+}
diff --git a/app/src/main/java/ca/mudar/rotationquicksetting/utils/OrientationUtils.java b/app/src/main/java/ca/mudar/rotationquicksetting/utils/OrientationUtils.java
new file mode 100644
index 0000000..310ee4b
--- /dev/null
+++ b/app/src/main/java/ca/mudar/rotationquicksetting/utils/OrientationUtils.java
@@ -0,0 +1,36 @@
+package ca.mudar.rotationquicksetting.utils;
+
+import android.support.annotation.NonNull;
+import android.view.Surface;
+
+import ca.mudar.rotationquicksetting.data.UserPrefs;
+
+/**
+ * Created by mudar on 10/05/17.
+ */
+
+public class OrientationUtils {
+ public final static int ROTATION_PORT = Surface.ROTATION_0;
+ public final static int ROTATION_PORT_REVERSE = Surface.ROTATION_180;
+ public final static int ROTATION_LAND = Surface.ROTATION_90;
+ public final static int ROTATION_LAND_REVERSE = Surface.ROTATION_270;
+ public final static int ROTATION_AUTO = -1;
+
+ public static int getOppositeOrientation(int orientation, @NonNull UserPrefs prefs) {
+ if (isPortrait(orientation)) {
+ return prefs.isReverseLandscape() ? ROTATION_LAND_REVERSE : ROTATION_LAND;
+ } else if (isLandscape(orientation)) {
+ return prefs.isReversePortrait() ? ROTATION_PORT_REVERSE : ROTATION_PORT;
+ } else {
+ return ROTATION_AUTO;
+ }
+ }
+
+ public static boolean isPortrait(int orientation) {
+ return (orientation == ROTATION_PORT) || (orientation == ROTATION_PORT_REVERSE);
+ }
+
+ public static boolean isLandscape(int orientation) {
+ return (orientation == ROTATION_LAND) || (orientation == ROTATION_LAND_REVERSE);
+ }
+}
diff --git a/app/src/main/res/drawable/ic_github_mark.xml b/app/src/main/res/drawable/ic_github_mark.xml
new file mode 100644
index 0000000..4b59c9f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_github_mark.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_person.xml b/app/src/main/res/drawable/ic_person.xml
new file mode 100644
index 0000000..0bbcaed
--- /dev/null
+++ b/app/src/main/res/drawable/ic_person.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_screen_landscape.xml b/app/src/main/res/drawable/ic_screen_landscape.xml
new file mode 100644
index 0000000..9314079
--- /dev/null
+++ b/app/src/main/res/drawable/ic_screen_landscape.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_screen_lock_rotation.xml b/app/src/main/res/drawable/ic_screen_lock_rotation.xml
new file mode 100644
index 0000000..f427d32
--- /dev/null
+++ b/app/src/main/res/drawable/ic_screen_lock_rotation.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_screen_portrait.xml b/app/src/main/res/drawable/ic_screen_portrait.xml
new file mode 100644
index 0000000..50c70b3
--- /dev/null
+++ b/app/src/main/res/drawable/ic_screen_portrait.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_screen_rotation.xml b/app/src/main/res/drawable/ic_screen_rotation.xml
new file mode 100644
index 0000000..3429c6b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_screen_rotation.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_security.xml b/app/src/main/res/drawable/ic_security.xml
new file mode 100644
index 0000000..78b47e4
--- /dev/null
+++ b/app/src/main/res/drawable/ic_security.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_swap_horiz_circle.xml b/app/src/main/res/drawable/ic_swap_horiz_circle.xml
new file mode 100644
index 0000000..b884170
--- /dev/null
+++ b/app/src/main/res/drawable/ic_swap_horiz_circle.xml
@@ -0,0 +1,6 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_swap_vert_circle.xml b/app/src/main/res/drawable/ic_swap_vert_circle.xml
new file mode 100644
index 0000000..2475ded
--- /dev/null
+++ b/app/src/main/res/drawable/ic_swap_vert_circle.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_thumb_up.xml b/app/src/main/res/drawable/ic_thumb_up.xml
new file mode 100644
index 0000000..35feaab
--- /dev/null
+++ b/app/src/main/res/drawable/ic_thumb_up.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml
new file mode 100644
index 0000000..11eaeeb
--- /dev/null
+++ b/app/src/main/res/layout/fragment_about.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..2dd159a
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..9d4f866
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..95e7111
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..e72d0ee
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6b249d1
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..2032dce
--- /dev/null
+++ b/app/src/main/res/values-w820dp/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 64dp
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..8cee067
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ #CE93D8
+ #9C27B0
+ #8E24AA
+ #7B1FA2
+ #6A1B9A
+ #4A148C
+ #2196F3
+ #FFEB3B
+ #FFC107
+ #AA00FF
+ #212121
+
+
+
+
+
+ @color/purple_500
+ @color/purple_700
+ @color/purple_a700
+ @color/grey_900
+
+
+ @color/color_primary_dark
+ @color/purple_900
+ @color/icon_prefs
+ @color/purple_200
+ @color/color_primary_dark
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..fb4f6ea
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,10 @@
+
+
+ 16dp
+ 16dp
+
+ 16dp
+ 48dp
+ 72dp
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..5c1836e
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,45 @@
+
+ Rotation Quick Setting
+ Rotation QS
+ Portrait
+ Landscape
+ Auto-rotate
+ System permission request
+ Tap to allow modifying screen rotation setting.
+
+
+ Permission
+ Rotation
+ About
+ Modify settings permission
+ Granted
+ Not granted, app is disabled
+ Reverse portrait
+ Reverse landscape
+ Include auto-rotate
+ About app
+ Version %s
+
+
+ Quick settings tile to select portrait or landscape screen orientation.
+
+ Android app developed by Mudar Noufal.
+ Open source project, available on GitHub. Source code is released under the GPLv3 license from the Free Software Foundation.
+ Please share or rate the app if you like it!
+
+
+ Try it
+
+
+
+ Portrait rotation is set to 0 degrees.
+ Portrait rotation is set to 180 degrees (upside down).
+ Landscape rotation is set to 90 degrees clockwise.
+ Landscape rotation is set to 90 degrees counterclockwise.
+
+
+ Credits
+ Source code
+ Rate app
+
+
diff --git a/app/src/main/res/values/strings_common.xml b/app/src/main/res/values/strings_common.xml
new file mode 100644
index 0000000..781789e
--- /dev/null
+++ b/app/src/main/res/values/strings_common.xml
@@ -0,0 +1,15 @@
+
+
+
+ http://play.google.com/store/apps/details?id=ca.mudar.orientationtile
+ http://www.mudar.ca/
+ https://github.com/mudar/ScreenOrientationTile
+
+ prefs_permission_granted
+ prefs_reverse_port
+ prefs_reverse_land
+ prefs_auto_rotate
+ prefs_about
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..9a377a6
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/prefs_defaults.xml b/app/src/main/res/xml/prefs_defaults.xml
new file mode 100644
index 0000000..aacb55a
--- /dev/null
+++ b/app/src/main/res/xml/prefs_defaults.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/prefs_settings.xml b/app/src/main/res/xml/prefs_settings.xml
new file mode 100644
index 0000000..5f47b29
--- /dev/null
+++ b/app/src/main/res/xml/prefs_settings.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..d0aa704
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.2'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..024b1bb
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun May 07 17:50:37 EDT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/playstore/EN/01_main.png b/playstore/EN/01_main.png
new file mode 100644
index 0000000..deb2045
Binary files /dev/null and b/playstore/EN/01_main.png differ
diff --git a/playstore/EN/02_quick_settings.png b/playstore/EN/02_quick_settings.png
new file mode 100644
index 0000000..6c96e6a
Binary files /dev/null and b/playstore/EN/02_quick_settings.png differ
diff --git a/playstore/EN/description-en.md b/playstore/EN/description-en.md
new file mode 100644
index 0000000..d0d5762
--- /dev/null
+++ b/playstore/EN/description-en.md
@@ -0,0 +1,14 @@
+## Title
+*30 chars*
+
+Rotation Quick Setting
+
+## Short description
+*80 chars*
+
+Quick settings tile to select portrait or landscape screen orientation.
+
+## Full description
+*4000 chars*
+
+Intended for Nexus 7 devices with accelerometer auto-rotation issues.
diff --git a/playstore/web_hi_res_512.png b/playstore/web_hi_res_512.png
new file mode 100644
index 0000000..17c2338
Binary files /dev/null and b/playstore/web_hi_res_512.png differ
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'