Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
9614ec4c
Commit
9614ec4c
authored
Oct 03, 2016
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Magisk officially moving away from Safety Net bypasses
parent
c4e90b81
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
6 additions
and
479 deletions
+6
-479
MainActivity.java
app/src/main/java/com/topjohnwu/magisk/MainActivity.java
+0
-5
RootFragment.java
app/src/main/java/com/topjohnwu/magisk/RootFragment.java
+0
-221
Shell.java
app/src/main/java/com/topjohnwu/magisk/utils/Shell.java
+6
-12
Utils.java
app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
+0
-11
ic_error.xml
app/src/main/res/drawable/ic_error.xml
+0
-9
root.xml
app/src/main/res/drawable/root.xml
+0
-9
root_fragment.xml
app/src/main/res/layout/root_fragment.xml
+0
-189
drawer.xml
app/src/main/res/menu/drawer.xml
+0
-4
strings.xml
app/src/main/res/values/strings.xml
+0
-19
No files found.
app/src/main/java/com/topjohnwu/magisk/MainActivity.java
View file @
9614ec4c
...
...
@@ -129,11 +129,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
tag
=
"magisk"
;
navFragment
=
new
MagiskFragment
();
break
;
case
R
.
id
.
root
:
setTitle
(
R
.
string
.
root
);
tag
=
"root"
;
navFragment
=
new
RootFragment
();
break
;
case
R
.
id
.
modules
:
setTitle
(
R
.
string
.
modules
);
tag
=
"modules"
;
...
...
app/src/main/java/com/topjohnwu/magisk/RootFragment.java
deleted
100644 → 0
View file @
c4e90b81
package
com
.
topjohnwu
.
magisk
;
import
android.app.Fragment
;
import
android.content.SharedPreferences
;
import
android.os.AsyncTask
;
import
android.os.Bundle
;
import
android.preference.PreferenceManager
;
import
android.support.annotation.Nullable
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.CompoundButton
;
import
android.widget.ImageView
;
import
android.widget.ProgressBar
;
import
android.widget.Switch
;
import
android.widget.TextView
;
import
com.topjohnwu.magisk.utils.Logger
;
import
com.topjohnwu.magisk.utils.Shell
;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.io.File
;
import
java.util.List
;
import
butterknife.BindColor
;
import
butterknife.BindView
;
import
butterknife.ButterKnife
;
public
class
RootFragment
extends
Fragment
{
public
SharedPreferences
prefs
;
@BindView
(
R
.
id
.
progressBar
)
ProgressBar
progressBar
;
@BindView
(
R
.
id
.
rootSwitchView
)
View
rootToggleView
;
@BindView
(
R
.
id
.
selinuxSwitchView
)
View
selinuxToggleView
;
@BindView
(
R
.
id
.
rootStatusView
)
View
rootStatusView
;
@BindView
(
R
.
id
.
safetynetStatusView
)
View
safetynetStatusView
;
@BindView
(
R
.
id
.
selinuxStatusView
)
View
selinuxStatusView
;
@BindView
(
R
.
id
.
root_toggle
)
Switch
rootToggle
;
@BindView
(
R
.
id
.
selinux_toggle
)
Switch
selinuxToggle
;
@BindView
(
R
.
id
.
root_status_container
)
View
rootStatusContainer
;
@BindView
(
R
.
id
.
root_status_icon
)
ImageView
rootStatusIcon
;
@BindView
(
R
.
id
.
root_status
)
TextView
rootStatus
;
@BindView
(
R
.
id
.
selinux_status_container
)
View
selinuxStatusContainer
;
@BindView
(
R
.
id
.
selinux_status_icon
)
ImageView
selinuxStatusIcon
;
@BindView
(
R
.
id
.
selinux_status
)
TextView
selinuxStatus
;
@BindView
(
R
.
id
.
safety_net_status
)
TextView
safetyNetStatus
;
@BindView
(
R
.
id
.
safety_net_icon
)
ImageView
safetyNetStatusIcon
;
int
statusOK
=
R
.
drawable
.
ic_check_circle
;
int
statusError
=
R
.
drawable
.
ic_error
;
int
statusUnknown
=
R
.
drawable
.
ic_help
;
@BindColor
(
R
.
color
.
green500
)
int
colorOK
;
@BindColor
(
R
.
color
.
yellow500
)
int
colorWarn
;
@BindColor
(
R
.
color
.
grey500
)
int
colorNeutral
;
@BindColor
(
R
.
color
.
red500
)
int
colorFail
;
private
SharedPreferences
.
OnSharedPreferenceChangeListener
listener
;
@Nullable
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
View
view
=
inflater
.
inflate
(
R
.
layout
.
root_fragment
,
container
,
false
);
ButterKnife
.
bind
(
this
,
view
);
prefs
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
());
updateUI
();
rootToggle
.
setOnClickListener
(
toggle
->
{
new
AsyncTask
<
Boolean
,
Void
,
Void
>()
{
@Override
protected
Void
doInBackground
(
Boolean
...
bools
)
{
Utils
.
toggleRoot
(
bools
[
0
],
getActivity
());
return
null
;
}
}.
executeOnExecutor
(
AsyncTask
.
SERIAL_EXECUTOR
,
((
CompoundButton
)
toggle
).
isChecked
());
});
selinuxToggle
.
setOnClickListener
(
toggle
->
{
new
AsyncTask
<
Boolean
,
Void
,
Void
>()
{
@Override
protected
Void
doInBackground
(
Boolean
...
bools
)
{
Shell
.
su
(
bools
[
0
]
?
"setenforce 1"
:
"setenforce 0"
);
return
null
;
}
@Override
protected
void
onPostExecute
(
Void
v
)
{
super
.
onPostExecute
(
v
);
updateUI
();
}
}.
executeOnExecutor
(
AsyncTask
.
SERIAL_EXECUTOR
,
((
CompoundButton
)
toggle
).
isChecked
());
});
return
view
;
}
@Override
public
void
onResume
()
{
super
.
onResume
();
listener
=
(
pref
,
key
)
->
{
if
((
key
.
contains
(
"autoRootEnable"
))
||
(
key
.
equals
(
"root"
)))
{
Logger
.
dev
(
"RootFragmnet, keychange detected for "
+
key
);
updateUI
();
}
};
prefs
.
registerOnSharedPreferenceChangeListener
(
listener
);
updateUI
();
}
@Override
public
void
onDestroy
()
{
super
.
onDestroy
();
prefs
.
unregisterOnSharedPreferenceChangeListener
(
listener
);
}
private
void
updateUI
()
{
progressBar
.
setVisibility
(
View
.
GONE
);
rootStatusView
.
setVisibility
(
View
.
VISIBLE
);
safetynetStatusView
.
setVisibility
(
View
.
VISIBLE
);
selinuxStatusView
.
setVisibility
(
View
.
VISIBLE
);
if
(
Shell
.
rootAccess
())
{
rootToggleView
.
setVisibility
(
View
.
VISIBLE
);
selinuxToggleView
.
setVisibility
(
View
.
VISIBLE
);
}
List
<
String
>
selinux
=
Shell
.
sh
(
"getenforce"
);
if
(
selinux
.
isEmpty
())
{
selinuxStatusContainer
.
setBackgroundColor
(
colorNeutral
);
selinuxStatusIcon
.
setImageResource
(
statusUnknown
);
selinuxStatus
.
setText
(
R
.
string
.
selinux_error_info
);
selinuxStatus
.
setTextColor
(
colorNeutral
);
selinuxToggle
.
setChecked
(
false
);
}
else
if
(
selinux
.
get
(
0
).
equals
(
"Enforcing"
))
{
selinuxStatusContainer
.
setBackgroundColor
(
colorOK
);
selinuxStatusIcon
.
setImageResource
(
statusOK
);
selinuxStatus
.
setText
(
R
.
string
.
selinux_enforcing_info
);
selinuxStatus
.
setTextColor
(
colorOK
);
selinuxToggle
.
setChecked
(
true
);
}
else
{
selinuxStatusContainer
.
setBackgroundColor
(
colorFail
);
selinuxStatusIcon
.
setImageResource
(
statusError
);
selinuxStatus
.
setText
(
R
.
string
.
selinux_permissive_info
);
selinuxStatus
.
setTextColor
(
colorFail
);
selinuxToggle
.
setChecked
(
false
);
}
if
(
new
File
(
"/system/framework/twframework.jar"
).
exists
())
{
selinuxStatus
.
append
(
"\n"
+
getString
(
R
.
string
.
selinux_samsung_info
));
}
switch
(
Shell
.
rootStatus
)
{
case
-
1
:
// Root Error
rootStatusContainer
.
setBackgroundColor
(
colorFail
);
rootStatusIcon
.
setImageResource
(
statusUnknown
);
rootStatus
.
setTextColor
(
colorNeutral
);
rootStatus
.
setText
(
R
.
string
.
root_error
);
rootToggle
.
setChecked
(
false
);
safetyNetStatusIcon
.
setImageResource
(
statusUnknown
);
safetyNetStatus
.
setText
(
R
.
string
.
root_error_info
);
break
;
case
0
:
// Not rooted
rootStatusContainer
.
setBackgroundColor
(
colorOK
);
rootStatusIcon
.
setImageResource
(
statusOK
);
rootStatus
.
setTextColor
(
colorOK
);
rootStatus
.
setText
(
R
.
string
.
root_none
);
rootToggle
.
setChecked
(
false
);
safetyNetStatusIcon
.
setImageResource
(
statusOK
);
safetyNetStatus
.
setText
(
R
.
string
.
root_none_info
);
break
;
case
1
:
// Proper root
rootToggle
.
setEnabled
(
true
);
if
(
Utils
.
rootEnabled
())
{
// Mounted
rootStatusContainer
.
setBackgroundColor
(
colorWarn
);
rootStatusIcon
.
setImageResource
(
statusError
);
rootStatus
.
setTextColor
(
colorWarn
);
rootStatus
.
setText
(
R
.
string
.
root_enabled
);
rootToggle
.
setChecked
(
true
);
safetyNetStatusIcon
.
setImageResource
(
statusError
);
safetyNetStatus
.
setText
(
R
.
string
.
root_enabled_info
);
break
;
}
else
{
// Disabled
rootStatusContainer
.
setBackgroundColor
(
colorOK
);
rootStatusIcon
.
setImageResource
(
statusOK
);
rootStatus
.
setTextColor
(
colorOK
);
rootStatus
.
setText
(
R
.
string
.
root_disabled
);
rootToggle
.
setChecked
(
false
);
safetyNetStatusIcon
.
setImageResource
(
statusOK
);
safetyNetStatus
.
setText
(
R
.
string
.
root_disabled_info
);
break
;
}
case
2
:
// Improper root
rootStatusContainer
.
setBackgroundColor
(
colorFail
);
rootStatusIcon
.
setImageResource
(
statusError
);
rootStatus
.
setTextColor
(
colorFail
);
rootStatus
.
setText
(
R
.
string
.
root_system
);
rootToggle
.
setChecked
(
true
);
safetyNetStatusIcon
.
setImageResource
(
statusError
);
safetyNetStatus
.
setText
(
R
.
string
.
root_system_info
);
rootToggleView
.
setVisibility
(
View
.
GONE
);
selinuxToggleView
.
setVisibility
(
View
.
GONE
);
break
;
}
}
}
app/src/main/java/com/topjohnwu/magisk/utils/Shell.java
View file @
9614ec4c
...
...
@@ -12,7 +12,7 @@ import java.util.List;
public
class
Shell
{
// -1 = problematic/unknown issue; 0 = not rooted; 1 = properly rooted
; 2 = improperly rooted;
// -1 = problematic/unknown issue; 0 = not rooted; 1 = properly rooted
public
static
int
rootStatus
;
private
static
Process
rootShell
;
...
...
@@ -27,18 +27,12 @@ public class Shell {
private
static
void
init
()
{
try
{
rootShell
=
Runtime
.
getRuntime
().
exec
(
sh
(
"getprop magisk.supath"
).
get
(
0
)
+
"/
su"
);
rootShell
=
Runtime
.
getRuntime
().
exec
(
"
su"
);
rootStatus
=
1
;
}
catch
(
IOException
e
)
{
try
{
// Improper root
rootShell
=
Runtime
.
getRuntime
().
exec
(
"su"
);
rootStatus
=
2
;
}
catch
(
IOException
err
)
{
// No root
rootStatus
=
0
;
return
;
}
}
catch
(
IOException
err
)
{
// No root
rootStatus
=
0
;
return
;
}
rootSTDIN
=
new
DataOutputStream
(
rootShell
.
getOutputStream
());
...
...
app/src/main/java/com/topjohnwu/magisk/utils/Utils.java
View file @
9614ec4c
...
...
@@ -73,17 +73,6 @@ public class Utils {
return
Shell
.
rootAccess
()
&&
Boolean
.
parseBoolean
(
Shell
.
su
(
command
).
get
(
0
));
}
public
static
void
toggleRoot
(
Boolean
b
,
Context
context
)
{
if
(
MagiskFragment
.
magiskVersion
!=
-
1
)
{
if
(
b
)
{
Shell
.
su
(
"ln -s $(getprop magisk.supath) /magisk/.core/bin"
,
"setprop magisk.root 1"
);
}
else
{
Shell
.
su
(
"rm -rf /magisk/.core/bin"
,
"setprop magisk.root 0"
);
}
PreferenceManager
.
getDefaultSharedPreferences
(
context
).
edit
().
putBoolean
(
"root"
,
b
).
apply
();
}
}
static
List
<
String
>
getModList
(
String
path
)
{
List
<
String
>
ret
;
String
command
=
"find "
+
path
+
" -type d -maxdepth 1 ! -name \"*.core\" ! -name \"*lost+found\" ! -name \"*magisk\""
;
...
...
app/src/main/res/drawable/ic_error.xml
deleted
100644 → 0
View file @
c4e90b81
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportHeight=
"24.0"
android:viewportWidth=
"24.0"
>
<path
android:fillColor=
"#fff"
android:pathData=
"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"
/>
</vector>
app/src/main/res/drawable/root.xml
deleted
100644 → 0
View file @
c4e90b81
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportHeight=
"24"
android:viewportWidth=
"24"
>
<path
android:fillColor=
"#000"
android:pathData=
"M3,5A2,2 0 0,1 5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5C3.89,21 3,20.1 3,19V5M7,18H9L9.35,16H13.35L13,18H15L15.35,16H17.35L17.71,14H15.71L16.41,10H18.41L18.76,8H16.76L17.12,6H15.12L14.76,8H10.76L11.12,6H9.12L8.76,8H6.76L6.41,10H8.41L7.71,14H5.71L5.35,16H7.35L7,18M10.41,10H14.41L13.71,14H9.71L10.41,10Z"
/>
</vector>
\ No newline at end of file
app/src/main/res/layout/root_fragment.xml
deleted
100644 → 0
View file @
c4e90b81
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_marginBottom=
"8dp"
android:layout_marginTop=
"?attr/actionBarSize"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
>
<ProgressBar
android:id=
"@+id/progressBar"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
/>
<android.support.v7.widget.CardView
android:id=
"@+id/rootSwitchView"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:elevation=
"2dp"
android:visibility=
"gone"
style=
"?attr/cardStyle"
app:cardCornerRadius=
"0dp"
>
<Switch
android:id=
"@+id/root_toggle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_margin=
"12dp"
android:checked=
"true"
android:text=
"@string/root_toggle"
android:textSize=
"16sp"
/>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id=
"@+id/selinuxSwitchView"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:elevation=
"2dp"
android:visibility=
"gone"
style=
"?attr/cardStyle"
app:cardCornerRadius=
"0dp"
>
<Switch
android:id=
"@+id/selinux_toggle"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_margin=
"12dp"
android:checked=
"true"
android:text=
"@string/selinux_toggle"
android:textSize=
"16sp"
/>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id=
"@+id/rootStatusView"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"4dp"
android:layout_marginLeft=
"5dip"
android:layout_marginRight=
"5dip"
android:layout_marginTop=
"6dp"
android:visibility=
"gone"
style=
"?attr/cardStyle"
app:cardUseCompatPadding=
"true"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
>
<FrameLayout
android:id=
"@+id/root_status_container"
android:layout_width=
"match_parent"
android:layout_height=
"100dp"
android:foregroundGravity=
"center"
android:orientation=
"vertical"
>
<ImageView
android:id=
"@+id/root_status_icon"
android:layout_width=
"84dp"
android:layout_height=
"84dp"
android:layout_gravity=
"center"
/>
</FrameLayout>
<TextView
android:id=
"@+id/root_status"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:gravity=
"center"
android:padding=
"6dp"
android:textStyle=
"bold"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id=
"@+id/safetynetStatusView"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"4dp"
android:layout_marginLeft=
"5dip"
android:layout_marginRight=
"5dip"
android:layout_marginTop=
"6dp"
android:visibility=
"gone"
style=
"?attr/cardStyle"
app:cardUseCompatPadding=
"true"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
android:padding=
"4dp"
>
<ImageView
android:id=
"@+id/safety_net_icon"
android:layout_width=
"48dp"
android:layout_height=
"48dp"
android:layout_gravity=
"center"
android:tint=
"#757575"
/>
<TextView
android:id=
"@+id/safety_net_status"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:padding=
"6dp"
android:textStyle=
"bold"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id=
"@+id/selinuxStatusView"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginBottom=
"4dp"
android:layout_marginLeft=
"5dip"
android:layout_marginRight=
"5dip"
android:layout_marginTop=
"6dp"
android:visibility=
"gone"
style=
"?attr/cardStyle"
app:cardUseCompatPadding=
"true"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
>
<FrameLayout
android:id=
"@+id/selinux_status_container"
android:layout_width=
"match_parent"
android:layout_height=
"100dp"
android:foregroundGravity=
"center"
android:orientation=
"vertical"
>
<ImageView
android:id=
"@+id/selinux_status_icon"
android:layout_width=
"84dp"
android:layout_height=
"84dp"
android:layout_gravity=
"center"
/>
</FrameLayout>
<TextView
android:id=
"@+id/selinux_status"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_gravity=
"center"
android:gravity=
"center"
android:padding=
"6dp"
android:textStyle=
"bold"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
\ No newline at end of file
app/src/main/res/menu/drawer.xml
View file @
9614ec4c
...
...
@@ -24,10 +24,6 @@
android:id=
"@+id/log"
android:icon=
"@drawable/ic_bug_report"
android:title=
"@string/log"
/>
<item
android:id=
"@+id/root"
android:icon=
"@drawable/root"
android:title=
"@string/root"
/>
</group>
<group
...
...
app/src/main/res/values/strings.xml
View file @
9614ec4c
...
...
@@ -6,7 +6,6 @@
<!--Welcome Activity-->
<string
name=
"navigation_drawer_open"
>
Open navigation drawer
</string>
<string
name=
"navigation_drawer_close"
>
Close navigation drawer
</string>
<string
name=
"root"
>
Root
</string>
<string
name=
"modules"
>
Modules
</string>
<string
name=
"downloads"
>
Downloads
</string>
<string
name=
"log"
>
Log
</string>
...
...
@@ -22,24 +21,6 @@
<string
name=
"up_to_date"
>
Latest version of %1$s installed
</string>
<!--Root Fragment-->
<string
name=
"root_toggle"
>
Root Toggle
</string>
<string
name=
"selinux_toggle"
>
SELinux Toggle
</string>
<string
name=
"root_error"
>
Root Error
</string>
<string
name=
"root_error_info"
>
Safety Net Status Unknown
</string>
<string
name=
"root_none"
>
Not Rooted
</string>
<string
name=
"root_none_info"
>
Safety Net (Android Pay) should work
</string>
<string
name=
"root_enabled"
>
Root enabled
</string>
<string
name=
"root_enabled_info"
>
Root enabled. Safety Net (Android Pay) will NOT work
</string>
<string
name=
"root_disabled"
>
Root disabled
</string>
<string
name=
"root_disabled_info"
>
Safety Net (Android Pay) should work, but no root temporarily\nYou might need to manually add a card in Android Pay app to refresh the root status of AP
</string>
<string
name=
"root_system"
>
Magisk Incompatible Root Detected
</string>
<string
name=
"root_system_info"
>
Root improperly installed. Safety Net (Android Pay) will NOT work, and impossible to toggle.
</string>
<string
name=
"selinux_error_info"
>
SELinux Status Unknown
</string>
<string
name=
"selinux_enforcing_info"
>
SELinux is enforced
</string>
<string
name=
"selinux_permissive_info"
>
SELinux is permissive\nOnly turn off SELinux if necessary!
</string>
<string
name=
"selinux_samsung_info"
>
Samsung need custom kernel for switching SELinux status!
</string>
<!--Module Fragment-->
<string
name=
"no_info_provided"
>
(No info provided)
</string>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment