diff options
Diffstat (limited to 'services/java/com/android/server')
20 files changed, 480 insertions, 263 deletions
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index df2e1aa..7bc6a88 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -223,6 +223,7 @@ class AppWidgetServiceImpl { final String action = intent.getAction(); boolean added = false; boolean changed = false; + boolean providersModified = false; String pkgList[] = null; if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); @@ -254,12 +255,12 @@ class AppWidgetServiceImpl { || (extras != null && extras.getBoolean(Intent.EXTRA_REPLACING, false))) { for (String pkgName : pkgList) { // The package was just upgraded - updateProvidersForPackageLocked(pkgName); + providersModified |= updateProvidersForPackageLocked(pkgName); } } else { // The package was just added for (String pkgName : pkgList) { - addProvidersForPackageLocked(pkgName); + providersModified |= addProvidersForPackageLocked(pkgName); } } saveStateLocked(); @@ -272,12 +273,20 @@ class AppWidgetServiceImpl { synchronized (mAppWidgetIds) { ensureStateLoadedLocked(); for (String pkgName : pkgList) { - removeProvidersForPackageLocked(pkgName); + providersModified |= removeProvidersForPackageLocked(pkgName); saveStateLocked(); } } } } + + if (providersModified) { + // If the set of providers has been modified, notify each active AppWidgetHost + synchronized (mAppWidgetIds) { + ensureStateLoadedLocked(); + notifyHostsForProvidersChangedLocked(); + } + } } private void dumpProvider(Provider p, int index, PrintWriter pw) { @@ -1637,7 +1646,8 @@ class AppWidgetServiceImpl { getSettingsFile(mUserId).delete(); } - void addProvidersForPackageLocked(String pkgName) { + boolean addProvidersForPackageLocked(String pkgName) { + boolean providersAdded = false; Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setPackage(pkgName); List<ResolveInfo> broadcastReceivers; @@ -1647,7 +1657,7 @@ class AppWidgetServiceImpl { PackageManager.GET_META_DATA, mUserId); } catch (RemoteException re) { // Shouldn't happen, local call - return; + return false; } final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size(); for (int i = 0; i < N; i++) { @@ -1658,11 +1668,15 @@ class AppWidgetServiceImpl { } if (pkgName.equals(ai.packageName)) { addProviderLocked(ri); + providersAdded = true; } } + + return providersAdded; } - void updateProvidersForPackageLocked(String pkgName) { + boolean updateProvidersForPackageLocked(String pkgName) { + boolean providersUpdated = false; HashSet<String> keep = new HashSet<String>(); Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setPackage(pkgName); @@ -1673,7 +1687,7 @@ class AppWidgetServiceImpl { PackageManager.GET_META_DATA, mUserId); } catch (RemoteException re) { // Shouldn't happen, local call - return; + return false; } // add the missing ones and collect which ones to keep @@ -1690,6 +1704,7 @@ class AppWidgetServiceImpl { if (p == null) { if (addProviderLocked(ri)) { keep.add(ai.name); + providersUpdated = true; } } else { Provider parsed = parseProviderInfoXml(component, ri); @@ -1724,6 +1739,7 @@ class AppWidgetServiceImpl { } // Now that we've told the host, push out an update. sendUpdateIntentLocked(p, appWidgetIds); + providersUpdated = true; } } } @@ -1737,16 +1753,21 @@ class AppWidgetServiceImpl { if (pkgName.equals(p.info.provider.getPackageName()) && !keep.contains(p.info.provider.getClassName())) { removeProviderLocked(i, p); + providersUpdated = true; } } + + return providersUpdated; } - void removeProvidersForPackageLocked(String pkgName) { + boolean removeProvidersForPackageLocked(String pkgName) { + boolean providersRemoved = false; int N = mInstalledProviders.size(); for (int i = N - 1; i >= 0; i--) { Provider p = mInstalledProviders.get(i); if (pkgName.equals(p.info.provider.getPackageName())) { removeProviderLocked(i, p); + providersRemoved = true; } } @@ -1761,5 +1782,24 @@ class AppWidgetServiceImpl { deleteHostLocked(host); } } + + return providersRemoved; + } + + void notifyHostsForProvidersChangedLocked() { + final int N = mHosts.size(); + for (int i = N - 1; i >= 0; i--) { + Host host = mHosts.get(i); + try { + if (host.callbacks != null) { + host.callbacks.providersChanged(); + } + } catch (RemoteException ex) { + // It failed; remove the callback. No need to prune because + // we know that this host is still referenced by this + // instance. + host.callbacks = null; + } + } } } diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java index ab9ae69..0a6f23c 100644 --- a/services/java/com/android/server/BatteryService.java +++ b/services/java/com/android/server/BatteryService.java @@ -68,7 +68,7 @@ import java.util.Arrays; * a degree Centigrade</p> * <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p> */ -class BatteryService extends Binder { +public class BatteryService extends Binder { private static final String TAG = BatteryService.class.getSimpleName(); private static final boolean LOCAL_LOGV = false; @@ -148,12 +148,12 @@ class BatteryService extends Binder { update(); } - final boolean isPowered() { + public final boolean isPowered() { // assume we are powered if battery state is unknown so the "stay on while plugged in" option will work. return (mAcOnline || mUsbOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN); } - final boolean isPowered(int plugTypeSet) { + public final boolean isPowered(int plugTypeSet) { // assume we are powered if battery state is unknown so // the "stay on while plugged in" option will work. if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) { @@ -172,7 +172,7 @@ class BatteryService extends Binder { return (plugTypeSet & plugTypeBit) != 0; } - final int getPlugType() { + public final int getPlugType() { return mPlugType; } @@ -195,7 +195,7 @@ class BatteryService extends Binder { }; // returns battery level as a percentage - final int getBatteryLevel() { + public final int getBatteryLevel() { return mBatteryLevel; } diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java index 64789d3..72c0767 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/java/com/android/server/DockObserver.java @@ -16,6 +16,8 @@ package com.android.server; +import com.android.server.power.PowerManagerService; + import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.ContentResolver; diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags index 41f7335..dd50beb 100644 --- a/services/java/com/android/server/EventLogTags.logtags +++ b/services/java/com/android/server/EventLogTags.logtags @@ -114,6 +114,8 @@ option java_package com.android.server # Package Manager ready: 3100 boot_progress_pms_ready (time|2|3) # + check activity_launch_time for Home app +# Value of "unknown sources" setting at app install time +3110 unknown_sources_enabled (value|1) # --------------------------- diff --git a/services/java/com/android/server/LightsService.java b/services/java/com/android/server/LightsService.java index 1e95f3e..89bfcac 100644 --- a/services/java/com/android/server/LightsService.java +++ b/services/java/com/android/server/LightsService.java @@ -31,29 +31,29 @@ public class LightsService { private static final String TAG = "LightsService"; private static final boolean DEBUG = false; - static final int LIGHT_ID_BACKLIGHT = 0; - static final int LIGHT_ID_KEYBOARD = 1; - static final int LIGHT_ID_BUTTONS = 2; - static final int LIGHT_ID_BATTERY = 3; - static final int LIGHT_ID_NOTIFICATIONS = 4; - static final int LIGHT_ID_ATTENTION = 5; - static final int LIGHT_ID_BLUETOOTH = 6; - static final int LIGHT_ID_WIFI = 7; - static final int LIGHT_ID_COUNT = 8; - - static final int LIGHT_FLASH_NONE = 0; - static final int LIGHT_FLASH_TIMED = 1; - static final int LIGHT_FLASH_HARDWARE = 2; + public static final int LIGHT_ID_BACKLIGHT = 0; + public static final int LIGHT_ID_KEYBOARD = 1; + public static final int LIGHT_ID_BUTTONS = 2; + public static final int LIGHT_ID_BATTERY = 3; + public static final int LIGHT_ID_NOTIFICATIONS = 4; + public static final int LIGHT_ID_ATTENTION = 5; + public static final int LIGHT_ID_BLUETOOTH = 6; + public static final int LIGHT_ID_WIFI = 7; + public static final int LIGHT_ID_COUNT = 8; + + public static final int LIGHT_FLASH_NONE = 0; + public static final int LIGHT_FLASH_TIMED = 1; + public static final int LIGHT_FLASH_HARDWARE = 2; /** * Light brightness is managed by a user setting. */ - static final int BRIGHTNESS_MODE_USER = 0; + public static final int BRIGHTNESS_MODE_USER = 0; /** * Light brightness is managed by a light sensor. */ - static final int BRIGHTNESS_MODE_SENSOR = 1; + public static final int BRIGHTNESS_MODE_SENSOR = 1; private final Light mLights[] = new Light[LIGHT_ID_COUNT]; diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java index f71125a..92af9a9 100644 --- a/services/java/com/android/server/NativeDaemonConnector.java +++ b/services/java/com/android/server/NativeDaemonConnector.java @@ -35,6 +35,9 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.LinkedList; /** @@ -482,102 +485,108 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo private static class ResponseQueue { - private static class Response { + private static class PendingCmd { public int cmdNum; - public LinkedList<NativeDaemonEvent> responses = new LinkedList<NativeDaemonEvent>(); + public BlockingQueue<NativeDaemonEvent> responses = + new ArrayBlockingQueue<NativeDaemonEvent>(10); public String request; - public Response(int c, String r) {cmdNum = c; request = r;} + + // The availableResponseCount member is used to track when we can remove this + // instance from the ResponseQueue. + // This is used under the protection of a sync of the mPendingCmds object. + // A positive value means we've had more writers retreive this object while + // a negative value means we've had more readers. When we've had an equal number + // (it goes to zero) we can remove this object from the mPendingCmds list. + // Note that we may have more responses for this command (and more readers + // coming), but that would result in a new PendingCmd instance being created + // and added with the same cmdNum. + // Also note that when this goes to zero it just means a parity of readers and + // writers have retrieved this object - not that they are done using it. The + // responses queue may well have more responses yet to be read or may get more + // responses added to it. But all those readers/writers have retreived and + // hold references to this instance already so it can be removed from + // mPendingCmds queue. + public int availableResponseCount; + public PendingCmd(int c, String r) {cmdNum = c; request = r;} } - private final LinkedList<Response> mResponses; + private final LinkedList<PendingCmd> mPendingCmds; private int mMaxCount; ResponseQueue(int maxCount) { - mResponses = new LinkedList<Response>(); + mPendingCmds = new LinkedList<PendingCmd>(); mMaxCount = maxCount; } public void add(int cmdNum, NativeDaemonEvent response) { - Response found = null; - synchronized (mResponses) { - for (Response r : mResponses) { - if (r.cmdNum == cmdNum) { - found = r; + PendingCmd found = null; + synchronized (mPendingCmds) { + for (PendingCmd pendingCmd : mPendingCmds) { + if (pendingCmd.cmdNum == cmdNum) { + found = pendingCmd; break; } } if (found == null) { // didn't find it - make sure our queue isn't too big before adding - // another.. - while (mResponses.size() >= mMaxCount) { + while (mPendingCmds.size() >= mMaxCount) { Slog.e("NativeDaemonConnector.ResponseQueue", - "more buffered than allowed: " + mResponses.size() + + "more buffered than allowed: " + mPendingCmds.size() + " >= " + mMaxCount); // let any waiter timeout waiting for this - Response r = mResponses.remove(); + PendingCmd pendingCmd = mPendingCmds.remove(); Slog.e("NativeDaemonConnector.ResponseQueue", - "Removing request: " + r.request + " (" + r.cmdNum + ")"); + "Removing request: " + pendingCmd.request + " (" + + pendingCmd.cmdNum + ")"); } - found = new Response(cmdNum, null); - mResponses.add(found); + found = new PendingCmd(cmdNum, null); + mPendingCmds.add(found); } - found.responses.add(response); - } - synchronized (found) { - found.notify(); + found.availableResponseCount++; + // if a matching remove call has already retrieved this we can remove this + // instance from our list + if (found.availableResponseCount == 0) mPendingCmds.remove(found); } + try { + found.responses.put(response); + } catch (InterruptedException e) { } } // note that the timeout does not count time in deep sleep. If you don't want // the device to sleep, hold a wakelock public NativeDaemonEvent remove(int cmdNum, int timeoutMs, String origCmd) { - long endTime = SystemClock.uptimeMillis() + timeoutMs; - long nowTime; - Response found = null; - while (true) { - synchronized (mResponses) { - for (Response response : mResponses) { - if (response.cmdNum == cmdNum) { - found = response; - // how many response fragments are left - switch (response.responses.size()) { - case 0: // haven't got any - must wait - break; - case 1: // last one - remove this from the master list - mResponses.remove(response); // fall through - default: // take one and move on - response.request = origCmd; - return response.responses.remove(); - } - } - } - nowTime = SystemClock.uptimeMillis(); - if (endTime <= nowTime) { - Slog.e("NativeDaemonConnector.ResponseQueue", - "Timeout waiting for response"); - return null; - } - /* pre-allocate so we have something unique to wait on */ - if (found == null) { - found = new Response(cmdNum, origCmd); - mResponses.add(found); + PendingCmd found = null; + synchronized (mPendingCmds) { + for (PendingCmd pendingCmd : mPendingCmds) { + if (pendingCmd.cmdNum == cmdNum) { + found = pendingCmd; + break; } } - try { - synchronized (found) { - found.wait(endTime - nowTime); - } - } catch (InterruptedException e) { - // loop around to check if we're done or if it's time to stop waiting + if (found == null) { + found = new PendingCmd(cmdNum, origCmd); + mPendingCmds.add(found); } + found.availableResponseCount--; + // if a matching add call has already retrieved this we can remove this + // instance from our list + if (found.availableResponseCount == 0) mPendingCmds.remove(found); + } + NativeDaemonEvent result = null; + try { + result = found.responses.poll(timeoutMs, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) {} + if (result == null) { + Slog.e("NativeDaemonConnector.ResponseQueue", "Timeout waiting for response"); } + return result; } public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("Pending requests:"); - synchronized (mResponses) { - for (Response response : mResponses) { - pw.println(" Cmd " + response.cmdNum + " - " + response.request); + synchronized (mPendingCmds) { + for (PendingCmd pendingCmd : mPendingCmds) { + pw.println(" Cmd " + pendingCmd.cmdNum + " - " + pendingCmd.request); } } } diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 11644e3..09792f5 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -923,14 +923,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void startAccessPoint( - WifiConfiguration wifiConfig, String wlanIface, String softapIface) { + WifiConfiguration wifiConfig, String wlanIface) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { wifiFirmwareReload(wlanIface, "AP"); if (wifiConfig == null) { - mConnector.execute("softap", "set", wlanIface, softapIface); + mConnector.execute("softap", "set", wlanIface); } else { - mConnector.execute("softap", "set", wlanIface, softapIface, wifiConfig.SSID, + mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID, getSecurityType(wifiConfig), wifiConfig.preSharedKey); } mConnector.execute("softap", "startap"); @@ -966,7 +966,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { mConnector.execute("softap", "stopap"); - mConnector.execute("softap", "stop", wlanIface); wifiFirmwareReload(wlanIface, "STA"); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); @@ -974,13 +973,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub } @Override - public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface) { + public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { if (wifiConfig == null) { - mConnector.execute("softap", "set", wlanIface, softapIface); + mConnector.execute("softap", "set", wlanIface); } else { - mConnector.execute("softap", "set", wlanIface, softapIface, wifiConfig.SSID, + mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID, getSecurityType(wifiConfig), wifiConfig.preSharedKey); } } catch (NativeDaemonConnectorException e) { diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java index 6ad8bd0..87843d9 100644 --- a/services/java/com/android/server/NsdService.java +++ b/services/java/com/android/server/NsdService.java @@ -110,8 +110,8 @@ public class NsdService extends INsdManager.Stub { private final EnabledState mEnabledState = new EnabledState(); @Override - protected String getMessageInfo(Message msg) { - return cmdToString(msg.what); + protected String getWhatToString(int what) { + return cmdToString(what); } /** @@ -144,7 +144,7 @@ public class NsdService extends INsdManager.Stub { } else { setInitialState(mDisabledState); } - setProcessedMessagesSize(25); + setLogRecSize(25); registerForNsdSetting(); } diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/java/com/android/server/ShutdownActivity.java index d85abe6..a4341b7 100644 --- a/services/java/com/android/server/ShutdownActivity.java +++ b/services/java/com/android/server/ShutdownActivity.java @@ -17,13 +17,12 @@ package com.android.server; import android.app.Activity; -import android.content.BroadcastReceiver; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.util.Slog; -import com.android.server.pm.ShutdownThread; +import com.android.server.power.ShutdownThread; public class ShutdownActivity extends Activity { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 7e733c6..ed7b6e3 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -55,7 +55,8 @@ import com.android.server.input.InputManagerService; import com.android.server.net.NetworkPolicyManagerService; import com.android.server.net.NetworkStatsService; import com.android.server.pm.PackageManagerService; -import com.android.server.pm.ShutdownThread; +import com.android.server.power.PowerManagerService; +import com.android.server.power.ShutdownThread; import com.android.server.usb.UsbService; import com.android.server.wm.WindowManagerService; diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java index c239382..c5b4a07 100644 --- a/services/java/com/android/server/Watchdog.java +++ b/services/java/com/android/server/Watchdog.java @@ -17,6 +17,7 @@ package com.android.server; import com.android.server.am.ActivityManagerService; +import com.android.server.power.PowerManagerService; import android.app.AlarmManager; import android.app.PendingIntent; diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 1f03d17..53fb60b 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -58,6 +58,7 @@ import android.os.SystemProperties; import android.os.WorkSource; import android.provider.Settings; import android.text.TextUtils; +import android.util.Log; import android.util.Slog; import java.util.ArrayList; @@ -110,10 +111,6 @@ public class WifiService extends IWifiManager.Stub { private int mScanLocksAcquired; private int mScanLocksReleased; - /* A mapping from UID to scan count */ - private HashMap<Integer, Integer> mScanCount = - new HashMap<Integer, Integer>(); - private final List<Multicaster> mMulticasters = new ArrayList<Multicaster>(); private int mMulticastEnabled; @@ -161,6 +158,10 @@ public class WifiService extends IWifiManager.Stub { /* Tracks whether wifi is enabled from WifiStateMachine's perspective */ private boolean mWifiEnabled; + /* The work source (UID) that triggered the current WIFI scan, synchronized + * on this */ + private WorkSource mScanWorkSource; + private boolean mIsReceiverRegistered = false; @@ -413,6 +414,7 @@ public class WifiService extends IWifiManager.Stub { } } else if (intent.getAction().equals( WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { + noteScanEnd(); checkAndSetNotification(); } } @@ -430,6 +432,44 @@ public class WifiService extends IWifiManager.Stub { mNotificationEnabledSettingObserver.register(); } + /** Tell battery stats about a new WIFI scan */ + private void noteScanStart() { + WorkSource scanWorkSource = null; + synchronized (WifiService.this) { + if (mScanWorkSource != null) { + // Scan already in progress, don't add this one to battery stats + return; + } + scanWorkSource = new WorkSource(Binder.getCallingUid()); + mScanWorkSource = scanWorkSource; + } + + long id = Binder.clearCallingIdentity(); + try { + mBatteryStats.noteWifiScanStartedFromSource(scanWorkSource); + } catch (RemoteException e) { + Log.w(TAG, e); + } finally { + Binder.restoreCallingIdentity(id); + } + } + + /** Tell battery stats that the current WIFI scan has completed */ + private void noteScanEnd() { + WorkSource scanWorkSource = null; + synchronized (WifiService.this) { + scanWorkSource = mScanWorkSource; + mScanWorkSource = null; + } + if (scanWorkSource != null) { + try { + mBatteryStats.noteWifiScanStoppedFromSource(scanWorkSource); + } catch (RemoteException e) { + Log.w(TAG, e); + } + } + } + /** * Check if Wi-Fi needs to be enabled and start * if needed @@ -541,16 +581,8 @@ public class WifiService extends IWifiManager.Stub { */ public void startScan(boolean forceActive) { enforceChangePermission(); - - int uid = Binder.getCallingUid(); - int count = 0; - synchronized (mScanCount) { - if (mScanCount.containsKey(uid)) { - count = mScanCount.get(uid); - } - mScanCount.put(uid, ++count); - } mWifiStateMachine.startScan(forceActive); + noteScanStart(); } private void enforceAccessPermission() { @@ -1011,12 +1043,6 @@ public class WifiService extends IWifiManager.Stub { mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent); } - //Start scan stats tracking when device unplugged - if (pluggedType == 0) { - synchronized (mScanCount) { - mScanCount.clear(); - } - } mPluggedType = pluggedType; } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, @@ -1207,13 +1233,6 @@ public class WifiService extends IWifiManager.Stub { pw.println("Locks held:"); mLocks.dump(pw); - pw.println("Scan count since last plugged in"); - synchronized (mScanCount) { - for(int sc : mScanCount.keySet()) { - pw.println("UID: " + sc + " Scan count: " + mScanCount.get(sc)); - } - } - pw.println(); pw.println("WifiWatchdogStateMachine dump"); mWifiWatchdogStateMachine.dump(pw); @@ -1333,10 +1352,8 @@ public class WifiService extends IWifiManager.Stub { switch(wifiLock.mMode) { case WifiManager.WIFI_MODE_FULL: case WifiManager.WIFI_MODE_FULL_HIGH_PERF: - mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource); - break; case WifiManager.WIFI_MODE_SCAN_ONLY: - mBatteryStats.noteScanWifiLockAcquiredFromSource(wifiLock.mWorkSource); + mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource); break; } } @@ -1345,10 +1362,8 @@ public class WifiService extends IWifiManager.Stub { switch(wifiLock.mMode) { case WifiManager.WIFI_MODE_FULL: case WifiManager.WIFI_MODE_FULL_HIGH_PERF: - mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource); - break; case WifiManager.WIFI_MODE_SCAN_ONLY: - mBatteryStats.noteScanWifiLockReleasedFromSource(wifiLock.mWorkSource); + mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource); break; } } diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java index 8f797ec..ab20208 100644 --- a/services/java/com/android/server/am/BatteryStatsService.java +++ b/services/java/com/android/server/am/BatteryStatsService.java @@ -346,18 +346,18 @@ public final class BatteryStatsService extends IBatteryStats.Stub { mStats.noteFullWifiLockReleasedLocked(uid); } } - - public void noteScanWifiLockAcquired(int uid) { + + public void noteWifiScanStarted(int uid) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteScanWifiLockAcquiredLocked(uid); + mStats.noteWifiScanStartedLocked(uid); } } - - public void noteScanWifiLockReleased(int uid) { + + public void noteWifiScanStopped(int uid) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteScanWifiLockReleasedLocked(uid); + mStats.noteWifiScanStoppedLocked(uid); } } @@ -389,17 +389,17 @@ public final class BatteryStatsService extends IBatteryStats.Stub { } } - public void noteScanWifiLockAcquiredFromSource(WorkSource ws) { + public void noteWifiScanStartedFromSource(WorkSource ws) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteScanWifiLockAcquiredFromSourceLocked(ws); + mStats.noteWifiScanStartedFromSourceLocked(ws); } } - public void noteScanWifiLockReleasedFromSource(WorkSource ws) { + public void noteWifiScanStoppedFromSource(WorkSource ws) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteScanWifiLockReleasedFromSourceLocked(ws); + mStats.noteWifiScanStoppedFromSourceLocked(ws); } } diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 88a0ccb..00832ee 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -500,8 +500,13 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mUsbTetherRequested = false; } } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { - if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION"); - mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED); + NetworkInfo networkInfo = (NetworkInfo)intent.getParcelableExtra( + ConnectivityManager.EXTRA_NETWORK_INFO); + if (networkInfo != null && + networkInfo.getDetailedState() != NetworkInfo.DetailedState.FAILED) { + if (VDBG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION"); + mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED); + } } } } @@ -1134,7 +1139,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { private State mStopTetheringErrorState; private State mSetDnsForwardersErrorState; - private ArrayList mNotifyList; + private ArrayList<TetherInterfaceSM> mNotifyList; private int mCurrentConnectionSequence; private int mMobileApnReserved = ConnectivityManager.TYPE_NONE; @@ -1164,7 +1169,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mSetDnsForwardersErrorState = new SetDnsForwardersErrorState(); addState(mSetDnsForwardersErrorState); - mNotifyList = new ArrayList(); + mNotifyList = new ArrayList<TetherInterfaceSM>(); setInitialState(mInitialState); } @@ -1361,8 +1366,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { protected void notifyTetheredOfNewUpstreamIface(String ifaceName) { if (DBG) Log.d(TAG, "notifying tethered with iface =" + ifaceName); mUpstreamIfaceName = ifaceName; - for (Object o : mNotifyList) { - TetherInterfaceSM sm = (TetherInterfaceSM)o; + for (TetherInterfaceSM sm : mNotifyList) { sm.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED, ifaceName); } @@ -1380,13 +1384,13 @@ public class Tethering extends INetworkManagementEventObserver.Stub { switch (message.what) { case CMD_TETHER_MODE_REQUESTED: TetherInterfaceSM who = (TetherInterfaceSM)message.obj; - if (VDBG) Log.d(TAG, "Tether Mode requested by " + who.toString()); + if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); mNotifyList.add(who); transitionTo(mTetherModeAliveState); break; case CMD_TETHER_MODE_UNREQUESTED: who = (TetherInterfaceSM)message.obj; - if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who.toString()); + if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); int index = mNotifyList.indexOf(who); if (index != -1) { mNotifyList.remove(who); @@ -1423,18 +1427,29 @@ public class Tethering extends INetworkManagementEventObserver.Stub { switch (message.what) { case CMD_TETHER_MODE_REQUESTED: TetherInterfaceSM who = (TetherInterfaceSM)message.obj; + if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); mNotifyList.add(who); who.sendMessage(TetherInterfaceSM.CMD_TETHER_CONNECTION_CHANGED, mUpstreamIfaceName); break; case CMD_TETHER_MODE_UNREQUESTED: who = (TetherInterfaceSM)message.obj; + if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); int index = mNotifyList.indexOf(who); if (index != -1) { + if (DBG) Log.d(TAG, "TetherModeAlive removing notifyee " + who); mNotifyList.remove(index); if (mNotifyList.isEmpty()) { turnOffMasterTetherSettings(); // transitions appropriately + } else { + if (DBG) { + Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() + + " live requests:"); + for (Object o : mNotifyList) Log.d(TAG, " " + o); + } } + } else { + Log.e(TAG, "TetherModeAliveState UNREQUESTED has unknown who: " + who); } break; case CMD_UPSTREAM_CHANGED: @@ -1561,7 +1576,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { pw.println(); pw.println("Tether state:"); for (Object o : mIfaces.values()) { - pw.println(" "+o.toString()); + pw.println(" " + o); } } pw.println(); diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 9a79f86..2609664 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -208,7 +208,15 @@ public class PackageManagerService extends IPackageManager.Stub { * The default maximum time to wait for the verification agent to return in * milliseconds. */ - private static final long DEFAULT_VERIFICATION_TIMEOUT = 60 * 1000; + private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; + + /** + * The default response for package verification timeout. + * + * This can be either PackageManager.VERIFICATION_ALLOW or + * PackageManager.VERIFICATION_REJECT. + */ + private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; @@ -694,6 +702,10 @@ public class PackageManagerService extends IPackageManager.Stub { // Remove the replaced package's older resources safely now deleteOld = true; } + + // Log current value of "unknown sources" setting + EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, + getUnknownSourcesSettings()); } // Force a gc to clear up things Runtime.getRuntime().gc(); @@ -769,7 +781,18 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.i(TAG, "Verification timed out for " + args.packageURI.toString()); mPendingVerification.remove(verificationId); - int ret = PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT; + int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; + + if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { + Slog.i(TAG, "Continuing with installation of " + args.packageURI.toString()); + state.setVerifierResponse(Binder.getCallingUid(), PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); + try { + ret = args.copyApk(mContainerService, true); + } catch (RemoteException e) { + Slog.e(TAG, "Could not contact the ContainerService"); + } + } + processPendingInstall(args, ret); mHandler.sendEmptyMessage(MCS_UNBIND); @@ -5446,6 +5469,17 @@ public class PackageManagerService extends IPackageManager.Stub { } /** + * Get the default verification agent response code. + * + * @return default verification response code + */ + private int getDefaultVerificationResponse() { + return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), + android.provider.Settings.Secure.PACKAGE_VERIFIER_DEFAULT_RESPONSE, + DEFAULT_VERIFICATION_RESPONSE); + } + + /** * Check whether or not package verification has been enabled. * * @return true if verification should be performed @@ -5456,6 +5490,17 @@ public class PackageManagerService extends IPackageManager.Stub { DEFAULT_VERIFY_ENABLE ? 1 : 0) == 1 ? true : false; } + /** + * Get the "allow unknown sources" setting. + * + * @return the current "allow unknown sources" setting + */ + private int getUnknownSourcesSettings() { + return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), + android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, + -1); + } + public void setInstallerPackageName(String targetPackage, String installerPackageName) { final int uid = Binder.getCallingUid(); // writer @@ -9376,14 +9421,20 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public UserInfo getUser(int userId) { - enforceSystemOrRoot("Only the system can remove users"); + enforceSystemOrRoot("Only the system can query user"); return sUserManager.getUser(userId); } @Override - public void updateUserName(int userId, String name) { + public void setUserName(int userId, String name) { enforceSystemOrRoot("Only the system can rename users"); - sUserManager.updateUserName(userId, name); + sUserManager.setUserName(userId, name); + } + + @Override + public ParcelFileDescriptor setUserIcon(int userId) { + enforceSystemOrRoot("Only the system can update users"); + return sUserManager.setUserIcon(userId); } @Override diff --git a/services/java/com/android/server/pm/UserManager.java b/services/java/com/android/server/pm/UserManager.java index 4e9e666..738ab08 100644 --- a/services/java/com/android/server/pm/UserManager.java +++ b/services/java/com/android/server/pm/UserManager.java @@ -16,6 +16,9 @@ package com.android.server.pm; +import static android.os.ParcelFileDescriptor.MODE_CREATE; +import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; + import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; @@ -24,6 +27,7 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.Environment; import android.os.FileUtils; +import android.os.ParcelFileDescriptor; import android.os.SystemClock; import android.os.UserId; import android.util.Log; @@ -34,6 +38,7 @@ import android.util.Xml; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -44,10 +49,15 @@ import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; public class UserManager { + + private static final String TAG = "UserManager"; + private static final String TAG_NAME = "name"; private static final String ATTR_FLAGS = "flags"; + private static final String ATTR_ICON_PATH = "icon"; + private static final String ATTR_ID = "id"; private static final String TAG_USERS = "users"; @@ -58,6 +68,7 @@ public class UserManager { private static final String USER_INFO_DIR = "system" + File.separator + "users"; private static final String USER_LIST_FILENAME = "userlist.xml"; + private static final String USER_PHOTO_FILENAME = "photo.png"; private SparseArray<UserInfo> mUsers = new SparseArray<UserInfo>(); @@ -114,7 +125,7 @@ public class UserManager { } } - public void updateUserName(int userId, String name) { + public void setUserName(int userId, String name) { synchronized (mUsers) { UserInfo info = mUsers.get(userId); if (name != null && !name.equals(info.name)) { @@ -124,6 +135,39 @@ public class UserManager { } } + public ParcelFileDescriptor setUserIcon(int userId) { + synchronized (mUsers) { + UserInfo info = mUsers.get(userId); + if (info == null) return null; + ParcelFileDescriptor fd = updateIconBitmapLocked(info); + if (fd != null) { + writeUserLocked(info); + } + return fd; + } + } + + private ParcelFileDescriptor updateIconBitmapLocked(UserInfo info) { + try { + File dir = new File(mUsersDir, Integer.toString(info.id)); + File file = new File(dir, USER_PHOTO_FILENAME); + if (!dir.exists()) { + dir.mkdir(); + FileUtils.setPermissions( + dir.getPath(), + FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, + -1, -1); + } + ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, + MODE_CREATE|MODE_READ_WRITE); + info.iconPath = file.getAbsolutePath(); + return fd; + } catch (FileNotFoundException e) { + Slog.w(TAG, "Error setting photo for user ", e); + } + return null; + } + /** * Returns an array of user ids. This array is cached here for quick access, so do not modify or * cache it elsewhere. @@ -187,7 +231,7 @@ public class UserManager { private void fallbackToSingleUserLocked() { // Create the primary user - UserInfo primary = new UserInfo(0, "Primary", + UserInfo primary = new UserInfo(0, "Primary", null, UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); mUsers.put(0, primary); updateUserIdsLocked(); @@ -219,6 +263,9 @@ public class UserManager { serializer.startTag(null, TAG_USER); serializer.attribute(null, ATTR_ID, Integer.toString(userInfo.id)); serializer.attribute(null, ATTR_FLAGS, Integer.toString(userInfo.flags)); + if (userInfo.iconPath != null) { + serializer.attribute(null, ATTR_ICON_PATH, userInfo.iconPath); + } serializer.startTag(null, TAG_NAME); serializer.text(userInfo.name); @@ -286,6 +333,7 @@ public class UserManager { private UserInfo readUser(int id) { int flags = 0; String name = null; + String iconPath = null; FileInputStream fis = null; try { @@ -312,6 +360,7 @@ public class UserManager { } String flagString = parser.getAttributeValue(null, ATTR_FLAGS); flags = Integer.parseInt(flagString); + iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH); while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { @@ -324,7 +373,7 @@ public class UserManager { } } - UserInfo userInfo = new UserInfo(id, name, flags); + UserInfo userInfo = new UserInfo(id, name, iconPath, flags); return userInfo; } catch (IOException ioe) { @@ -342,7 +391,7 @@ public class UserManager { public UserInfo createUser(String name, int flags) { int userId = getNextAvailableId(); - UserInfo userInfo = new UserInfo(userId, name, flags); + UserInfo userInfo = new UserInfo(userId, name, null, flags); File userPath = new File(mBaseUserPath, Integer.toString(userId)); if (!createPackageFolders(userId, userPath)) { return null; diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java index 0a9905e..de2edff 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/power/PowerManagerService.java @@ -14,11 +14,16 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.power; import com.android.internal.app.IBatteryStats; +import com.android.server.BatteryService; +import com.android.server.EventLogTags; +import com.android.server.LightsService; +import com.android.server.LightsService.Light; +import com.android.server.Watchdog; +import com.android.server.Watchdog.Monitor; import com.android.server.am.BatteryStatsService; -import com.android.server.pm.ShutdownThread; import android.app.ActivityManagerNative; import android.app.IActivityManager; @@ -532,7 +537,7 @@ public class PowerManagerService extends IPowerManager.Stub } } - PowerManagerService() { + public PowerManagerService() { // Hack to get our uid... should have a func for this. long token = Binder.clearCallingIdentity(); MY_UID = Process.myUid(); @@ -550,7 +555,7 @@ public class PowerManagerService extends IPowerManager.Stub private ContentQueryMap mSettings; - void init(Context context, LightsService lights, IActivityManager activity, + public void init(Context context, LightsService lights, IActivityManager activity, BatteryService battery) { mLightsService = lights; mContext = context; @@ -707,7 +712,7 @@ public class PowerManagerService extends IPowerManager.Stub /** * Low-level function turn the device off immediately, without trying * to be clean. Most people should use - * {@link com.android.server.pm.internal.app.ShutdownThread} for a clean shutdown. + * {@link com.android.server.power.internal.app.ShutdownThread} for a clean shutdown. */ public static void lowLevelShutdown() { nativeShutdown(); @@ -2384,13 +2389,13 @@ public class PowerManagerService extends IPowerManager.Stub } private int getPreferredBrightness() { + int brightness = mScreenBrightnessSetting; if (mScreenBrightnessOverride >= 0) { - return mScreenBrightnessOverride; + brightness = mScreenBrightnessOverride; } else if (mLightSensorScreenBrightness >= 0 && mUseSoftwareAutoBrightness && mAutoBrightessEnabled) { - return mLightSensorScreenBrightness; + brightness = mLightSensorScreenBrightness; } - final int brightness = mScreenBrightnessSetting; // Don't let applications turn the screen all the way off return Math.max(brightness, mScreenBrightnessDim); } @@ -3056,7 +3061,7 @@ public class PowerManagerService extends IPowerManager.Stub return mPolicy; } - void systemReady() { + public void systemReady() { mSensorManager = new SystemSensorManager(mHandlerThread.getLooper()); mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); // don't bother with the light sensor if auto brightness is handled in hardware diff --git a/services/java/com/android/server/pm/ShutdownThread.java b/services/java/com/android/server/power/ShutdownThread.java index 3675d41..5f2f428 100644 --- a/services/java/com/android/server/pm/ShutdownThread.java +++ b/services/java/com/android/server/power/ShutdownThread.java @@ -15,7 +15,7 @@ */ -package com.android.server.pm; +package com.android.server.power; import android.app.ActivityManagerNative; import android.app.AlertDialog; @@ -43,7 +43,6 @@ import android.os.storage.IMountService; import android.os.storage.IMountShutdownObserver; import com.android.internal.telephony.ITelephony; -import com.android.server.PowerManagerService; import android.util.Log; import android.view.WindowManager; diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index 758b6e7..e65d5d2 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -38,10 +38,18 @@ public class WindowAnimator { ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>(); boolean mAnimating; - boolean mTokenMayBeDrawn; - boolean mForceHiding; - WindowState mWindowAnimationBackground; - int mWindowAnimationBackgroundColor; + + /** Variables only intended to be valid within each pass through animate(). Does not contain + * persistent state. */ + private class InnerLoopParams { + boolean mTokenMayBeDrawn; + boolean mForceHiding; + WindowState mDetachedWallpaper = null; + WindowState mWindowAnimationBackground; + int mWindowAnimationBackgroundColor; + } + InnerLoopParams mInner = new InnerLoopParams(); + int mAdjResult; int mPendingLayoutChanges; @@ -65,9 +73,9 @@ public class WindowAnimator { // Window currently running an animation that has requested it be detached // from the wallpaper. This means we need to ensure the wallpaper is // visible behind it in case it animates in a way that would allow it to be - // seen. + // seen. If multiple windows satisfy this, use the lowest window. WindowState mWindowDetachedWallpaper = null; - WindowState mDetachedWallpaper = null; + DimSurface mWindowAnimationBackgroundSurface = null; int mBulkUpdateParams = 0; @@ -103,19 +111,20 @@ public class WindowAnimator { } private void testWallpaperAndBackgroundLocked() { - if (mWindowDetachedWallpaper != mDetachedWallpaper) { + final WindowState detachedWallpaper = mInner.mDetachedWallpaper; + if (mWindowDetachedWallpaper != detachedWallpaper) { if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from " + mWindowDetachedWallpaper - + " to " + mDetachedWallpaper); - mWindowDetachedWallpaper = mDetachedWallpaper; + + " to " + detachedWallpaper); + mWindowDetachedWallpaper = detachedWallpaper; mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; } - if (mWindowAnimationBackgroundColor != 0) { + if (mInner.mWindowAnimationBackgroundColor != 0) { // If the window that wants black is the current wallpaper // target, then the black goes *below* the wallpaper so we // don't cause the wallpaper to suddenly disappear. - WindowState target = mWindowAnimationBackground; + WindowState target = mInner.mWindowAnimationBackground; if (mService.mWallpaperTarget == target || mService.mLowerWallpaperTarget == target || mService.mUpperWallpaperTarget == target) { @@ -135,7 +144,7 @@ public class WindowAnimator { final int dh = mDh; mWindowAnimationBackgroundSurface.show(dw, dh, target.mWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM, - mWindowAnimationBackgroundColor); + mInner.mWindowAnimationBackgroundColor); } else if (mWindowAnimationBackgroundSurface != null) { mWindowAnimationBackgroundSurface.hide(); } @@ -199,9 +208,9 @@ public class WindowAnimator { ArrayList<WindowStateAnimator> unForceHiding = null; boolean wallpaperInUnForceHiding = false; - for (int i = mService.mWindows.size() - 1; i >= 0; i--) { - WindowState win = mService.mWindows.get(i); - WindowStateAnimator winAnimator = win.mWinAnimator; + for (int i = mWinAnimators.size() - 1; i >= 0; i--) { + WindowStateAnimator winAnimator = mWinAnimators.get(i); + WindowState win = winAnimator.mWin; final int flags = winAnimator.mAttrFlags; if (winAnimator.mSurface != null) { @@ -220,15 +229,15 @@ public class WindowAnimator { if (winAnimator.mAnimation != null) { if ((flags & FLAG_SHOW_WALLPAPER) != 0 && winAnimator.mAnimation.getDetachWallpaper()) { - mDetachedWallpaper = win; + mInner.mDetachedWallpaper = win; } final int backgroundColor = winAnimator.mAnimation.getBackgroundColor(); if (backgroundColor != 0) { - if (mWindowAnimationBackground == null - || (winAnimator.mAnimLayer < - mWindowAnimationBackground.mWinAnimator.mAnimLayer)) { - mWindowAnimationBackground = win; - mWindowAnimationBackgroundColor = backgroundColor; + final WindowState background = mInner.mWindowAnimationBackground; + if (background == null || (winAnimator.mAnimLayer < + background.mWinAnimator.mAnimLayer)) { + mInner.mWindowAnimationBackground = win; + mInner.mWindowAnimationBackgroundColor = backgroundColor; } } } @@ -244,15 +253,15 @@ public class WindowAnimator { && appAnimator.animating) { if ((flags & FLAG_SHOW_WALLPAPER) != 0 && appAnimator.animation.getDetachWallpaper()) { - mDetachedWallpaper = win; + mInner.mDetachedWallpaper = win; } final int backgroundColor = appAnimator.animation.getBackgroundColor(); if (backgroundColor != 0) { - if (mWindowAnimationBackground == null - || (winAnimator.mAnimLayer < - mWindowAnimationBackground.mWinAnimator.mAnimLayer)) { - mWindowAnimationBackground = win; - mWindowAnimationBackgroundColor = backgroundColor; + final WindowState background = mInner.mWindowAnimationBackground; + if (background == null || (winAnimator.mAnimLayer < + background.mWinAnimator.mAnimLayer)) { + mInner.mWindowAnimationBackground = win; + mInner.mWindowAnimationBackgroundColor = backgroundColor; } } } @@ -280,10 +289,10 @@ public class WindowAnimator { mService.mFocusMayChange = true; } if (win.isReadyForDisplay() && !winAnimator.isAnimating()) { - mForceHiding = true; + mInner.mForceHiding = true; } if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, - "Force hide " + mForceHiding + "Force hide " + mInner.mForceHiding + " hasSurface=" + win.mHasSurface + " policyVis=" + win.mPolicyVisibility + " destroying=" + win.mDestroying @@ -293,7 +302,7 @@ public class WindowAnimator { + " anim=" + win.mWinAnimator.mAnimation); } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) { final boolean changed; - if (mForceHiding && !winAnimator.isAnimating()) { + if (mInner.mForceHiding && !winAnimator.isAnimating()) { changed = win.hideLw(false, false); if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, "Now policy hidden: " + win); @@ -308,7 +317,7 @@ public class WindowAnimator { unForceHiding = new ArrayList<WindowStateAnimator>(); } unForceHiding.add(winAnimator); - if ((win.mAttrs.flags&WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { + if ((flags & FLAG_SHOW_WALLPAPER) != 0) { wallpaperInUnForceHiding = true; } } @@ -320,7 +329,7 @@ public class WindowAnimator { } } } - if (changed && (flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { + if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) { mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { @@ -364,7 +373,7 @@ public class WindowAnimator { "tokenMayBeDrawn: " + atoken + " freezingScreen=" + atoken.mAppAnimator.freezingScreen + " mAppFreezing=" + win.mAppFreezing); - mTokenMayBeDrawn = true; + mInner.mTokenMayBeDrawn = true; } } } else if (win.isDrawnLw()) { @@ -454,18 +463,18 @@ public class WindowAnimator { } private void performAnimationsLocked() { - mTokenMayBeDrawn = false; - mForceHiding = false; - mDetachedWallpaper = null; - mWindowAnimationBackground = null; - mWindowAnimationBackgroundColor = 0; + mInner.mTokenMayBeDrawn = false; + mInner.mForceHiding = false; + mInner.mDetachedWallpaper = null; + mInner.mWindowAnimationBackground = null; + mInner.mWindowAnimationBackgroundColor = 0; updateWindowsAndWallpaperLocked(); if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { mPendingActions |= WALLPAPER_ACTION_PENDING; } - if (mTokenMayBeDrawn) { + if (mInner.mTokenMayBeDrawn) { testTokenMayBeDrawnLocked(); } } @@ -526,7 +535,15 @@ public class WindowAnimator { Surface.closeTransaction(); } - mService.bulkSetParameters(mBulkUpdateParams, mPendingLayoutChanges); + if (mBulkUpdateParams != 0 || mPendingLayoutChanges != 0) { + final WindowManagerService.AnimatorToLayoutParams animToLayout = mService.mAnimToLayout; + synchronized (animToLayout) { + animToLayout.mBulkUpdateParams = mBulkUpdateParams; + animToLayout.mPendingLayoutChanges = mPendingLayoutChanges; + animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper; + mService.setAnimatorParameters(); + } + } if (mAnimating) { mService.scheduleAnimationLocked(); diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index c329174..e2acd7f 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -42,12 +42,12 @@ import com.android.internal.view.IInputMethodManager; import com.android.internal.view.WindowManagerPolicyThread; import com.android.server.AttributeCache; import com.android.server.EventLogTags; -import com.android.server.PowerManagerService; import com.android.server.Watchdog; import com.android.server.am.BatteryStatsService; import com.android.server.input.InputFilter; import com.android.server.input.InputManagerService; -import com.android.server.pm.ShutdownThread; +import com.android.server.power.PowerManagerService; +import com.android.server.power.ShutdownThread; import android.Manifest; import android.app.ActivityManagerNative; @@ -511,9 +511,9 @@ public class WindowManagerService extends IWindowManager.Stub // State while inside of layoutAndPlaceSurfacesLocked(). boolean mFocusMayChange; - + Configuration mCurConfiguration = new Configuration(); - + // This is held as long as we have the screen frozen, to give us time to // perform a rotation animation when turning off shows the lock screen which // changes the orientation. @@ -640,7 +640,17 @@ public class WindowManagerService extends IWindowManager.Stub private float mButtonBrightness = -1; private boolean mUpdateRotation = false; } - LayoutFields mInnerFields = new LayoutFields(); + final LayoutFields mInnerFields = new LayoutFields(); + + static class AnimatorToLayoutParams { + int mBulkUpdateParams; + int mPendingLayoutChanges; + WindowState mWindowDetachedWallpaper; + } + final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams(); + + /** The lowest wallpaper target with a detached wallpaper animation on it. */ + WindowState mWindowDetachedWallpaper = null; /** Only do a maximum of 6 repeated layouts. After that quit */ private int mLayoutRepeatCount; @@ -671,7 +681,7 @@ public class WindowManagerService extends IWindowManager.Stub } final AnimationRunnable mAnimationRunnable = new AnimationRunnable(); boolean mAnimationScheduled; - + final WindowAnimator mAnimator; final class DragInputEventReceiver extends InputEventReceiver { @@ -1576,9 +1586,9 @@ public class WindowManagerService extends IWindowManager.Stub Slog.v(TAG, "List with no IM target:"); logWindowList(" "); } - if (DN > 0) moveInputMethodDialogsLocked(-1);; + if (DN > 0) moveInputMethodDialogsLocked(-1); } else { - moveInputMethodDialogsLocked(-1);; + moveInputMethodDialogsLocked(-1); } } @@ -1640,7 +1650,7 @@ public class WindowManagerService extends IWindowManager.Stub continue; } topCurW = null; - if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) { + if (w != mWindowDetachedWallpaper && w.mAppToken != null) { // If this window's app token is hidden and not animating, // it is of no interest to us. if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) { @@ -1666,7 +1676,7 @@ public class WindowManagerService extends IWindowManager.Stub continue; } break; - } else if (w == mAnimator.mWindowDetachedWallpaper) { + } else if (w == mWindowDetachedWallpaper) { windowDetachedI = i; } } @@ -3108,12 +3118,11 @@ public class WindowManagerService extends IWindowManager.Stub a.setDetachWallpaper(true); a.setDuration(duration); return a; - } else { - // For normal animations, the exiting element just holds in place. - Animation a = new AlphaAnimation(1, 1); - a.setDuration(duration); - return a; } + // For normal animations, the exiting element just holds in place. + Animation a = new AlphaAnimation(1, 1); + a.setDuration(duration); + return a; } /** @@ -6826,7 +6835,7 @@ public class WindowManagerService extends IWindowManager.Stub public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22; public static final int BOOT_TIMEOUT = 23; public static final int WAITING_FOR_DRAWN_TIMEOUT = 24; - public static final int BULK_UPDATE_PARAMETERS = 25; + public static final int UPDATE_ANIM_PARAMETERS = 25; public static final int SHOW_STRICT_MODE_VIOLATION = 26; public static final int DO_ANIMATION_CALLBACK = 27; @@ -7253,44 +7262,49 @@ public class WindowManagerService extends IWindowManager.Stub break; } - case BULK_UPDATE_PARAMETERS: { + case UPDATE_ANIM_PARAMETERS: { // Used to send multiple changes from the animation side to the layout side. synchronized (mWindowMap) { - boolean doRequest = false; - // TODO(cmautner): As the number of bits grows, use masks of bit groups to - // eliminate unnecessary tests. - if ((msg.arg1 & LayoutFields.SET_UPDATE_ROTATION) != 0) { - mInnerFields.mUpdateRotation = true; - doRequest = true; - } - if ((msg.arg1 & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) { - mInnerFields.mWallpaperMayChange = true; - doRequest = true; - } - if ((msg.arg1 & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) { - mInnerFields.mWallpaperForceHidingChanged = true; - doRequest = true; - } - if ((msg.arg1 & LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE) != 0) { - mInnerFields.mOrientationChangeComplete = false; - } else { - mInnerFields.mOrientationChangeComplete = true; - if (mWindowsFreezingScreen) { + synchronized (mAnimToLayout) { + boolean doRequest = false; + final int bulkUpdateParams = mAnimToLayout.mBulkUpdateParams; + // TODO(cmautner): As the number of bits grows, use masks of bit groups to + // eliminate unnecessary tests. + if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) { + mInnerFields.mUpdateRotation = true; doRequest = true; } - } - if ((msg.arg1 & LayoutFields.SET_TURN_ON_SCREEN) != 0) { - mTurnOnScreen = true; - } + if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) { + mInnerFields.mWallpaperMayChange = true; + doRequest = true; + } + if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) { + mInnerFields.mWallpaperForceHidingChanged = true; + doRequest = true; + } + if ((bulkUpdateParams & LayoutFields.CLEAR_ORIENTATION_CHANGE_COMPLETE) != 0) { + mInnerFields.mOrientationChangeComplete = false; + } else { + mInnerFields.mOrientationChangeComplete = true; + if (mWindowsFreezingScreen) { + doRequest = true; + } + } + if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) { + mTurnOnScreen = true; + } - mPendingLayoutChanges |= msg.arg2; - if (mPendingLayoutChanges != 0) { - doRequest = true; - } + mPendingLayoutChanges |= mAnimToLayout.mPendingLayoutChanges; + if (mPendingLayoutChanges != 0) { + doRequest = true; + } - if (doRequest) { - mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS); - performLayoutAndPlaceSurfacesLocked(); + mWindowDetachedWallpaper = mAnimToLayout.mWindowDetachedWallpaper; + + if (doRequest) { + mH.sendEmptyMessage(CLEAR_PENDING_ACTIONS); + performLayoutAndPlaceSurfacesLocked(); + } } } break; @@ -10015,8 +10029,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - void bulkSetParameters(final int bulkUpdateParams, int pendingLayoutChanges) { - mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams, - pendingLayoutChanges)); + void setAnimatorParameters() { + mH.sendMessage(mH.obtainMessage(H.UPDATE_ANIM_PARAMETERS)); } } |