顯示具有 Android 標籤的文章。 顯示所有文章
顯示具有 Android 標籤的文章。 顯示所有文章

2013年9月23日 星期一

Add command in init rc in Android

I want to run a conditional script commands during boot-up and the place to add it looks like better in init.rc or init.xxx.rc, where xxx stands for a platform name. init files have their own language and thus don't take conditional script language. Instead of directly putting those commands inside an init file, I wrote those commands in a seperate script file and call it as an service in init.rc.

(1) gemtek_prop_check.sh

#!/system/bin/sh
if [ -f /data/gemtek.prop ]
then
        /system/busybox/bin/echo "gemtek.prop found!"
else
        /system/busybox/bin/cp /gemtek_default.prop /data/gemtek.prop
        /system/busybox/bin/chmod 666 /data/gemtek.prop
        /system/busybox/bin/echo "gemtek.prop is re-generated!"
fi


- must contain  #!/system/bin/sh
- must use absolute path

(2) init.rc

service console /system/bin/sh
    class core
    console
    disabled
    user root
    group log

service gtk_prop_check /gemtek_prop_check.sh
    class core
    oneshot


- don't really know if the sequence matters, but I put it behind console service anyway.

(3) build/tools/post_process_props.py
 Where a custom prop file can be added. In my case, gemtek_default.prop is added.

(4) build/core/build/core/Makefile
Where give the command to generate gemtek_default.prop


Reference links
http://blog.csdn.net/silvervi/article/details/6315888
https://github.com/android/platform_system_core/blob/master/init/readme.txt

2013年9月17日 星期二

Check existency and write file in Android


     File file = new File(filePath);  
     if (!file.exists()){
         Log.d(TAG, "Create " + filePath);
         try {    
          file.createNewFile();
          OutputStreamWriter pswtr = new OutputStreamWriter(new FileOutputStream(file));
             for (int i= 0;i < 8; i++) {
                   pswtr.write("hotkey"+i+"=com.android.settings\n");
             }      
                pswtr.close();
         }
         catch (FileNotFoundException e) {
             Log.e(TAG , "Got exception " + e);
         }
         catch (IOException e) {
             Log.e(TAG , "Got exception " + e);
         }             
     }

2013年9月16日 星期一

[hi3716c] Add custom prop file

build/core/Makefile
Add:
(1)
# -----------------------------------------------------------------
# gemtek.prop
INSTALLED_GTK_PROP_TARGET := $(TARGET_ROOT_OUT)/gemtek_default.prop
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_GTK_PROP_TARGET)

$(INSTALLED_GTK_PROP_TARGET):
        @echo Target buildinfo: $@
        @mkdir -p $(dir $@)
        $(hide) echo "#Gemtek-defined properties" > $@;
        build/tools/post_process_props.py $@

(2)
cat $(INSTALLED_GTK_PROP_TARGET) > $(TARGET_RECOVERY_ROOT_OUT)/gemtek_default.prop

build/CleanSpec.mk
Add:
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/gemtek_default.prop)

build/tools/post_process_props.py
Add:
(1)
 Put the modifications that you need to make into the /data/gemtek.prop into this
# function. The prop object has get(name) and put(name,value) methods.
def mangle_gtk_prop(prop):
    prop.put("hotkey0", "com.android.settings")
    prop.put("hotkey1", "com.android.settings")
    prop.put("hotkey2", "com.android.settings")
    prop.put("hotkey3", "com.android.settings")
    prop.put("hotkey4", "com.android.settings")
    prop.put("hotkey5", "com.android.settings")
    prop.put("hotkey6", "com.android.settings")
    prop.put("hotkey7", "com.android.settings")

(2)
elif filename.endswith("/gemtek_default.prop"):
    mangle_gtk_prop(properties)


Then check it in init.rc and copy the gemtek_default.prop to /data if gemtek.prop doesn't exist.
gemtek.prop is the copy that user could modify on.

2013年9月12日 星期四

get/set properties in Android

I tried to use setprop/getprop shell commands to test if I could set/get a defined key to a system's permanent storage, but it didn't do that instead the key is gone after reboot. I then turned to another solution after researching the internet. I create a properties file in the data folder and read it into a Properties object. I can operate on  the object and save back the properties after finish. The following is the snippet I wrote after referring to the red link in the reference links below:

public class HotkeyListAdapter extends ArrayAdapter<Object> {
    int total_hotkey_count = 8;
    Context context;
    static String filePath = "/data/hotkey.properties";
    String hotkey_map[] = {
        "A", "B", "C", "D", "E", "F", "G", "H"
    };
    static String targetApp = "com.android.settings";   
    static String TAG = "HotkeyListAdapter";

    public HotkeyListAdapter(Context context, int resourceId) {
        super(context, resourceId);
        this.context = context;
    }

    @Override
    public int getCount() {
        return total_hotkey_count;
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    static Properties loadPropties() throws IOException {
        Properties prop = new Properties();
        try {
            InputStream fileStream = new BufferedInputStream(new FileInputStream(filePath));
            prop.load(fileStream);
            fileStream.close();
        } 
     catch (FileNotFoundException e) {
            Log.e(TAG , "Got exception " + e);
        }
        return prop;
    }


    static void storePropties(Properties prop) throws IOException {
        try {
            OutputStream fileStream = new BufferedOutputStream(new FileOutputStream(filePath));
            prop.store(fileStream, "Hotkey mappings");
            fileStream.close();
        } 
     catch (FileNotFoundException e) {
            Log.e(TAG , "Got exception " + e);
        }
    }


    static String getProperties(String key) {
     Properties prop;
        try {
            prop = loadPropties();
         return prop.getProperty(key, "NA");
        }
     catch (IOException e) {
            Log.e(TAG, "Exception", e);
        }
     return "NA";
    }

    static void setProperties(String key, String value) {
     Properties prop;   
        try {
         prop = loadPropties();
         prop.setProperty(key, value);
            storePropties(prop);
        }
     catch (IOException e) {
            Log.e(TAG, "Exception", e);
        }
     return;   
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView appImage;
     TextView keyName, appName;   
     Intent hotkey_intent;
     List<ResolveInfo> resolveinfo_list;
     PackageManager pm = context.getPackageManager();
        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.hotkey_list_row, null);    
        }   

        appImage = (ImageView) convertView.findViewById(R.id.hotkey_app_image);
     appName = (TextView) convertView.findViewById(R.id.hotkey_app_name);
     keyName = (TextView) convertView.findViewById(R.id.hotkey_name);

        /* Retrieve APP info */
     targetApp = getProperties("hotkey"+position);   
     Log.d(TAG, targetApp);
   
        hotkey_intent = new Intent("android.intent.action.MAIN");
        hotkey_intent.addCategory("android.intent.category.LAUNCHER");
     resolveinfo_list = context.getPackageManager().queryIntentActivities(hotkey_intent, 0);
        for(ResolveInfo info:resolveinfo_list){
                 if(info.activityInfo.packageName.equalsIgnoreCase(targetApp)){    
                  ApplicationInfo ai;
                     appImage.setImageDrawable(info.activityInfo.loadIcon(pm));
            try {
                         ai = pm.getApplicationInfo(info.activityInfo.packageName, 0);
                     }
            catch (final NameNotFoundException e) {
                         ai = null;
                     }
            appName.setText((ai == null ? "not found" : pm.getApplicationLabel(ai)));
            keyName.setText(hotkey_map[position]);
                     break;
                 }
        }
       
        return convertView;
    }
}


public class HotkeyAppListDialog extends DialogFragment {
    private AlertDialog mDialog;
    private static HotkeyListAdapter hotkey_list_adapter;
    private static int hotkey_num;
   
    public static HotkeyAppListDialog newInstance(int position, HotkeyListAdapter adapter) {
        HotkeyAppListDialog frag = new HotkeyAppListDialog();
     hotkey_list_adapter = adapter;
     hotkey_num = position;
        return frag;
    }
   
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
     HotkeyAppListAdapter adapter = new HotkeyAppListAdapter(getActivity(), R.layout.hotkey_app_list_row);
     ListView appList = new ListView(getActivity());   
     appList.setAdapter(adapter);
     appList.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
     appList.setOnItemClickListener(new OnItemClickListener() {   
            public void onItemClick(AdapterView<?> parent,View view,int position,long id) {
          HotkeyListAdapter.setProperties("hotkey"+hotkey_num, (String)view.getTag());
          hotkey_list_adapter.notifyDataSetChanged();
                mDialog.cancel();
            }
        });
        builder.setView(appList);
        builder.setTitle(R.string.hotkey_app_list_title);  
     mDialog = builder.create();
        return mDialog;
    }
}


Reference links
http://stackoverflow.com/questions/14450714/how-do-i-read-a-property-from-project-properties-or-local-properties
Architecture
http://rxwen.blogspot.tw/2010/01/android-property-system.html
worth reading
http://hi.baidu.com/seucrcr/item/2b988c570cb63c9208be1778
http://bininda.com/blog/tag/android/


2013年9月11日 星期三

dump stack trace in Java

Thread.dumpStack()

Reference links
http://stackoverflow.com/questions/1069066/get-current-stack-trace-in-java

Refresh previous View from a Dialog

When returning from a Dialog, if want to refresh a previous View, say a list, the following code shows the way:

public class HotkeyAppListDialog extends DialogFragment {
    private AlertDialog mDialog;
    private static HotkeyListAdapter hotkey_list_adapter;

    public static HotkeyAppListDialog newInstance(int position, HotkeyListAdapter adapter) {
        HotkeyAppListDialog frag = new HotkeyAppListDialog();
        hotkey_list_adapter = adapter;
        return frag;
    }
   
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        HotkeyAppListAdapter adapter = new HotkeyAppListAdapter(getActivity(), R.layout.hotkey_app_list_row);
        ListView appList = new ListView(getActivity());  
        appList.setAdapter(adapter);
        appList.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        appList.setOnItemClickListener(new OnItemClickListener() {  
            public void onItemClick(AdapterView<?> parent,View view,int position,long id) {
                Log.d("HotkeyAppListDialog", "position:"+position);
                hotkey_list_adapter.notifyDataSetChanged();
                mDialog.cancel();
            }
        });
        builder.setView(appList);
        builder.setTitle(R.string.hotkey_app_list_title);  
        mDialog = builder.create();
        return mDialog;
    }
}
 

public class HotkeySettings extends ListFragment {
    private HotkeyListAdapter hla;
   
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {                    
        View root = inflater.inflate(R.layout.hotkey_main, container, false);                    
        ListView list = (ListView) root.findViewById(android.R.id.list);
        hla = new HotkeyListAdapter(getActivity(), R.layout.hotkey_list_row);  
        hla.setNotifyOnChange(true);
        list.setAdapter(hla);
        return root;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        DialogFragment had = HotkeyAppListDialog.newInstance(position, hla);
        had.show(getActivity().getFragmentManager(), "hotkey app list");  
    }   
}


Reference links
http://stackoverflow.com/questions/15588538/android-listfragment-does-not-refresh

Return from a Dialog to a previous View

The following code shows how to return from a popped-out dialog to a previous view:

public class HotkeyAppListDialog extends DialogFragment {
    private AlertDialog mDialog;
    private static HotkeyListAdapter hotkey_list_adapter;

    public static HotkeyAppListDialog newInstance(int position, HotkeyListAdapter adapter) {
        HotkeyAppListDialog frag = new HotkeyAppListDialog();
        hotkey_list_adapter = adapter;
        return frag;
    }
   
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
     HotkeyAppListAdapter adapter = new HotkeyAppListAdapter(getActivity(), R.layout.hotkey_app_list_row);
     ListView appList = new ListView(getActivity());   
     appList.setAdapter(adapter);
     appList.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
     appList.setOnItemClickListener(new OnItemClickListener() {   
            public void onItemClick(AdapterView<?> parent,View view,int position,long id) {
          Log.d("HotkeyAppListDialog", "position:"+position);
          hotkey_list_adapter.notifyDataSetChanged();
                mDialog.cancel();
            }
        });
        builder.setView(appList);
        builder.setTitle(R.string.hotkey_app_list_title);  
        mDialog = builder.create();
        return mDialog;
    }
}


public class HotkeySettings extends ListFragment {
    private HotkeyListAdapter hla;
   
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {                    
        View root = inflater.inflate(R.layout.hotkey_main, container, false);                    
     ListView list = (ListView) root.findViewById(android.R.id.list);
     hla = new HotkeyListAdapter(getActivity(), R.layout.hotkey_list_row);   
     hla.setNotifyOnChange(true);
     list.setAdapter(hla);
        return root;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        DialogFragment had = HotkeyAppListDialog.newInstance(position, hla);
        had.show(getActivity().getFragmentManager(), "hotkey app list");   
    }    
}


Reference links
http://stackoverflow.com/questions/9429550/performing-onclick-action-on-listview-inside-a-dialog-box

2013年9月10日 星期二

java.lang.IllegalStateException:The specifiedchildalready has a parent. Youmust call removeView() on the child's parent first

public class HotkeyAppListDialog extends DialogFragment {

    public static HotkeyAppListDialog newInstance(int position) {
        HotkeyAppListDialog frag = new HotkeyAppListDialog();
        return frag;
    }
   
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        HotkeyAppListAdapter adapter = new HotkeyAppListAdapter(getActivity(), R.layout.hotkey_app_list_row);
---------------------------------------------------------------------
Where causes the exception !

        View list = getActivity().getLayoutInflater().inflate(R.layout.hotkey_app_list, null);                    
        ListView appList = (ListView) list.findViewById(R.id.app_list_view);
The correct way to create a ListView instance here to avoid re-attach parent !

        ListView appList = new ListView(getActivity());    
---------------------------------------------------------------------
        appList.setAdapter(adapter);   
        builder.setView(appList);
        builder.setTitle(R.string.hotkey_app_list_title);  
        return builder.create();
    }
}

public class HotkeySettings extends ListFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {                    
        View root = inflater.inflate(R.layout.hotkey_main, container, false);                    
        ListView list = (ListView) root.findViewById(android.R.id.list);
        HotkeyListAdapter hla = new HotkeyListAdapter(getActivity(), R.layout.hotkey_list_row);   
        list.setAdapter(hla);
        return root;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        DialogFragment had = HotkeyAppListDialog.newInstance(position);
        had.show(getActivity().getFragmentManager(), "hotkey app list");   
    }    
}

Reference links
http://stackoverflow.com/questions/13504781/custom-listview-inside-a-dialog-in-android

Use Bundle and static contructor wrapper to pass data

There's a way to define kinda a static custom constructor wrapper to pass in arguments to the real constructor :

public class HotkeyAppListDialog extends DialogFragment { 
    public static HotkeyAppListDialog newInstance(int position) {
        HotkeyAppListDialog frag = new HotkeyAppListDialog();
        Bundle args = new Bundle();
        args.putInt("position", position);
        frag.setArguments(args);
        return frag;
    }
   
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int position = getArguments().getInt("position");   
        ...
    }
}

public class HotkeySettings extends ListFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {                    
...
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        DialogFragment had = HotkeyAppListDialog.newInstance(position);
        had.show(getActivity().getFragmentManager(), "hotkey app list");   
    }    
}


2013年8月28日 星期三

[Hi3716c] Fix IR power key wake up mechanism

Some files worth noticing...
* device/hisilicon/godbox/driver/sdk/msp/ecs/drv/ir/ir_s2/ir_drv.c
IR driver. It handles IRQ.

* device/hisilicon/godbox/driver/sdk/msp_base/ecs/drv/include/ir.h
 IRQ no of IR is defined here

* kernel/arch/arm/mach-godbox/include/mach/irqs.h
Some IRQs are defined here

* device/hisilicon/godbox/driver/sdk/msp/ecs/drv/ir/ir_s2/hiir_ir2.h
Handles raw-linux_key_code mapping and works as API for the IR driver

* device/hisilicon/godbox/driver/sdk/sample/pmoc/sample_pmoc.c
A sample code to test IR and other ways to wake up the device

* device/hisilicon/godbox/driver/sdk/msp/ecs/drv/c51/drv_c51.c
MCU driver. MCU handles wake-up job after cpu power is down. The IR module decodes the infrared signals and then sends interrupts to MCU

* device/hisilicon/godbox/driver/sdk/msp/ecs/api/hi_unf_pm.c
A wrapped API to access MCU driver

* framework/base/core/jni/standby_wakeup.c
Hooked to the underlying HI_UNF_PM MCU driver wrapper APIs. It actually sets wake-up mode a particular power key code

* framework/base/service/jni/com_android_server_AlarmManagerService.cpp
android_server_AlarmManagerService_setWakeUp() body is here, which calls HI_Standby_Wakeup() in standby_wakeup.c

* framework/base/service/jni/com_android_server_PowerManagerService.cpp
android_server_PowerManagerService_nativeSetWakeup() body is here, which calls  android_server_AlarmManagerService_setWakeUp() in com_android_server_AlarmManagerService.cpp

* framework/base/services/java/com/android/server/PowerManagerService.java
goToSleep() body is here, which calls nativeSetWakeup() defined in com_android_server_PowerManagerService.cpp, which points to  android_server_PowerManagerService_nativeSetWakeup()

What happens when a power key is detected for standby mode to proceed to set the wake-up key attribute from the point of view of Android:

interceptKeyBeforeQueueing(), frameworks/base/services/jni/com_android_server_InputManager.cpp
 |
V
interceptKeyBeforeQueueing(), frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
 |
V
handleInterceptActions(), frameworks/base/services/jni/com_android_server_InputManager.cpp
 |
V
goToSleep(), framework/base/services/java/com/android/server/PowerManagerService.java
 |
V
nativeSetWakeup(),  framework/base/service/jni/com_android_server_PowerManagerService.cpp
 |
V
android_server_AlarmManagerService_setWakeUp(),  framework/base/service/jni/com_android_server_AlarmManagerService.cpp
 |
V
HI_Standby_Wakeup(),  framework/base/core/jni/standby_wakeup.c

Related shell commands...
* Trigger standby mode
echo MODE > /sys/power/state
MODE: on, standby, mem

* Test standby/wakeup functions
sample_pmoc

The fix:
Modify the wake-up value from 0x639cff00 to 0xfd024db2 in  HI_Standby_Wakeup().


2013年8月23日 星期五

Store perminant data in Android

There are basically 3 ways to save data in Android. The one I'm going to talk about here is SharedPreferences method. Before expanding the usage, be aware of that  SharedPreferences method does not apply across multiple processes.The following is the snippet:

import android.content.SharedPreferences;
...
private SharedPreferences mKeyAppMap;
...
mKeyAppMap = mContext.getSharedPreferences(HOTKEY_PREF_NAME, 0);
...
String AppName = mKeyAppMap.getString(targetName,"none"); <-- Get data
...

SharedPreferences.Editor editor = mKeyAppMap.edit(); <-- Save data

editor.putString(key, appName);
editor.commit();

Reference links
http://www.ozzysun.com/2010/11/android.html
http://developer.android.com/training/basics/data-storage/index.html

Implementing Broadcasting in Android

The snippet:
---------------------------- Receiver body --------------------------------------------
private String ACTION_CUSTOM_HOTKEY = "android.internal.policy.impl.PhoneWindowManager";

BroadcastReceiver mDockReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
...
            else if (ACTION_CUSTOM_HOTKEY.equals(intent.getAction())) {
                String key = intent.getExtras().getString("whichkey");
                String appName = intent.getExtras().getString(key);
                Log.d(TAG, "write pair " + key + "-" + appName);
                SharedPreferences.Editor editor = mKeyAppMap.edit();
                editor.putString(key, appName);
                editor.commit();
            }
 ...
    };

---------------------------- Register the receiver and filter ----------------------------
IntentFilter filter = new IntentFilter();
...

filter.addAction(ACTION_CUSTOM_HOTKEY);
Intent intent = context.registerReceiver(mDockReceiver, filter);
if (intent != null) {
       // Retrieve current sticky dock event broadcast.
       mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
               Intent.EXTRA_DOCK_STATE_UNDOCKED);

}
...
-----------------------------------------------------------------------------------
Instead of using registerReceiver, one could also add the filter it in the manifest file for permitted intent action.
-----------------------------------------------------------------------------------
----------------------- Send broadcasting message -------------------------------
Intent intent = new Intent();
intent.setAction("android.internal.policy.impl.PhoneWindowManager");
intent.putExtra("whichkey", currentTab);
intent.putExtra(currentTab, entry.info.packageName);
getActivity().sendBroadcast(intent);

Reference links
http://stackoverflow.com/questions/3907713/how-to-send-and-receive-broadcast-message
http://www.techotopia.com/index.php/Android_Broadcast_Intents_and_Broadcast_Receivers
http://www.ozzysun.com/2010/11/android.html

2013年8月19日 星期一

[Code trace] Android Irda input key mapping


[Irda key mapping to Anroid layer]
Take color key, red, as the example to illustrate the flow to add a new key
==================================================================
- device/hisilicon/godbox/driver/sdk/msp/ecs/drv/ir/ir_s2/hiir_ir2.h
Obtain the keycode of red key and define a MACRO as below:
#define NEC_IR_KEY_RED                                  0xcd
...
Maps Irda keycode to keylabel RED 398:
{NEC_IR_KEY_RED,     KEY_RED},
-------------------------------------------------------------------------------------------
- device/hisilicon/godbox/prebuilt/Vendor_0001_Product_0001.kl
key 398         RED
# key 398 "KEY_RED"
-------------------------------------------------------------------------------------------
211 is the event value retrieved through onKeyDown() in Android.

- external/webkit/Source/WebKit/android/plugins/ANPKeyCodes.h
kRed_ANPKeyCode = 211,

- frameworks/base/native/include/android/keycodes.h
AKEYCODE_RED = 211,

- frameworks/base/core/java/android/view/KeyEvent.java
public static final int KEYCODE_RED     = 211;

- frameworks/base/core/res/res/values/attrs.xml
<enum name="KEYCODE_RED" value="211" />
-------------------------------------------------------------------------------------------
- frameworks/base/include/ui/KeycodeLabels.h
Maps keylabel RED 398 to 211
{ "RED", 211 },
-------------------------------------------------------------------------------------------
- frameworks/base/libs/ui/Input.cpp
case AKEYCODE_RED:

[Code trace] power management (standby/suspend/resume) mechanism in Android & Linux

[INPUT MNGR]
frameworks/base/services/jni/com_android_server_InputManager.cpp
NativeInputManager::handleInterceptActions() :
dispatch keys to users or filter them as special event key like power control...

handleInterceptActions() callbacks to PowerManagerService goToSleep() for putting to sleep, to another function to wake it up, or passing keys to users

Code flow:
interceptKeyBeforeQueueing(), frameworks/base/services/jni/com_android_server_InputManager.cpp
 |
V
interceptKeyBeforeQueueing(), frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
 |
V
handleInterceptActions(), frameworks/base/services/jni/com_android_server_InputManager.cpp

[PWR MNGR CODE FLOW]
frameworks/base/core/java/android/os/PowerManager.java - API for APPS
 |
V
frameworks/base/services/java/com/android/server/PowerManagerService.java - core
 |
V
frameworks/base/core/java/android/os/Power.java - JNI


Reference links
http://blog.csdn.net/tommy_wxie/article/details/7208633
http://3y.uu456.com/bp-f823387031b76sce0s081439-1.html 

Very good illustration for the architecture of PM in Android
http://www.kandroid.org/online-pdk/guide/power_management.html

This is a very handy illustration on standby/wake framework from top to bottom
http://blog.csdn.net/lizhiguo0532/article/details/6453595

Tells different configuring opions for /sys/power/state
http://www.mjmwired.net/kernel/Documentation/power/states.txt


Start an APP from another APP in Android

The following is the snippet for testing:

import android.content.pm.ResolveInfo;
import java.util.List;


if (keyCode == KeyEvent.KEYCODE_GREEN) {
             Log.d(TAG, "green key is triggered");
             Intent hotkey_intent = new Intent("android.intent.action.MAIN");
             hotkey_intent.addCategory("android.intent.category.LAUNCHER");

             List<ResolveInfo> resolveinfo_list = mContext.getPackageManager().queryIntentActivities(hotkey_intent, 0);

             for(ResolveInfo info:resolveinfo_list){
                 Log.d(TAG, info.activityInfo.packageName);
                 if(info.activityInfo.packageName.equalsIgnoreCase("com.android.settings")){
                     hotkey_intent.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name));
                     hotkey_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                     mContext.startActivity(hotkey_intent);
                     break;
                 }
             }
         }


settings APP is brought up when GREEN key is pressed.

Action and category seem to work as filters for the activities it searches. In order to get a full list of APPs, I perhaps have to change them.

Reference links
http://stackoverflow.com/questions/2780102/open-another-application-from-your-own-intent

[Code trace] Android Irda Input key handling

The purpose is to find out where some globally functioned keys are handled, like power key, which is specially handled within handleInterceptActions() after interceptKeyBeforeQueueing() is called, and a key works to change the TV display format wherever you are. The goal however, is to add a set of 4 hot keys each of which is a shortcut to a certain APP.

remote control key : UP
------------------------------------------------------------------------------------------------
D/InputReader( 1417): BatchSize: 2 Count: 2
D/InputReader( 1417): Input event: device=1 type=0x0001 scancode=0x0067 keycode=0x0013 value=0x00000001 flags=0x00000000
D/InputReader( 1417): Input event: device=1 type=0x0000 scancode=0x0000 keycode=0x0000 value=0x00000000 flags=0x00000000

D/WindowManager( 1417): UP key is pressed/released
D/KeyEvent-JNI( 1417): android_view_KeyEvent_recycle...
D/InputManager-JNI( 1417): NativeInputManager::handleInterceptActions
D/KeyEvent-JNI( 1417): android_view_KeyEvent_recycle...
D/KeyEvent-JNI( 1417): android_view_KeyEvent_recycle...

------------------------------------------------------------------------------------------------
                                 (1)                   (2)
remote control key <-> scancode <-> keycode
        0xca                        0x67              0x13

remote control key :  device/hisilicon/godbox/driver/sdk/msp/ecs/drv/ir/ir_s2/hiir_ir2.h
keycode :  frameworks/base/native/include/android/keycodes.h
scancode : device/hisilicon/godbox/prebuilt/Vendor_0001_Product_0001.kl

Mappings:
(1) device/hisilicon/godbox/driver/sdk/msp/ecs/drv/ir/ir_s2/hiir_ir2.h
(2) frameworks/base/include/ui/KeycodeLabels.h

The following code handles a universal key event - KEYCODE_MORE(0x498)
[Window Manager]
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
interceptKeyBeforeQueueing()

After finding out the place, the idea is then to handle these 4 hot keys here in interceptKeyBeforeQueseing() and jump to the corresponding APP designated.

Reference links
http://www.hovercool.com/en/Special:History?topicVersionId=767&topic=Input%E4%BA%8B%E4%BB%B6%E6%B5%81%E7%A8%8B
http://blog.csdn.net/eastmoon502136/article/details/7697434