Sunday, January 17, 2021

[osx command] file or folder monitoring

1. command fswatch [file or folder to monitor] | xargs -I {} echo $(date) {} >> [log file name] 2. explanation fswatch : file monitoring program xargs -I {} [command] : replace {} with input string echo [string] >> [file name] : add string to file

Wednesday, July 3, 2019

Android OpenGL ES Setting for Build up

To generate more powerful graphic effect, OpenGL ES(OpenGL for Embeded System) provides modern graphic processing api.

I will make a simple GLSurfaceView(pre-defined view class to use opengl in android) and Renderer to visualize effect only using fragment shader. Once I build this successfully, I can refer some interesting glsl codes in online like glsl sandbox or shader frog.

1. Manifest Setting

I will use gles 3.1 version. Way to checking of supported version is in developer docs.

<uses-feature android:glEsVersion="0x00030001" android:required="true" />
<application ... />

2. Custom GLSurfaceView Class

class MySurfaceView(context:Context) :GLSurfaceView(context) {
  private lateinit var renderer:MyRenderer
override fun setRenderer(renderer: Renderer) {
   super.setRenderer(renderer)
   this.renderer = renderer as MyRenderer
 }
}

3. Custom Renderer

Most of Renderer's codes are boilerplate code. Shader compile and attach processes are explained in dev docs. I will add tiny additional code.

class MyRenderer(context:Context):GLSurfaceView.Renderer{
 ...
 private var hMouse = 0
 private var hTime = 0
 private var hResolution = 0
 private var width = 0
 private var height = 0
 var mouseX : Float = 0f
 var mouseY : Float = 0f
 ...
 override fun onDrawFrame(gl: GL10?) {
  ...
  GLES31.glClear(GLES31.GL_DEPTH_BUFFER_BIT or GLES31.GL_COLOR_BUFFER_BIT)
  val time = SystemClock.uptimeMillis() % 10000L
  GLES31.glUniform1f(hTime,(time/1000f))
  GLES31.glUniform2f(hResolution,this.width.toFloat(),this.height.toFloat())
  GLES31.glUniform2f(hMouse,-1f+(2*this.mouseX/this.width),1f-(2*this.mouseY/this.height))
  GLES31.glUniformMatrix4fv(hScale,1,false, mScale,0)
  ...
 }
 override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
  ...
  this.width = width
  this.height = height
  ...
 }
 override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
  ...
  hTime = GLES31.glGetUniformLocation(hProgram,"time")
  hResolution = GLES31.glGetUniformLocation(hProgram,"resolution")
  hMouse = GLES31.glGetUniformLocation(hProgram,"mouse")
  ...
 }

Almost done. Override onTouchEvent in view class to pass the mouse location to renderer(mouseX,mouseY variables at above code).

override fun onTouchEvent(event: MotionEvent): Boolean {
  this.renderer.mouseX = event.x
  this.renderer.mouseY = event.y
  return super.onTouchEvent(event)
 }

4. etc

For vertex Shader, Any shape is possible. To see the fragment shader code's effect fully, use Square Shape.

And find some code in online, test and make own code.

Tuesday, June 25, 2019

Grid UI Launcher by ConstraintLayout

When we are trying to build a custom launcher, we could think about some layout options like grid, scroll view... In this post, we are implementing the grid layout by android default constraint layout.

1. Draw GuideLines

constraintlayout with grid guideline

ConstraintLayout containing 5x4 grid with 6x5 guideline

guideline attribute percent

Set constraint like the above picture(percent 0.2, 0.4, etc...) to each of vertical, horizontal lines.

2. Grid Element View

Make Custom Element View composed of upper-side Icon image, lower-side app name.

class AppIconView(context:Context) : View(context) {
 private val paint = Paint()
 private val iconDrawRegion = Rect()
 private lateinit var label: String
 lateinit var icon: Bitmap
 lateinit var packageName: String

 init{
  paint.setTypeface(Typeface.create(Typeface.DEFAULT,Typeface.NORMAL))
  paint.setAntiAlias(true)
 }

 fun setAppInfo(packageName:String, label:String ,icon:BitmapDrawable){
  this.packageName = packageName
  this.label = label
  this.icon = icon.bitmap
 }

 override fun onDraw(canvas: Canvas) {
  paint.textSize = width/7f
  val paddingW = width/5
  iconDrawRegion.set(paddingW,paddingW,width-paddingW,width-paddingW)
  canvas.drawBitmap(icon,null,iconDrawRegion,paint)

  val textDrawSize = paint.measureText(label)
  canvas.drawText(label,(width-textDrawSize)/2f,height-(2*paint.textSize),paint)
 }

Above code would make a view seems like simple and conventional launcher. For launcher's other behaviors such as drag and drop, We need some additional code that would also be covered by later post.

3. Compose Simple Activity

 guideLineV = arrayOf(R.id.guide_v0,R.id.guide_v1,R.id.guide_v2,R.id.guide_v3,R.id.guide_v4)  guideLineH = arrayOf(R.id.guide_h0,R.id.guide_h1,R.id.guide_h2,R.id.guide_h3,R.id.guide_h4,R.id.guide_h5)  layout = findViewById(R.id.my_constraint_layout)
 var app_count =0
 val filter = Intent(Intent.ACTION_MAIN)
 filter.addCategory(Intent.CATEGORY_LAUNCHER)
 val allApps = packageManager.queryIntentActivities(filter, 0)
 val cs = ConstraintSet()
 for (info in allApps) {
  val da = AppIconView(this).apply {
   id = View.generateViewId()
   setAppInfo(info.activityInfo.packageName, info.loadLabel(packageManager).toString() ,info.activityInfo.loadIcon(packageManager) as BitmapDrawable)
   
  val col = app_count % 4
  val row = app_count / 4
  if(row>4){ // Because we didn't implement tab for multiple appPage, exceeded apps would be just skipped
   break
  }
  apps[row][col] = da
  da.col = col
  da.row = row
  layout.addView(da)
  cs.connect(da.id,ConstraintSet.START,guideLineV[col],ConstraintSet.START)
  cs.connect(da.id,ConstraintSet.END,guideLineV[col+1],ConstraintSet.START)
  cs.connect(da.id,ConstraintSet.TOP,guideLineH[row],ConstraintSet.TOP)
  cs.connect(da.id,ConstraintSet.BOTTOM,guideLineH[row+1],ConstraintSet.TOP)
  app_count++
 }
 cs.applyTo(layout)

I referenced this article for getting installed apps for custom launcher. We can insert above code to oncreate method, and it's done.

4. Result

Now, Our view would be seems like below.

android launcher grid layout

Friday, June 14, 2019

When you delete project in android studio by mistake

Few minutes ago, I had almost been dying after deleting my project by mistake, I tried some third-party recovery softwares. Though it had restored some files(.gitignore, .class, etc..), really most-helpful files(in my case, kotlin files) were not recovered.

Luckily, I found a solution before shutdown the android studio then it saved me to recover the complete project with all files.

If you delete a project in android studio and are still remaining the studio open, you can recover your project.

On Menubar, VCS -> Local History -> Show History.

Then window like below picture would be shown.

how to recover misdelete by android studio history

(Because I had deleted the project after creating new-project, In history it was recorded as EXTERNAL CHANGE)

Right-click the log, and click revert. it's done.

I hope it would save you.

Thursday, June 13, 2019

Sc create, devcon install Difference

In Window Driver, There are the pnp(plug-and-play) type drivers, and the non-pnp type drivers. When non-pnp type drivers have once installed, they would be supposed to be used continuously without uninstall. On the other hand, pnp drivers are namely for easy plug-in(out). For two different types of driver, two-ways of installing exists.

1. PNP Driver

sc create [service name] binpath=[c:\...] type=[kernel]

sc start [service name]

sc stop [service name]

Because sc command is used for creating wide-range window-services, this is Not used only for the device driver. But this is also useful for the device driver.

2. Non PNP Driver

devcon install [filename.inf] [hardware id]

Saturday, June 8, 2019

When Devcon install command failed on VM

I was missing two basic points for installing driver on virtualbox because I never experienced developing driver before.

1. Test-certificate driver could only be installed after recovery boot. ( on 32bit window it could be simple, see this )

Settings -> Update & Security -> Recovery tab -> Restart now -> Trouble Shoot ->
Advanced Options -> Startup Settings -> Restart -> F7

hardware id location in inf file

Red-marked place should be replaced with real hardware id. it can be checked in device manager.

Way to call Default Launcher by Custom Launcher

It would not be guaranteed to work always properly, though it works well in my case

1. manifest example

<activity ... android:label="@string/app_name" android:name=".activities.LauncherActivity" android:theme="@style/FullscreenTheme">
 <intent-filter>
  <action android:name="android.intent.action.MAIN"/>
  <category android:name="android.intent.category.HOME"/>
  <category android:name="android.intent.category.DEFAULT"/>
 </intent-filter>
</activity>

2. custom launcher code example

var launcher_list = packageManager.queryIntentActivities(Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_HOME) },0)
val name = ComponentName(
 //expecting first element of launchers be the default
 launcher_list[0].activityInfo.packageName,
 launcher_list[0].activityInfo.name
)

val i = Intent(Intent.ACTION_MAIN)
i.addCategory(Intent.CATEGORY_LAUNCHER)
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
i.setComponent(name)

startActivity(i)
finish()

[osx command] file or folder monitoring

1. command fswatch [file or folder to monitor] | xargs -I {} echo $(date) {} >> [log file name] ...