143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor/* 243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * Copyright (C) 2010 The Android Open Source Project 343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * 443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * Licensed under the Apache License, Version 2.0 (the "License"); 543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * you may not use this file except in compliance with the License. 643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * You may obtain a copy of the License at 743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * 843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * http://www.apache.org/licenses/LICENSE-2.0 943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * 1043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * Unless required by applicable law or agreed to in writing, software 1143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * distributed under the License is distributed on an "AS IS" BASIS, 1243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * See the License for the specific language governing permissions and 1443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * limitations under the License. 1543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor */ 1643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 1743fe81bc2c186e49b25762450003276a7ed0002dDan Egnorpackage android.os; 1843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 1943fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport android.content.ComponentName; 2043fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport android.content.Context; 2143fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport android.content.Intent; 2243fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport android.content.ServiceConnection; 2343fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport android.test.AndroidTestCase; 2443fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport android.test.suitebuilder.annotation.MediumTest; 2543fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport android.util.Log; 2643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 2743fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport java.io.File; 2843fe81bc2c186e49b25762450003276a7ed0002dDan Egnorimport java.io.IOException; 2943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 3043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor/** 3143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor * Test whether Binder calls inherit thread priorities correctly. 3243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor */ 3343fe81bc2c186e49b25762450003276a7ed0002dDan Egnorpublic class BinderThreadPriorityTest extends AndroidTestCase { 3443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor private static final String TAG = "BinderThreadPriorityTest"; 3543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor private IBinderThreadPriorityService mService; 3643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor private int mSavedPriority; 3743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 3843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor private ServiceConnection mConnection = new ServiceConnection() { 3943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public void onServiceConnected(ComponentName name, IBinder service) { 4043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor synchronized (BinderThreadPriorityTest.this) { 4143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor mService = IBinderThreadPriorityService.Stub.asInterface(service); 4243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor BinderThreadPriorityTest.this.notifyAll(); 4343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 4443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 4543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 4643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public void onServiceDisconnected(ComponentName name) { 4743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor mService = null; 4843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 4943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor }; 5043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 5143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor private static class ServiceStub extends IBinderThreadPriorityService.Stub { 5243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public int getThreadPriority() { fail(); return -999; } 5343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public String getThreadSchedulerGroup() { fail(); return null; } 5443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public void setPriorityAndCallBack(int p, IBinderThreadPriorityService cb) { fail(); } 5543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public void callBack(IBinderThreadPriorityService cb) { fail(); } 5643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor private static void fail() { throw new RuntimeException("unimplemented"); } 5743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 5843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 5943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor @Override 6043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor protected void setUp() throws Exception { 6143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor super.setUp(); 6243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 6343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor getContext().bindService( 6443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor new Intent(getContext(), BinderThreadPriorityService.class), 6543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor mConnection, Context.BIND_AUTO_CREATE); 6643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 6743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor synchronized (this) { 6843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor if (mService == null) { 6943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor try { 7043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor wait(30000); 7143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } catch (InterruptedException e) { 7243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor throw new RuntimeException(e); 7343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 7443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertNotNull("Gave up waiting for BinderThreadPriorityService", mService); 7543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 7643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 7743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 7843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor mSavedPriority = Process.getThreadPriority(Process.myTid()); 7943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor Process.setThreadPriority(mSavedPriority); // To realign priority & cgroup, if needed 8043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(expectedSchedulerGroup(mSavedPriority), getSchedulerGroup()); 8143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor Log.i(TAG, "Saved priority: " + mSavedPriority); 8243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 8343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 8443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor @Override 8543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor protected void tearDown() throws Exception { 8643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor // HACK -- see bug 2665914 -- setThreadPriority() doesn't always set the 8743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor // scheduler group reliably unless we start out with background priority. 8843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 8943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor Process.setThreadPriority(mSavedPriority); 9043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(mSavedPriority, Process.getThreadPriority(Process.myTid())); 9143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(expectedSchedulerGroup(mSavedPriority), getSchedulerGroup()); 9243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 9343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor getContext().unbindService(mConnection); 9443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor super.tearDown(); 9543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 9643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 9743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public static String getSchedulerGroup() { 9843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor String fn = "/proc/" + Process.myPid() + "/task/" + Process.myTid() + "/cgroup"; 9943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor try { 10043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor String cgroup = FileUtils.readTextFile(new File(fn), 1024, null); 10143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor for (String line : cgroup.split("\n")) { 10243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor String fields[] = line.trim().split(":"); 10343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor if (fields.length == 3 && fields[1].equals("cpu")) return fields[2]; 10443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 10543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } catch (IOException e) { 10643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor Log.e(TAG, "Can't read: " + fn, e); 10743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 10843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor return null; // Unknown 10943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 11043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 11143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public static String expectedSchedulerGroup(int prio) { 11243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor return prio < Process.THREAD_PRIORITY_BACKGROUND ? "/" : "/bg_non_interactive"; 11343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 11443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 11543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public void testPassPriorityToService() throws Exception { 11643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor for (int prio = 19; prio >= -20; prio--) { 11743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor Process.setThreadPriority(prio); 11843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 11943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor // Local 12043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(prio, Process.getThreadPriority(Process.myTid())); 12143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(expectedSchedulerGroup(prio), getSchedulerGroup()); 12243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 12343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor // Remote 12443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(prio, mService.getThreadPriority()); 12543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(expectedSchedulerGroup(prio), mService.getThreadSchedulerGroup()); 12643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 12743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 12843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 12943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public void testCallBackFromServiceWithPriority() throws Exception { 13043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor for (int prio = -20; prio <= 19; prio++) { 13143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor final int expected = prio; 13243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor mService.setPriorityAndCallBack(prio, new ServiceStub() { 13343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor public void callBack(IBinderThreadPriorityService cb) { 13443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(expected, Process.getThreadPriority(Process.myTid())); 13543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(expectedSchedulerGroup(expected), getSchedulerGroup()); 13643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 13743fe81bc2c186e49b25762450003276a7ed0002dDan Egnor }); 13843fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 13943fe81bc2c186e49b25762450003276a7ed0002dDan Egnor assertEquals(mSavedPriority, Process.getThreadPriority(Process.myTid())); 14043fe81bc2c186e49b25762450003276a7ed0002dDan Egnor 14143fe81bc2c186e49b25762450003276a7ed0002dDan Egnor // BROKEN -- see bug 2665954 -- scheduler group doesn't get reset 14243fe81bc2c186e49b25762450003276a7ed0002dDan Egnor // properly after a back-call with a different priority. 14343fe81bc2c186e49b25762450003276a7ed0002dDan Egnor // assertEquals(expectedSchedulerGroup(mSavedPriority), getSchedulerGroup()); 14443fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 14543fe81bc2c186e49b25762450003276a7ed0002dDan Egnor } 14643fe81bc2c186e49b25762450003276a7ed0002dDan Egnor} 147