Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Termux Operation plugin #205

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2016 - 2018 Rui Zhao <[email protected]>
*
* This file is part of Easer.
*
* Easer 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.
*
* Easer 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 Easer. If not, see <http://www.gnu.org/licenses/>.
*/

package ryey.easer.plugins.operation.termux;

import android.os.Parcel;

import org.junit.Test;

import ryey.easer.plugins.TestHelper;
import ryey.easer.plugins.operation.command.CommandOperationData;
import ryey.easer.plugins.operation.command.CommandOperationDataFactory;

import static org.junit.Assert.assertEquals;

public class TermuxOperationDataTest {

@Test
public void testParcel() {
TermuxOperationData dummyData = new TermuxOperationDataFactory().dummyData();
Parcel parcel = TestHelper.writeToParcel(dummyData);
CommandOperationData parceledData = CommandOperationData.CREATOR.createFromParcel(parcel);
assertEquals(dummyData, parceledData);
}

}
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="com.termux.permission.TERMUX_SERVICE" />


<application
android:name=".EaserApplication"
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/ryey/easer/plugins/LocalPluginRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import ryey.easer.plugins.operation.send_sms.SendSmsOperationPlugin;
import ryey.easer.plugins.operation.state_control.StateControlOperationPlugin;
import ryey.easer.plugins.operation.synchronization.SynchronizationOperationPlugin;
import ryey.easer.plugins.operation.termux.TermuxOperationPlugin;
import ryey.easer.plugins.operation.ui_mode.UiModeOperationPlugin;
import ryey.easer.plugins.operation.volume.VolumeOperationPlugin;
import ryey.easer.plugins.operation.wifi.WifiOperationPlugin;
Expand Down Expand Up @@ -163,6 +164,11 @@ final public class LocalPluginRegistry {
operation().registerPlugin(LaunchAppOperationPlugin.class);
operation().registerPlugin(UiModeOperationPlugin.class);
//TODO: write more plugins
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
// TODO define it as external plugin ? or check if termux is installed
operation().registerPlugin(TermuxOperationPlugin.class);

}
}

private static final LocalPluginRegistry instance = new LocalPluginRegistry();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;

import ryey.easer.R;
Expand All @@ -30,6 +31,7 @@
import ryey.easer.commons.local_plugin.operationplugin.PrivilegeUsage;
import ryey.easer.plugin.operation.Category;
import ryey.easer.plugins.operation.OperationLoader;
import ryey.easer.plugins.reusable.PluginHelper;

public class CommandOperationPlugin implements OperationPlugin<CommandOperationData> {

Expand Down Expand Up @@ -73,7 +75,6 @@ public boolean checkPermissions(@NonNull Context context) {

@Override
public void requestPermissions(@NonNull Activity activity, int requestCode) {

}

@NonNull
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ryey.easer.plugins.operation.termux;

public class TermuxConstant {

public static final String URI_SCHEME = "com.termux.file";
public static final String ACTION_NAME = "com.termux.service_execute";
public static final String PACKAGE_NAME = "com.termux";
public static final String CLASS_NAME = "com.termux.app.TermuxService";
public static final String EXTRA_BACKGROUND = "com.termux.execute.background";
public static final String EXTRA_INITIAL_URI = "content://com.termux.documents/document/";
public static final String COLUMN_ID = "document_id";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2016 - 2018 Rui Zhao <[email protected]>
*
* This file is part of Easer.
*
* Easer 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.
*
* Easer 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 Easer. If not, see <http://www.gnu.org/licenses/>.
*/

package ryey.easer.plugins.operation.termux;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;

import com.orhanobut.logger.Logger;

import java.io.File;
import java.io.IOException;

import ryey.easer.Utils;
import ryey.easer.commons.local_plugin.ValidData;
import ryey.easer.plugins.operation.OperationLoader;
import ryey.easer.plugins.reusable.PluginHelper;

import static ryey.easer.plugins.operation.termux.TermuxConstant.ACTION_NAME;
import static ryey.easer.plugins.operation.termux.TermuxConstant.CLASS_NAME;
import static ryey.easer.plugins.operation.termux.TermuxConstant.EXTRA_BACKGROUND;
import static ryey.easer.plugins.operation.termux.TermuxConstant.PACKAGE_NAME;
import static ryey.easer.plugins.operation.termux.TermuxConstant.URI_SCHEME;

public class TermuxLoader extends OperationLoader<TermuxOperationData> {
public TermuxLoader(Context context) {
super(context);
}

@Override
public boolean load(@ValidData @NonNull TermuxOperationData data) {
boolean success = true;
String script = Utils.format(data.get());
File f = new File(script);
Logger.i("Running Termux command: " + f.getAbsolutePath());
Uri scriptUri = new Uri.Builder().scheme(URI_SCHEME).path(f.getAbsolutePath()).build();
Intent executeIntent = new Intent(ACTION_NAME, scriptUri);
executeIntent.setClassName(PACKAGE_NAME, CLASS_NAME);
executeIntent.putExtra(EXTRA_BACKGROUND, true);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// https://developer.android.com/about/versions/oreo/background.html
context.startForegroundService(executeIntent);
} else {
context.startService(executeIntent);
}
return success;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2016 - 2018 Rui Zhao <[email protected]>
*
* This file is part of Easer.
*
* Easer 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.
*
* Easer 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 Easer. If not, see <http://www.gnu.org/licenses/>.
*/

package ryey.easer.plugins.operation.termux;

import android.os.Parcel;
import android.support.annotation.NonNull;

import ryey.easer.Utils;
import ryey.easer.commons.local_plugin.IllegalStorageDataException;
import ryey.easer.commons.local_plugin.dynamics.SolidDynamicsAssignment;
import ryey.easer.commons.local_plugin.operationplugin.OperationData;
import ryey.easer.plugin.PluginDataFormat;
import ryey.easer.plugins.operation.StringOperationData;

public class TermuxOperationData extends StringOperationData {

TermuxOperationData(String script) {
super(script);
}

TermuxOperationData(@NonNull String data, @NonNull PluginDataFormat format, int version) throws IllegalStorageDataException {
super(data, format, version);
}

public static final Creator<TermuxOperationData> CREATOR
= new Creator<TermuxOperationData>() {
public TermuxOperationData createFromParcel(Parcel in) {
return new TermuxOperationData(in);
}

public TermuxOperationData[] newArray(int size) {
return new TermuxOperationData[size];
}
};

private TermuxOperationData(Parcel in) {
super(in);
}

@NonNull
@Override
public OperationData applyDynamics(SolidDynamicsAssignment dynamicsAssignment) {
return new TermuxOperationData(Utils.applyDynamics(text, dynamicsAssignment));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2016 - 2018 Rui Zhao <[email protected]>
*
* This file is part of Easer.
*
* Easer 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.
*
* Easer 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 Easer. If not, see <http://www.gnu.org/licenses/>.
*/

package ryey.easer.plugins.operation.termux;

import android.support.annotation.NonNull;

import ryey.easer.commons.local_plugin.IllegalStorageDataException;
import ryey.easer.commons.local_plugin.ValidData;
import ryey.easer.commons.local_plugin.operationplugin.OperationDataFactory;
import ryey.easer.plugin.PluginDataFormat;

class TermuxOperationDataFactory implements OperationDataFactory<TermuxOperationData> {
@NonNull
@Override
public Class<TermuxOperationData> dataClass() {
return TermuxOperationData.class;
}

@ValidData
@NonNull
@Override
public TermuxOperationData dummyData() {
return new TermuxOperationData("/sdcard/mycmd_file");
}

@ValidData
@NonNull
@Override
public TermuxOperationData parse(@NonNull String data, @NonNull PluginDataFormat format, int version) throws IllegalStorageDataException {
return new TermuxOperationData(data, format, version);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2016 - 2018 Rui Zhao <[email protected]>
*
* This file is part of Easer.
*
* Easer 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.
*
* Easer 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 Easer. If not, see <http://www.gnu.org/licenses/>.
*/

package ryey.easer.plugins.operation.termux;

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;

import ryey.easer.R;
import ryey.easer.commons.local_plugin.PluginViewFragmentInterface;
import ryey.easer.commons.local_plugin.operationplugin.OperationDataFactory;
import ryey.easer.commons.local_plugin.operationplugin.OperationPlugin;
import ryey.easer.commons.local_plugin.operationplugin.PrivilegeUsage;
import ryey.easer.plugin.operation.Category;
import ryey.easer.plugins.operation.OperationLoader;
import ryey.easer.plugins.reusable.PluginHelper;

public class TermuxOperationPlugin implements OperationPlugin<TermuxOperationData> {

@NonNull
@Override
public String id() {
return "termux";
}

@Override
public int name() {
return R.string.operation_termux;
}

@Override
public boolean isCompatible(@NonNull final Context context) {
return true;
}

@NonNull
@Override
public PrivilegeUsage privilege() {
return PrivilegeUsage.prefer_root;
}

@Override
public int maxExistence() {
return 0;
}

@NonNull
@Override
public Category category() {
return Category.misc;
}

@Override
public boolean checkPermissions(@NonNull Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return PluginHelper.checkPermission(context, "com.termux.permission.TERMUX_SERVICE");
} else {
return true;
}
}

@Override
public void requestPermissions(@NonNull Activity activity, int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PluginHelper.requestPermission(activity, requestCode, "com.termux.permission.TERMUX_SERVICE");
}
}

@NonNull
@Override
public OperationDataFactory<TermuxOperationData> dataFactory() {
return new TermuxOperationDataFactory();

}

@NonNull
@Override
public PluginViewFragmentInterface<TermuxOperationData> view() {
return new TermuxPluginViewFragment();
}

@NonNull
@Override
public OperationLoader<TermuxOperationData> loader(@NonNull Context context) {
return new TermuxLoader(context);
}

}
Loading