トラッキング コード

7/28/2013

About AppOps in Android 4.3

Android 4.3 added "AppOps" whitch is like permission manager.


Points


  • added AppOpsManager, AppOpsService in the frameworks(Java Layer).
  • If you would like to use "AppOps", you can called getSystemService(Context.LAYOUT_INFLATER_SERVICE).
  • Each "Service" in frameworks decide to run operation, by obtaining a setting from the AppOpsService,
If you want to know more info, you should do grep "AppOpsManager.MODE_ALLOWED / MODE_IGNORED" in AOSP.




Create "AppOpsService" instance

AppOpsService is created in ActivityManagerService's constructor.

    private ActivityManagerService() {
        File systemDir = new File(dataDir, "system");
            :
        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
            :
    }



Setting data of AppOpsManager

Setting data of AppOps is saved to xml file. Xml file is named "appops.xml". It is saved under the System directory.

public class AppOpsService extends IAppOpsService.Stub {
    public AppOpsService(File storagePath) {
        mFile = new AtomicFile(storagePath);
        mHandler = new Handler();
        readState();
    }

    void readState() {

    }
    void writeState() {

    }
}

Ckeck it

You should check many source in AOPS(android-4.3_r2.1).
Settings application
packages/apps/Settings/src/com/android/settings/applications
- AppOpsCategory.java
- AppOpsDetails.java
- AppOpsState.java
- AppOpsSummary.java


Frameworks
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/AppOpsManager.java
frameworks/base/services/java/com/android/server/AppOpsService.java
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java


12/12/2012

How to use ActivityLifecycleCallbacks in Application Class

Do you want to add same code in all your ActivityLifeCycle?
You must use ActivityLifecycleCallbacks.

ActivityLifecycleCallbacks is interface of Application.class.
Can handle the called lifeCycle of Activity.


Sample code:
public class MyApplication extends Application {

    @Override
 public void onCreate (){
  super.onCreate();
  registerActivityLifecycleCallbacks(new MyActivityLifecycleCallbacks());
 }
 
    @Override
    public void onTerminate (){
     super.onTerminate();
    }
    
    @Override
    public void onConfigurationChanged (Configuration newConfig){
     super.onConfigurationChanged(newConfig);
    }
    
    private static final class MyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {

  public void onActivityCreated(Activity activity, Bundle bundle) {
   Log.e("","onActivityCreated:" + activity.getLocalClassName());
  }

  public void onActivityDestroyed(Activity activity) {
   Log.e("","onActivityDestroyed:" + activity.getLocalClassName());
  }

  public void onActivityPaused(Activity activity) {
   Log.e("","onActivityPaused:" + activity.getLocalClassName());
  }

  public void onActivityResumed(Activity activity) {
   Log.e("","onActivityResumed:" + activity.getLocalClassName());
  }

  public void onActivitySaveInstanceState(Activity activity,
    Bundle outState) {
   Log.e("","onActivitySaveInstanceState:" + activity.getLocalClassName());
  }

  public void onActivityStarted(Activity activity) {
   Log.e("","onActivityStarted:" + activity.getLocalClassName());
  }

  public void onActivityStopped(Activity activity) {
   Log.e("","onActivityStopped:" + activity.getLocalClassName());
  }
    }
}

9/05/2012

How to use Camera Preview of Portrait

If Camera Preview's oientation is incorrect when the device is Portrait, you should read following developer's site.


http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)

Sample code:
 public void surfaceCreated(SurfaceHolder holder) {
      mCamera = Camera.open();
      setCameraDisplayOrientation();
 }

 private void setCameraDisplayOrientation(){
      int rotation = mWindowManager.getDefaultDisplay().getRotation();
      
      Camera.CameraInfo info = new Camera.CameraInfo();
      // camera id is ...
      Camera.getCameraInfo(0, info);
      int degrees = 0;
      switch (rotation) {
          case Surface.ROTATION_0: degrees = 0; break;
          case Surface.ROTATION_90: degrees = 90; break;
          case Surface.ROTATION_180: degrees = 180; break;
          case Surface.ROTATION_270: degrees = 270; break;
      }

      int result;
      if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
          result = (info.orientation + degrees) % 360;
          result = (360 - result) % 360;  // compensate the mirror
      } else {  // back-facing
          result = (info.orientation - degrees + 360) % 360;
      }
      mCamera.setDisplayOrientation(result);
 }

9/02/2012

How to handle "Screen ON/OFF and Keygurad"



You need to use BroadcastReceiver and IntentFilter.

  • Create BroadcastReceiver
  • Register BroadcastReceiver and IntentFilter
  • If you do not need, you must unregister.


Create BroadcastReceiver

If the device is Screen ON/OFF, Android frameworks call mReceiver#onReceive().

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                // Screen is off
                Log.e("", "ACTION_SCREEN_OFF");
            }
            else if (action.equals(Intent.ACTION_SCREEN_ON)) {
                // Intent.ACTION_USER_PRESENT will be broadcast when the screen
                // is
                // unlocked.

                // if API Level 16
                /*
                 * if(mKeyguard.isKeyguardLocked()){ // the keyguard is
                 * currently locked. Log.e("","ACTION_SCREEN_ON : locked"); }
                 */
                if (mKeyguard.inKeyguardRestrictedInputMode()) {
                    // the keyguard is currently locked.
                    Log.e("", "ACTION_SCREEN_ON : locked");
                }
                else {
                    // unlocked
                    Log.e("", "ACTION_SCREEN_ON : unlocked");
                }

            }
            else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                // The user has unlocked the screen. Enabled!
                Log.e("", "ACTION_USER_PRESENT");
            }

        }

    };


Register BroadcastReceiver and IntentFilter

Create IntentFilter with ACTION_SCREEN_ON(OFF), and register to use Activity(or Serivce)#registerReceiver().

        // get KeyGuardManager
        mKeyguard = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);

        // IntetFilter with Action
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
        intentFilter.addAction(Intent.ACTION_USER_PRESENT);// Keyguard is GONE

        // register BroadcastReceiver and IntentFilter
        registerReceiver(mReceiver, intentFilter);


Unregister

If you do not need, you must unregister.

        // register BroadcastReceiver and IntentFilter
        unregisterReceiver(mReceiver);

8/30/2012

Never be called Application#onTerminate()


I checked up that Application(not Activity) has module of handling "stopped / resumed".
There was no explicit modules that are called from the frameworks.


So, What is Application#onTerminate()? Where is called in frameworks?
Are described in the Android Developers.

http://developer.android.com/reference/android/app/Application.html#onTerminate()

This method is for use in emulated process environments. It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so.

This Module will be present for what?

I do "grep" in Android frameworks, it is called from ActivityThread.java.

                case EXIT_APPLICATION:
                    if (mInitialApplication != null) {
                        mInitialApplication.onTerminate();
                    }
                    Looper.myLooper().quit();
                    break;


When ActivityThread#scheduleExit() send message, this process is called.

2 module in ActivityManagerService.java is called ActivityThread#scheduleExit()。


private final boolean attachApplicationLocked(IApplicationThread thread, int pid)
final void trimApplications()

Cord in module.
                    if (app.pid > 0 && app.pid != MY_PID) {
                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
                                app.processName, app.setAdj, "empty");
                        Process.killProcessQuiet(app.pid);
                    } else {
                        try {
                            app.thread.scheduleExit();
                        } catch (Exception e) {
                            // Ignore exceptions.
                        }
                    }
If the following case to call ActivityThread#scheduleExit().
  • PID is under "0"
  • PID is MY_PID(= System Process)


When Application is same "System Process", called ActivityThread#scheduleExit().
So, It is not application of "same System Process"...

7/18/2012

Starting for Android JUnit Test

If you would like to publish application to Google Market, I recommend that you test.
Android has test framework which helping you to test .

Check develoer's site!!

http://developer.android.com/tools/testing/index.html
The Android framework includes an integrated testing framework that helps you test all aspects of your application and the SDK tools include tools for setting up and running test applications. Whether you are working in Eclipse with ADT or working from the command line, the SDK tools help you set up and run your tests within an emulator or the device you are targeting.
If you aren't yet familiar with the Android testing framework, start by reading Testing Fundamentals. For a step-by-step introduction to Android testing, try the Activity Testing Tutorial.

How to set up Project for eclipse:

http://developer.android.com/tools/testing/testing_android.html

7/01/2012

Phone mode or Tablet mode in Android 4.1 Jelly Bean?




Android 4.1 Jelly Bean has Phone UI Mode and Tablet UI Mode, so same ICS.
How to change Phone / Tablet in Android Frameworks ?

If you have Android SDK Api 16, you can notice source code!!

Definition of UI Mode

Check in PhoneWindowManager#setInitialDisplaySize.

\sources\android-16\com\android\internal\policy\impl\PhoneWindowManager.java

        // SystemUI (status bar) layout policy
        int shortSizeDp = shortSize
                * DisplayMetrics.DENSITY_DEFAULT
                / DisplayMetrics.DENSITY_DEVICE;

        if (shortSizeDp < 600) {
            // 0-599dp: "phone" UI with a separate status & navigation bar
            mHasSystemNavBar = false;
            mNavigationBarCanMove = true;
        } else if (shortSizeDp < 720) {
            // 600-719dp: "phone" UI with modifications for larger screens
            mHasSystemNavBar = false;
            mNavigationBarCanMove = false;
        } else {
            // 720dp: "tablet" UI with a single combined status & navigation bar
            mHasSystemNavBar = true;
            mNavigationBarCanMove = false;
        }

        if (!mHasSystemNavBar) {
            mHasNavigationBar = mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_showNavigationBar);
            // Allow a system property to override this. Used by the emulator.
            // See also hasNavigationBar().
            String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
            if (! "".equals(navBarOverride)) {
                if      (navBarOverride.equals("1")) mHasNavigationBar = false;
                else if (navBarOverride.equals("0")) mHasNavigationBar = true;
            }
        } else {
            mHasNavigationBar = false;
        } 
PhoneWindowManager has been changed from ICS.
Tablet UI mode need 720dp!!