Compare commits

...

6 Commits

Author SHA1 Message Date
topjohnwu
1adf331268 Bump version 2017-12-29 04:03:05 +08:00
topjohnwu
349b3e961b More robust sudb handling 2017-12-29 04:01:39 +08:00
topjohnwu
96650c06f0 Fix the issue that installation configs won't stick 2017-12-29 03:21:51 +08:00
dark-basic #DarkBasic BasicHD
26038a0a07 Update strings.xml 2017-12-29 01:44:36 +08:00
topjohnwu
6a148b5dd9 Add sorting repo by update time 2017-12-27 01:07:33 +08:00
topjohnwu
0e109ef979 Remove snet version checkpoint, always check by code 2017-12-26 18:24:43 +08:00
22 changed files with 187 additions and 119 deletions

View File

@@ -2,14 +2,14 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion "27.0.2"
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "com.topjohnwu.magisk"
minSdkVersion 21
targetSdkVersion 27
versionCode 82
versionName "5.5.1"
versionCode 84
versionName "5.5.2"
ndk {
moduleName 'zipadjust'
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'

View File

@@ -1,12 +1,4 @@
### v5.5.1
- Fix an issue in setting up superuser database
### v5.5.0
- Fix dynamic resource loading, prevent crashes when checking SafetyNet
- Update SignAPK to use very little RAM for supporting old devices
- Support settings migration after hiding Magisk Manager
- Add reboot menu in modules section
- Add dark theme to superuser request dialogs
- Properly handle new `HIGHCOMP` and add recommended `KEEPVERITY` and `KEEPFORCEENCRYPT` flags for installation
- Support new paths for v14.6
- Massive improvements in repackaging Magisk Manager
### v5.5.2
- Support sorting online repos with last update
- Fix issue that advanced installation settings won't stick
- Prevent sudb crashing Magisk Manager

View File

@@ -91,7 +91,7 @@ public class MagiskFragment extends Fragment
new CheckSafetyNet(getActivity()).exec();
collapse();
};
if (mm.snetVersion < 0) {
if (!CheckSafetyNet.dexPath.exists()) {
// Show dialog
new AlertDialogBuilder(getActivity())
.setTitle(R.string.proprietary_title)
@@ -138,13 +138,9 @@ public class MagiskFragment extends Fragment
setupExpandable();
keepVerityChkbox.setChecked(mm.keepVerity);
keepVerityChkbox.setOnCheckedChangeListener((view, isChecked) -> {
mm.keepVerity = isChecked;
});
keepVerityChkbox.setOnCheckedChangeListener((view, checked) -> mm.keepVerity = checked);
keepEncChkbox.setChecked(mm.keepEnc);
keepEncChkbox.setOnCheckedChangeListener((view, isChecked) -> {
mm.keepEnc = isChecked;
});
keepEncChkbox.setOnCheckedChangeListener((view, checked) -> mm.keepEnc = checked);
mSwipeRefreshLayout.setOnRefreshListener(this);
updateUI();

View File

@@ -49,7 +49,6 @@ public class MagiskManager extends Application {
public int remoteManagerVersionCode = -1;
public String managerLink;
public String bootBlock = null;
public int snetVersion;
public boolean keepVerity = false;
public boolean keepEnc = false;
@@ -76,6 +75,7 @@ public class MagiskManager extends Application {
public int updateChannel;
public String bootFormat;
public String customChannelUrl;
public int repoOrder;
// Global resources
public SharedPreferences prefs;
@@ -106,7 +106,7 @@ public class MagiskManager extends Application {
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
}
suDB = new SuDatabaseHelper(false);
suDB = SuDatabaseHelper.getSuDB(false);
repoDB = new RepoDatabaseHelper(this);
defaultLocale = Locale.getDefault();
setLocale();
@@ -145,8 +145,30 @@ public class MagiskManager extends Application {
updateNotification = prefs.getBoolean(Const.Key.UPDATE_NOTIFICATION, true);
updateChannel = Utils.getPrefsInt(prefs, Const.Key.UPDATE_CHANNEL, Const.Value.STABLE_CHANNEL);
bootFormat = prefs.getString(Const.Key.BOOT_FORMAT, ".img");
snetVersion = prefs.getInt(Const.Key.SNET_VER, -1);
customChannelUrl = prefs.getString(Const.Key.CUSTOM_CHANNEL, "");
repoOrder = prefs.getInt(Const.Key.REPO_ORDER, Const.Value.ORDER_NAME);
}
public void writeConfig() {
prefs.edit()
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
.putBoolean(Const.Key.UPDATE_NOTIFICATION, updateNotification)
.putBoolean(Const.Key.HOSTS, Utils.itemExist(Const.MAGISK_HOST_FILE()))
.putBoolean(Const.Key.COREONLY, Utils.itemExist(Const.MAGISK_DISABLE_FILE))
.putBoolean(Const.Key.SU_REAUTH, suReauth)
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
.putString(Const.Key.ROOT_ACCESS, String.valueOf(suAccessState))
.putString(Const.Key.SU_MULTIUSER_MODE, String.valueOf(multiuserMode))
.putString(Const.Key.SU_MNT_NS, String.valueOf(suNamespaceMode))
.putString(Const.Key.UPDATE_CHANNEL, String.valueOf(updateChannel))
.putString(Const.Key.LOCALE, localeConfig)
.putString(Const.Key.BOOT_FORMAT, bootFormat)
.putInt(Const.Key.UPDATE_SERVICE_VER, Const.UPDATE_SERVICE_VER)
.putInt(Const.Key.REPO_ORDER, repoOrder)
.apply();
}
public static void toast(String msg, int duration) {
@@ -190,6 +212,14 @@ public class MagiskManager extends Application {
if (Utils.isValidShellResponse(ret))
bootBlock = ret.get(0);
if (suDB != null && !SuDatabaseHelper.verified) {
suDB.close();
suDB = SuDatabaseHelper.getSuDB(true);
}
}
public void getDefaultInstallFlags() {
List<String> ret;
ret = Shell.su("echo \"$DTBOIMAGE\"");
if (Utils.isValidShellResponse(ret))
keepVerity = true;
@@ -213,11 +243,6 @@ public class MagiskManager extends Application {
if (Utils.isValidShellResponse(ret))
keepEnc = Boolean.parseBoolean(ret.get(0));
} catch (NumberFormatException ignored) {}
if (suDB != null && !SuDatabaseHelper.verified) {
suDB.close();
suDB = new SuDatabaseHelper();
}
}
public void setPermissionGrantCallback(Runnable callback) {

View File

@@ -1,5 +1,6 @@
package com.topjohnwu.magisk;
import android.app.AlertDialog;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
@@ -7,6 +8,7 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SearchView;
@@ -15,6 +17,7 @@ import android.widget.TextView;
import com.topjohnwu.magisk.adapters.ReposAdapter;
import com.topjohnwu.magisk.asyncs.UpdateRepos;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.Topic;
import butterknife.BindView;
@@ -98,6 +101,22 @@ public class ReposFragment extends Fragment implements Topic.Subscriber {
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
MagiskManager mm = getApplication();
if (item.getItemId() == R.id.repo_sort) {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.sorting_order)
.setSingleChoiceItems(R.array.sorting_orders, mm.repoOrder, (d, which) -> {
mm.repoOrder = which;
mm.prefs.edit().putInt(Const.Key.REPO_ORDER, mm.repoOrder).apply();
adapter.notifyDBChanged();
d.dismiss();
}).show();
}
return true;
}
@Override
public void onDestroyView() {
super.onDestroyView();

View File

@@ -34,6 +34,7 @@ public class SplashActivity extends Activity {
MagiskManager mm = getMagiskManager();
mm.loadMagiskInfo();
mm.getDefaultInstallFlags();
Utils.loadPrefs();
// Dynamic detect all locales
@@ -61,7 +62,7 @@ public class SplashActivity extends Activity {
if (Shell.rootAccess() && mm.magiskVersionCode > 0) {
// Add update checking service
if (Const.Value.UPDATE_SERVICE_VER > mm.prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
if (Const.UPDATE_SERVICE_VER > mm.prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
ComponentName service = new ComponentName(this, UpdateCheckService.class);
JobInfo info = new JobInfo.Builder(Const.ID.UPDATE_SERVICE_ID, service)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
@@ -79,24 +80,7 @@ public class SplashActivity extends Activity {
}
// Write back default values
mm.prefs.edit()
.putBoolean(Const.Key.DARK_THEME, mm.isDarkTheme)
.putBoolean(Const.Key.MAGISKHIDE, mm.magiskHide)
.putBoolean(Const.Key.UPDATE_NOTIFICATION, mm.updateNotification)
.putBoolean(Const.Key.HOSTS, Utils.itemExist(Const.MAGISK_HOST_FILE()))
.putBoolean(Const.Key.COREONLY, Utils.itemExist(Const.MAGISK_DISABLE_FILE))
.putBoolean(Const.Key.SU_REAUTH, mm.suReauth)
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(mm.suRequestTimeout))
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(mm.suResponseType))
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(mm.suNotificationType))
.putString(Const.Key.ROOT_ACCESS, String.valueOf(mm.suAccessState))
.putString(Const.Key.SU_MULTIUSER_MODE, String.valueOf(mm.multiuserMode))
.putString(Const.Key.SU_MNT_NS, String.valueOf(mm.suNamespaceMode))
.putString(Const.Key.UPDATE_CHANNEL, String.valueOf(mm.updateChannel))
.putString(Const.Key.LOCALE, mm.localeConfig)
.putString(Const.Key.BOOT_FORMAT, mm.bootFormat)
.putInt(Const.Key.UPDATE_SERVICE_VER, Const.Value.UPDATE_SERVICE_VER)
.apply();
mm.writeConfig();
mm.hasInit = true;

View File

@@ -108,7 +108,7 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.app_name) TextView appName;
@BindView(R.id.app_package) TextView appPackage;
@BindView(R.id.package_name) TextView appPackage;
@BindView(R.id.checkbox) CheckBox checkBox;
ViewHolder(View itemView) {

View File

@@ -95,6 +95,7 @@ public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, R
String author = repo.getAuthor();
holder.author.setText(TextUtils.isEmpty(author) ? null : context.getString(R.string.author, author));
holder.description.setText(repo.getDescription());
holder.updateTime.setText(context.getString(R.string.updated_on, repo.getLastUpdateString()));
holder.infoLayout.setOnClickListener(v ->
new MarkDownWindow((Activity) context, null, repo.getDetailUrl()).exec());
@@ -180,6 +181,7 @@ public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, R
@BindView(R.id.author) TextView author;
@BindView(R.id.info_layout) LinearLayout infoLayout;
@BindView(R.id.download) ImageView downloadImage;
@BindView(R.id.update_time) TextView updateTime;
RepoHolder(View itemView) {
super(itemView);

View File

@@ -22,13 +22,13 @@ import dalvik.system.DexClassLoader;
public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
private File dexPath;
public static final File dexPath =
new File(MagiskManager.get().getFilesDir().getParent() + "/snet", "snet.apk");
private DexClassLoader loader;
private Class<?> helperClazz, callbackClazz;
public CheckSafetyNet(Activity activity) {
super(activity);
dexPath = new File(activity.getCacheDir().getParent() + "/snet", "snet.apk");
}
private void dlSnet() throws IOException {
@@ -65,7 +65,7 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
e.printStackTrace();
}
if (snet_ver != Const.Value.SNET_VER) {
if (snet_ver != Const.SNET_VER) {
dlSnet();
loadClasses();
}
@@ -79,8 +79,6 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
@Override
protected void onPostExecute(Exception err) {
MagiskManager mm = MagiskManager.get();
mm.snetVersion = Const.Value.SNET_VER;
mm.prefs.edit().putInt(Const.Key.SNET_VER, Const.Value.SNET_VER).apply();
try {
if (err != null) throw err;
Object helper = helperClazz.getConstructors()[0].newInstance(

View File

@@ -3,9 +3,11 @@ package com.topjohnwu.magisk.container;
import android.content.ContentValues;
import android.database.Cursor;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Const;
import com.topjohnwu.magisk.utils.WebService;
import java.text.DateFormat;
import java.util.Date;
public class Repo extends BaseModule {
@@ -40,7 +42,7 @@ public class Repo extends BaseModule {
if (getVersionCode() < 0) {
throw new IllegalRepoException("Repo [" + repoName + "] does not contain versionCode");
}
if (getMinMagiskVersion() < Const.Value.MIN_MODULE_VER) {
if (getMinMagiskVersion() < Const.MIN_MODULE_VER) {
throw new IllegalRepoException("Repo [" + repoName + "] is outdated");
}
}
@@ -78,6 +80,11 @@ public class Repo extends BaseModule {
return String.format(Const.Url.FILE_URL, repoName, "README.md");
}
public String getLastUpdateString() {
return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM,
MagiskManager.locale).format(mLastUpdate);
}
public Date getLastUpdate() {
return mLastUpdate;
}

View File

@@ -28,7 +28,7 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
// Clear bad repos
mDb.delete(TABLE_NAME, "minMagisk<?",
new String[] { String.valueOf(Const.Value.MIN_MODULE_VER) });
new String[] { String.valueOf(Const.MIN_MODULE_VER) });
}
@Override
@@ -95,9 +95,17 @@ public class RepoDatabaseHelper extends SQLiteOpenHelper {
}
public Cursor getRepoCursor() {
String orderBy = null;
switch (mm.repoOrder) {
case Const.Value.ORDER_NAME:
orderBy = "name COLLATE NOCASE";
break;
case Const.Value.ORDER_DATE:
orderBy = "last_update DESC";
}
return mDb.query(TABLE_NAME, null, "minMagisk<=?",
new String[] { String.valueOf(mm.magiskVersionCode) },
null, null, "name COLLATE NOCASE");
null, null, orderBy);
}
public List<String> getRepoIDList() {

View File

@@ -62,7 +62,7 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
File db = Utils.getDB(context, DB_NAME);
if (!verify) {
if (db.length() == 0) {
if (db.exists() && db.length() == 0) {
ce.loadMagiskInfo();
// Continue verification
} else {
@@ -108,7 +108,7 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
// New global su db
Shell.su(Utils.fmt("mkdir %s 2>/dev/null; chmod 700 %s", GLOBAL_DB.getParent(), GLOBAL_DB.getParent()));
if (!Utils.itemExist(GLOBAL_DB)) {
Utils.javaCreateFile(db);
context.openOrCreateDatabase(DB_NAME, 0, null).close();
Shell.su(Utils.fmt("cp -af %s %s; rm -f %s*", db, GLOBAL_DB, db));
}
verified = TextUtils.equals(Utils.checkInode(GLOBAL_DB), Utils.checkInode(db));
@@ -125,12 +125,17 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
return context;
}
public SuDatabaseHelper() {
this(true);
}
public SuDatabaseHelper(boolean verify) {
this(initDB(verify));
public static SuDatabaseHelper getSuDB(boolean verify) {
try {
return new SuDatabaseHelper(initDB(verify));
} catch(Exception e) {
// Try to catch runtime exceptions and remove all db for retry
unmntDB();
Shell.su(Utils.fmt("rm -rf /data/user*/*/magisk.db /data/adb/magisk.db /data/user*/*/%s/databases"),
MagiskManager.get().getPackageName());
e.printStackTrace();
return new SuDatabaseHelper(initDB(false));
}
}
private SuDatabaseHelper(Context context) {

View File

@@ -30,6 +30,11 @@ public class Const {
public static final File EXTERNAL_PATH = new File(Environment.getExternalStorageDirectory(), "MagiskManager");
public static final String MANAGER_CONFIGS = ".tmp.magisk.config";
// Versions
public static final int UPDATE_SERVICE_VER = 1;
public static final int SNET_VER = 7;
public static final int MIN_MODULE_VER = 1400;
public static String BUSYBOX_PATH() {
if (Utils.itemExist("/sbin/.core/busybox/busybox")) {
return "/sbin/.core/busybox";
@@ -118,7 +123,6 @@ public class Const {
public static final String UPDATE_CHANNEL = "update_channel";
public static final String CUSTOM_CHANNEL = "custom_channel";
public static final String BOOT_FORMAT = "boot_format";
public static final String SNET_VER = "snet_version";
public static final String UPDATE_SERVICE_VER = "update_service_version";
public static final String APP_VER = "app_version";
public static final String MAGISKHIDE = "magiskhide";
@@ -129,6 +133,7 @@ public class Const {
public static final String ETAG_KEY = "ETag";
public static final String LINK_KEY = "Link";
public static final String IF_NONE_MATCH = "If-None-Match";
public static final String REPO_ORDER = "repo_order";
}
@@ -158,8 +163,7 @@ public class Const {
public static final String PATCH_BOOT = "patch";
public static final String FLASH_MAGISK = "magisk";
public static final int[] timeoutList = {0, -1, 10, 20, 30, 60};
public static final int UPDATE_SERVICE_VER = 1;
public static final int SNET_VER = 7;
public static final int MIN_MODULE_VER = 1400;
public static final int ORDER_NAME = 0;
public static final int ORDER_DATE = 1;
}
}

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/imageColorTint"
android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
</vector>

View File

@@ -15,71 +15,63 @@
card_view:cardCornerRadius="@dimen/card_corner_radius"
card_view:cardElevation="@dimen/card_elevation">
<RelativeLayout
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:padding="@dimen/card_layout_padding">
android:layout_height="wrap_content"
android:id="@+id/info_layout"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<ImageView
android:id="@+id/app_icon"
android:layout_width="@dimen/card_appicon_size"
android:layout_height="@dimen/card_appicon_size"
android:layout_centerVertical="true"
android:scaleType="centerCrop"/>
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical"
android:gravity="end" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignBottom="@+id/app_icon"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingEnd="@dimen/card_appicon_size"
android:paddingStart="65dp"
android:weightSum="1">
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp">
<TextView
android:id="@+id/app_name"
android:layout_width="fill_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:paddingEnd="3dp"
android:paddingStart="3dp"
android:textStyle="bold"/>
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textIsSelectable="false"/>
<TextView
android:id="@+id/app_package"
android:layout_width="fill_parent"
android:layout_height="25dp"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:marqueeRepeatLimit="marquee_forever"
android:paddingEnd="3dp"
android:paddingStart="3dp"
android:singleLine="true"/>
android:id="@+id/package_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false" />
</LinearLayout>
<LinearLayout
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true">
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:gravity="center"
android:src="@drawable/ic_menu_overflow_material"
android:checked="false" />
</LinearLayout>
</RelativeLayout>
android:focusable="false"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_menu_overflow_material"
android:checked="false" />
</LinearLayout>
</android.support.v7.widget.CardView>

View File

@@ -52,7 +52,6 @@
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorPrimary"
android:textIsSelectable="false"/>
<TextView

View File

@@ -67,6 +67,15 @@
android:textAppearance="?android:attr/textAppearanceSmall"
android:textIsSelectable="false" />
<TextView
android:id="@+id/update_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/tertiary_text_dark"
android:textIsSelectable="false"
android:textStyle="bold|italic" />
</LinearLayout>
<ImageView

View File

@@ -2,9 +2,15 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/repo_sort"
android:icon="@drawable/ic_sort"
app:showAsAction="always"/>
<item
android:id="@+id/repo_search"
android:title=""
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always"/>
</menu>

View File

@@ -50,6 +50,10 @@
<string name="update_available">Actualización disponible</string>
<string name="installed">Instalado</string>
<string name="not_installed">No Instalado</string>
<string name="updated_on">Actualizando en: %1$s</string>
<string name="sorting_order">Orden de Clasificación</string>
<string name="sort_by_name">Ordenar por nombre</string>
<string name="sort_by_update">Ordenar según la última actualización</string>
<!--Log Fragment-->
<string name="menuSaveLog">Guardar registro</string>

View File

@@ -83,4 +83,9 @@
<item>.img.tar</item>
</string-array>
<string-array name="sorting_orders">
<item>@string/sort_by_name</item>
<item>@string/sort_by_update</item>
</string-array>
</resources>

View File

@@ -53,6 +53,10 @@
<string name="update_available">Update Available</string>
<string name="installed">Installed</string>
<string name="not_installed">Not Installed</string>
<string name="updated_on">Updated on: %1$s</string>
<string name="sorting_order">Sorting Order</string>
<string name="sort_by_name">Sort by name</string>
<string name="sort_by_update">Sort by last update</string>
<!--Log Fragment-->
<string name="menuSaveLog">Save log</string>

View File

@@ -12,7 +12,7 @@
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="imageColorTint">@android:color/background_dark</item>
<item name="imageColorTint">@android:color/secondary_text_light</item>
</style>
<style name="AppTheme.Dark" parent="Theme.AppCompat.NoActionBar">
@@ -25,7 +25,7 @@
<item name="windowNoTitle">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:textColorSecondary">@color/dark_secondary_text</item>
<item name="imageColorTint">@android:color/background_light</item>
<item name="imageColorTint">@color/dark_secondary_text</item>
</style>
<style name="CardViewStyle.Dark" parent="CardView">