summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp34
-rw-r--r--services/input/InputDispatcher.cpp4
-rw-r--r--services/input/InputReader.cpp30
-rw-r--r--services/input/InputReader.h3
-rw-r--r--services/input/tests/InputReader_test.cpp52
-rw-r--r--services/java/com/android/server/ConnectivityService.java33
-rw-r--r--services/java/com/android/server/DevicePolicyManagerService.java7
-rw-r--r--services/java/com/android/server/DropBoxManagerService.java6
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java86
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java24
-rw-r--r--services/java/com/android/server/PowerManagerService.java30
-rw-r--r--services/java/com/android/server/SystemServer.java249
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java137
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java22
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java62
-rw-r--r--services/java/com/android/server/am/ActivityStack.java2
-rw-r--r--services/java/com/android/server/am/TaskRecord.java2
-rw-r--r--services/java/com/android/server/connectivity/Vpn.java42
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java297
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java58
-rw-r--r--services/java/com/android/server/usb/UsbDeviceManager.java18
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java186
-rw-r--r--services/sensorservice/Fusion.cpp65
-rw-r--r--services/sensorservice/vec.h9
-rw-r--r--services/surfaceflinger/Layer.cpp29
-rw-r--r--services/surfaceflinger/Layer.h1
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp55
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
-rw-r--r--services/surfaceflinger/SurfaceTextureLayer.cpp8
-rw-r--r--services/surfaceflinger/TextureManager.cpp341
-rw-r--r--services/surfaceflinger/TextureManager.h93
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java115
32 files changed, 1237 insertions, 865 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 941c9c8..744fa50 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -522,6 +522,11 @@ uint32_t AudioFlinger::latency(int output) const
status_t AudioFlinger::setMasterVolume(float value)
{
+ status_t ret = initCheck();
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
// check calling permissions
if (!settingsAllowed()) {
return PERMISSION_DENIED;
@@ -547,7 +552,10 @@ status_t AudioFlinger::setMasterVolume(float value)
status_t AudioFlinger::setMode(int mode)
{
- status_t ret;
+ status_t ret = initCheck();
+ if (ret != NO_ERROR) {
+ return ret;
+ }
// check calling permissions
if (!settingsAllowed()) {
@@ -577,6 +585,11 @@ status_t AudioFlinger::setMode(int mode)
status_t AudioFlinger::setMicMute(bool state)
{
+ status_t ret = initCheck();
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
// check calling permissions
if (!settingsAllowed()) {
return PERMISSION_DENIED;
@@ -584,13 +597,18 @@ status_t AudioFlinger::setMicMute(bool state)
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
- status_t ret = mPrimaryHardwareDev->set_mic_mute(mPrimaryHardwareDev, state);
+ ret = mPrimaryHardwareDev->set_mic_mute(mPrimaryHardwareDev, state);
mHardwareStatus = AUDIO_HW_IDLE;
return ret;
}
bool AudioFlinger::getMicMute() const
{
+ status_t ret = initCheck();
+ if (ret != NO_ERROR) {
+ return false;
+ }
+
bool state = AUDIO_MODE_INVALID;
mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
mPrimaryHardwareDev->get_mic_mute(mPrimaryHardwareDev, &state);
@@ -814,6 +832,11 @@ String8 AudioFlinger::getParameters(int ioHandle, const String8& keys)
size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
{
+ status_t ret = initCheck();
+ if (ret != NO_ERROR) {
+ return 0;
+ }
+
return mPrimaryHardwareDev->get_input_buffer_size(mPrimaryHardwareDev, sampleRate, format, channelCount);
}
@@ -834,6 +857,11 @@ unsigned int AudioFlinger::getInputFramesLost(int ioHandle)
status_t AudioFlinger::setVoiceVolume(float value)
{
+ status_t ret = initCheck();
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
// check calling permissions
if (!settingsAllowed()) {
return PERMISSION_DENIED;
@@ -841,7 +869,7 @@ status_t AudioFlinger::setVoiceVolume(float value)
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
- status_t ret = mPrimaryHardwareDev->set_voice_volume(mPrimaryHardwareDev, value);
+ ret = mPrimaryHardwareDev->set_voice_volume(mPrimaryHardwareDev, value);
mHardwareStatus = AUDIO_HW_IDLE;
return ret;
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index f6ce44c..cf167ae 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -1831,8 +1831,8 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
bool resumeWithAppendedMotionSample) {
#if DEBUG_DISPATCH_CYCLE
- LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
- "xOffset=%f, yOffset=%f, scaleFactor=%f"
+ LOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
+ "xOffset=%f, yOffset=%f, scaleFactor=%f, "
"pointerIds=0x%x, "
"resumeWithAppendedMotionSample=%s",
connection->getInputChannelName(), inputTarget->flags,
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 40c85fc..bfcf8e0 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -1220,6 +1220,9 @@ void TouchButtonAccumulator::reset(InputDevice* device) {
mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
+ mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
+ mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
+ mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
}
void TouchButtonAccumulator::clearButtons() {
@@ -1234,6 +1237,9 @@ void TouchButtonAccumulator::clearButtons() {
mBtnToolAirbrush = 0;
mBtnToolMouse = 0;
mBtnToolLens = 0;
+ mBtnToolDoubleTap = 0;
+ mBtnToolTripleTap = 0;
+ mBtnToolQuadTap = 0;
}
void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
@@ -1272,6 +1278,15 @@ void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
case BTN_TOOL_LENS:
mBtnToolLens = rawEvent->value;
break;
+ case BTN_TOOL_DOUBLETAP:
+ mBtnToolDoubleTap = rawEvent->value;
+ break;
+ case BTN_TOOL_TRIPLETAP:
+ mBtnToolTripleTap = rawEvent->value;
+ break;
+ case BTN_TOOL_QUADTAP:
+ mBtnToolQuadTap = rawEvent->value;
+ break;
}
}
}
@@ -1297,7 +1312,7 @@ int32_t TouchButtonAccumulator::getToolType() const {
if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
return AMOTION_EVENT_TOOL_TYPE_STYLUS;
}
- if (mBtnToolFinger) {
+ if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
return AMOTION_EVENT_TOOL_TYPE_FINGER;
}
return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
@@ -1306,7 +1321,8 @@ int32_t TouchButtonAccumulator::getToolType() const {
bool TouchButtonAccumulator::isToolActive() const {
return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
|| mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
- || mBtnToolMouse || mBtnToolLens;
+ || mBtnToolMouse || mBtnToolLens
+ || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
}
bool TouchButtonAccumulator::isHovering() const {
@@ -2172,6 +2188,7 @@ void CursorInputMapper::sync(nsecs_t when) {
}
nsecs_t downTime = mDownTime;
bool buttonsChanged = currentButtonState != lastButtonState;
+ bool buttonsPressed = currentButtonState & ~lastButtonState;
float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
@@ -2233,7 +2250,7 @@ void CursorInputMapper::sync(nsecs_t when) {
// the device in your pocket.
// TODO: Use the input device configuration to control this behavior more finely.
uint32_t policyFlags = 0;
- if (getDevice()->isExternal()) {
+ if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
policyFlags |= POLICY_FLAG_WAKE_DROPPED;
}
@@ -3329,9 +3346,12 @@ void TouchInputMapper::sync(nsecs_t when) {
// Handle policy on initial down or hover events.
uint32_t policyFlags = 0;
- if (mLastRawPointerData.pointerCount == 0 && mCurrentRawPointerData.pointerCount != 0) {
+ bool initialDown = mLastRawPointerData.pointerCount == 0
+ && mCurrentRawPointerData.pointerCount != 0;
+ bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
+ if (initialDown || buttonsPressed) {
+ // If this is a touch screen, hide the pointer on an initial down.
if (mDeviceMode == DEVICE_MODE_DIRECT) {
- // If this is a touch screen, hide the pointer on an initial down.
getContext()->fadePointer();
}
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 76d77f1..bad96df 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -596,6 +596,9 @@ private:
bool mBtnToolAirbrush;
bool mBtnToolMouse;
bool mBtnToolLens;
+ bool mBtnToolDoubleTap;
+ bool mBtnToolTripleTap;
+ bool mBtnToolQuadTap;
void clearButtons();
};
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 4796958..32f948b 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -3377,8 +3377,32 @@ TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
- // finger
+ // double-tap
processKey(mapper, BTN_TOOL_LENS, 0);
+ processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // triple-tap
+ processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
+ processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // quad-tap
+ processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
+ processKey(mapper, BTN_TOOL_QUADTAP, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // finger
+ processKey(mapper, BTN_TOOL_QUADTAP, 0);
processKey(mapper, BTN_TOOL_FINGER, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
@@ -4766,8 +4790,32 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
- // finger
+ // double-tap
processKey(mapper, BTN_TOOL_LENS, 0);
+ processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // triple-tap
+ processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
+ processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // quad-tap
+ processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
+ processKey(mapper, BTN_TOOL_QUADTAP, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // finger
+ processKey(mapper, BTN_TOOL_QUADTAP, 0);
processKey(mapper, BTN_TOOL_FINGER, 1);
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 1341dd4..bfca851 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -72,7 +72,6 @@ import com.android.internal.net.VpnConfig;
import com.android.internal.telephony.Phone;
import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
-
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
@@ -89,7 +88,6 @@ import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* @hide
@@ -251,6 +249,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private static final int EVENT_SEND_STICKY_BROADCAST_INTENT =
MAX_NETWORK_STATE_TRACKER_EVENT + 12;
+ /**
+ * Used internally to
+ * {@link NetworkStateTracker#setPolicyDataEnable(boolean)}.
+ */
+ private static final int EVENT_SET_POLICY_DATA_ENABLE = MAX_NETWORK_STATE_TRACKER_EVENT + 13;
+
private Handler mHandler;
// list of DeathRecipients used to make sure features are turned off when
@@ -1282,7 +1286,25 @@ public class ConnectivityService extends IConnectivityManager.Stub {
if (VDBG) {
log(mNetTrackers[ConnectivityManager.TYPE_MOBILE].toString() + enabled);
}
- mNetTrackers[ConnectivityManager.TYPE_MOBILE].setDataEnable(enabled);
+ mNetTrackers[ConnectivityManager.TYPE_MOBILE].setUserDataEnable(enabled);
+ }
+ }
+
+ @Override
+ public void setPolicyDataEnable(int networkType, boolean enabled) {
+ // only someone like NPMS should only be calling us
+ mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+
+ mHandler.sendMessage(mHandler.obtainMessage(
+ EVENT_SET_POLICY_DATA_ENABLE, networkType, (enabled ? ENABLED : DISABLED)));
+ }
+
+ private void handleSetPolicyDataEnable(int networkType, boolean enabled) {
+ if (isNetworkTypeValid(networkType)) {
+ final NetworkStateTracker tracker = mNetTrackers[networkType];
+ if (tracker != null) {
+ tracker.setPolicyDataEnable(enabled);
+ }
}
}
@@ -2263,6 +2285,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
sendStickyBroadcast(intent);
break;
}
+ case EVENT_SET_POLICY_DATA_ENABLE: {
+ final int networkType = msg.arg1;
+ final boolean enabled = msg.arg2 == ENABLED;
+ handleSetPolicyDataEnable(networkType, enabled);
+ }
}
}
}
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index d549308..f1b8bae 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -1556,13 +1556,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return false;
}
}
-
- LockPatternUtils utils = new LockPatternUtils(mContext);
- if(utils.checkPasswordHistory(password)) {
- Slog.w(TAG, "resetPassword: password is the same as one of the last "
- + getPasswordHistoryLength(null) + " passwords");
- return false;
- }
}
int callingUid = Binder.getCallingUid();
diff --git a/services/java/com/android/server/DropBoxManagerService.java b/services/java/com/android/server/DropBoxManagerService.java
index 5c878c9..d37c9ab 100644
--- a/services/java/com/android/server/DropBoxManagerService.java
+++ b/services/java/com/android/server/DropBoxManagerService.java
@@ -28,7 +28,6 @@ import android.os.Debug;
import android.os.DropBoxManager;
import android.os.FileUtils;
import android.os.Handler;
-import android.os.ParcelFileDescriptor;
import android.os.StatFs;
import android.os.SystemClock;
import android.provider.Settings;
@@ -45,14 +44,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.OutputStreamWriter;
import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.zip.GZIPOutputStream;
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 73d790a..c11755b 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1,5 +1,4 @@
/*
- * Copyright (C) 2006-2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -48,7 +47,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
@@ -57,7 +55,6 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.ContentObserver;
-import android.graphics.BitmapFactory;
import android.inputmethodservice.InputMethodService;
import android.os.Binder;
import android.os.Environment;
@@ -98,12 +95,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.TreeMap;
/**
@@ -147,7 +142,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final Handler mHandler;
final InputMethodSettings mSettings;
final SettingsObserver mSettingsObserver;
- final StatusBarManagerService mStatusBar;
final IWindowManager mIWindowManager;
final HandlerCaller mCaller;
private final InputMethodFileManager mFileManager;
@@ -162,10 +156,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
new LruCache<SuggestionSpan, InputMethodInfo>(SECURE_SUGGESTION_SPANS_MAX_SIZE);
// Ongoing notification
- private final NotificationManager mNotificationManager;
- private final KeyguardManager mKeyguardManager;
- private final Notification mImeSwitcherNotification;
- private final PendingIntent mImeSwitchPendingIntent;
+ private NotificationManager mNotificationManager;
+ private KeyguardManager mKeyguardManager;
+ private StatusBarManagerService mStatusBar;
+ private Notification mImeSwitcherNotification;
+ private PendingIntent mImeSwitchPendingIntent;
private boolean mShowOngoingImeSwitcherForPhones;
private boolean mNotificationShown;
@@ -469,8 +464,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Pick another one...
Slog.i(TAG, "Current input method removed: " + curInputMethodId);
mImeWindowVis = 0;
- mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis,
- mBackDisposition);
+ updateImeWindowStatusLocked();
if (!chooseNewDefaultIMELocked()) {
changed = true;
curIm = null;
@@ -511,7 +505,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- public InputMethodManagerService(Context context, StatusBarManagerService statusBar) {
+ public InputMethodManagerService(Context context) {
mContext = context;
mRes = context.getResources();
mHandler = new Handler(this);
@@ -524,10 +518,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
});
- mKeyguardManager = (KeyguardManager)
- mContext.getSystemService(Context.KEYGUARD_SERVICE);
- mNotificationManager = (NotificationManager)
- mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mImeSwitcherNotification = new Notification();
mImeSwitcherNotification.icon = com.android.internal.R.drawable.ic_notification_ime_default;
mImeSwitcherNotification.when = 0;
@@ -553,8 +543,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
screenOnOffFilt.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mContext.registerReceiver(new ScreenOnOffReceiver(), screenOnOffFilt);
- mStatusBar = statusBar;
- statusBar.setIconVisibility("ime", false);
mNotificationShown = false;
// mSettings should be created before buildInputMethodListLocked
@@ -608,10 +596,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- public void systemReady() {
+ public void systemReady(StatusBarManagerService statusBar) {
synchronized (mMethodMap) {
if (!mSystemReady) {
mSystemReady = true;
+ mKeyguardManager = (KeyguardManager)
+ mContext.getSystemService(Context.KEYGUARD_SERVICE);
+ mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ mStatusBar = statusBar;
+ statusBar.setIconVisibility("ime", false);
+ updateImeWindowStatusLocked();
mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
com.android.internal.R.bool.show_ongoing_ime_switcher);
try {
@@ -623,6 +618,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
+ void updateImeWindowStatusLocked() {
+ setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition);
+ }
+
@Override
public List<InputMethodInfo> getInputMethodList() {
synchronized (mMethodMap) {
@@ -993,6 +992,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
sessionState.session.finishSession();
} catch (RemoteException e) {
Slog.w(TAG, "Session failed to close due to remote exception", e);
+ mImeWindowVis = 0;
+ updateImeWindowStatusLocked();
}
}
}
@@ -1009,7 +1010,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mEnabledSession = null;
mCurMethod = null;
}
- mStatusBar.setIconVisibility("ime", false);
+ if (mStatusBar != null) {
+ mStatusBar.setIconVisibility("ime", false);
+ }
}
@Override
@@ -1046,7 +1049,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
synchronized (mMethodMap) {
if (iconId == 0) {
if (DEBUG) Slog.d(TAG, "hide the small icon for the input method");
- mStatusBar.setIconVisibility("ime", false);
+ if (mStatusBar != null) {
+ mStatusBar.setIconVisibility("ime", false);
+ }
} else if (packageName != null) {
if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
CharSequence contentDescription = null;
@@ -1057,9 +1062,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} catch (NameNotFoundException nnfe) {
/* ignore */
}
- mStatusBar.setIcon("ime", packageName, iconId, 0,
- contentDescription != null ? contentDescription.toString() : null);
- mStatusBar.setIconVisibility("ime", true);
+ if (mStatusBar != null) {
+ mStatusBar.setIcon("ime", packageName, iconId, 0,
+ contentDescription != null
+ ? contentDescription.toString() : null);
+ mStatusBar.setIconVisibility("ime", true);
+ }
}
}
} finally {
@@ -1112,6 +1120,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
+ @SuppressWarnings("deprecation")
@Override
public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
int uid = Binder.getCallingUid();
@@ -1125,7 +1134,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
synchronized (mMethodMap) {
mImeWindowVis = vis;
mBackDisposition = backDisposition;
- mStatusBar.setImeWindowStatus(token, vis, backDisposition);
+ if (mStatusBar != null) {
+ mStatusBar.setImeWindowStatus(token, vis, backDisposition);
+ }
final boolean iconVisibility = (vis & InputMethodService.IME_ACTIVE) != 0;
final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
if (imi != null && iconVisibility && needsToShowImeSwitchOngoingNotification()) {
@@ -1142,12 +1153,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mImeSwitcherNotification.setLatestEventInfo(
mContext, title, summary, mImeSwitchPendingIntent);
- mNotificationManager.notify(
- com.android.internal.R.string.select_input_method,
- mImeSwitcherNotification);
- mNotificationShown = true;
+ if (mNotificationManager != null) {
+ mNotificationManager.notify(
+ com.android.internal.R.string.select_input_method,
+ mImeSwitcherNotification);
+ mNotificationShown = true;
+ }
} else {
- if (mNotificationShown) {
+ if (mNotificationShown && mNotificationManager != null) {
mNotificationManager.cancel(
com.android.internal.R.string.select_input_method);
mNotificationShown = false;
@@ -1252,8 +1265,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mImeWindowVis = (mInputShown || hardKeyShown) ? (
InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE)
: 0;
- mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis,
- mBackDisposition);
+ updateImeWindowStatusLocked();
// If subtype is null, try to find the most applicable one from
// getCurrentInputMethodSubtype.
if (subtype == null) {
@@ -1374,13 +1386,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (DEBUG) Slog.w(TAG, "Ignoring hideSoftInput of uid "
+ uid + ": " + client);
mImeWindowVis = 0;
- mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis,
- mBackDisposition);
+ updateImeWindowStatusLocked();
return false;
}
} catch (RemoteException e) {
mImeWindowVis = 0;
- mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition);
+ updateImeWindowStatusLocked();
return false;
}
}
@@ -2151,7 +2162,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
});
- if (showSubtypes && !(mKeyguardManager.isKeyguardLocked()
+ if (showSubtypes && mKeyguardManager != null && !(mKeyguardManager.isKeyguardLocked()
&& mKeyguardManager.isKeyguardSecure())) {
mDialogBuilder.setPositiveButton(
com.android.internal.R.string.configure_input_methods,
@@ -2580,6 +2591,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
// TODO: We should change the return type from List to List<Parcelable>
+ @SuppressWarnings("rawtypes")
@Override
public List getShortcutInputMethodsAndSubtypes() {
synchronized (mMethodMap) {
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 6edb132..7a3a344 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -101,13 +101,8 @@ public class NotificationManagerService extends INotificationManager.Stub
private Vibrator mVibrator = new Vibrator();
// for enabling and disabling notification pulse behavior
- private boolean mScreenOn = true;
private boolean mInCall = false;
private boolean mNotificationPulseEnabled;
- // This is true if we have received a new notification while the screen is off
- // (that is, if mLedNotification was set while the screen was off)
- // This is reset to false when the screen is turned on.
- private boolean mPendingPulseNotification;
private final ArrayList<NotificationRecord> mNotificationList =
new ArrayList<NotificationRecord>();
@@ -349,12 +344,6 @@ public class NotificationManagerService extends INotificationManager.Stub
cancelAllNotificationsInt(pkgName, 0, 0, !queryRestart);
}
}
- } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
- mScreenOn = true;
- updateNotificationPulse();
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- mScreenOn = false;
- updateNotificationPulse();
} else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
mInCall = (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK));
updateNotificationPulse();
@@ -1059,11 +1048,6 @@ public class NotificationManagerService extends INotificationManager.Stub
// lock on mNotificationList
private void updateLightsLocked()
{
- // clear pending pulse notification if screen is on
- if (mScreenOn || mLedNotification == null) {
- mPendingPulseNotification = false;
- }
-
// handle notification lights
if (mLedNotification == null) {
// get next notification, if any
@@ -1071,14 +1055,10 @@ public class NotificationManagerService extends INotificationManager.Stub
if (n > 0) {
mLedNotification = mLights.get(n-1);
}
- if (mLedNotification != null && !mScreenOn) {
- mPendingPulseNotification = true;
- }
}
- // we only flash if screen is off and persistent pulsing is enabled
- // and we are not currently in a call
- if (!mPendingPulseNotification || mScreenOn || mInCall) {
+ // Don't flash while we are in a call
+ if (mLedNotification == null || mInCall) {
mNotificationLight.turnOff();
} else {
int ledARGB = mLedNotification.notification.ledARGB;
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index d80a2cd..cbd986f 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -161,6 +161,7 @@ public class PowerManagerService extends IPowerManager.Stub
private int mStayOnConditions = 0;
private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
private final int[] mBroadcastWhy = new int[3];
+ private boolean mBroadcastingScreenOff = false;
private int mPartialCount = 0;
private int mPowerState;
// mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
@@ -1342,6 +1343,10 @@ public class PowerManagerService extends IPowerManager.Stub
mBroadcastWakeLock.release();
}
+ // The broadcast queue has changed; make sure the screen is on if it
+ // is now possible for it to be.
+ updateNativePowerStateLocked();
+
// Now send the message.
if (index >= 0) {
// Acquire the broadcast wake lock before changing the power
@@ -1370,6 +1375,9 @@ public class PowerManagerService extends IPowerManager.Stub
mBroadcastWhy[i] = mBroadcastWhy[i+1];
}
policy = getPolicyLocked();
+ if (value == 0) {
+ mBroadcastingScreenOff = true;
+ }
}
if (value == 1) {
mScreenOnStart = SystemClock.uptimeMillis();
@@ -1412,6 +1420,8 @@ public class PowerManagerService extends IPowerManager.Stub
synchronized (mLocks) {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
mBroadcastWakeLock.mCount);
+ mBroadcastingScreenOff = false;
+ updateNativePowerStateLocked();
mBroadcastWakeLock.release();
}
}
@@ -1442,6 +1452,10 @@ public class PowerManagerService extends IPowerManager.Stub
synchronized (mLocks) {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
+ synchronized (mLocks) {
+ mBroadcastingScreenOff = false;
+ updateNativePowerStateLocked();
+ }
mBroadcastWakeLock.release();
}
}
@@ -1768,6 +1782,22 @@ public class PowerManagerService extends IPowerManager.Stub
}
private void updateNativePowerStateLocked() {
+ if ((mPowerState & SCREEN_ON_BIT) != 0) {
+ // Don't turn screen on if we are currently reporting a screen off.
+ // This is to avoid letting the screen go on before things like the
+ // lock screen have been displayed due to it going off.
+ if (mBroadcastingScreenOff) {
+ // Currently broadcasting that the screen is off. Don't
+ // allow screen to go on until that is done.
+ return;
+ }
+ for (int i=0; i<mBroadcastQueue.length; i++) {
+ if (mBroadcastQueue[i] == 0) {
+ // A screen off is currently enqueued.
+ return;
+ }
+ }
+ }
nativeSetPowerState(
(mPowerState & SCREEN_ON_BIT) != 0,
(mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 5dd3c5b..e6f92a5 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -40,6 +40,7 @@ import android.server.BluetoothService;
import android.server.search.SearchManagerService;
import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.Log;
import android.util.Slog;
import android.view.WindowManager;
@@ -66,6 +67,11 @@ class ServerThread extends Thread {
ContentResolver mContentResolver;
+ void reportWtf(String msg, Throwable e) {
+ Slog.w(TAG, "***********************************************");
+ Log.wtf(TAG, "BOOT FAILURE " + msg, e);
+ }
+
@Override
public void run() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
@@ -116,7 +122,6 @@ class ServerThread extends Thread {
WindowManagerService wm = null;
BluetoothService bluetooth = null;
BluetoothA2dpService bluetoothA2dp = null;
- WiredAccessoryObserver wiredAccessory = null;
DockObserver dock = null;
UsbService usb = null;
UiModeManagerService uiMode = null;
@@ -222,7 +227,8 @@ class ServerThread extends Thread {
}
} catch (RuntimeException e) {
- Slog.e("System", "Failure starting core service", e);
+ Slog.e("System", "******************************************");
+ Slog.e("System", "************ Failure starting core service", e);
}
DevicePolicyManagerService devicePolicy = null;
@@ -235,13 +241,52 @@ class ServerThread extends Thread {
CountryDetectorService countryDetector = null;
TextServicesManagerService tsms = null;
+ // Bring up services needed for UI.
+ if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
+ try {
+ Slog.i(TAG, "Input Method Service");
+ imm = new InputMethodManagerService(context);
+ ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
+ } catch (Throwable e) {
+ reportWtf("starting Input Manager Service", e);
+ }
+
+ try {
+ Slog.i(TAG, "Accessibility Manager");
+ ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
+ new AccessibilityManagerService(context));
+ } catch (Throwable e) {
+ reportWtf("starting Accessibility Manager", e);
+ }
+ }
+
+ try {
+ wm.displayReady();
+ } catch (Throwable e) {
+ reportWtf("making display ready", e);
+ }
+
+ try {
+ pm.performBootDexOpt();
+ } catch (Throwable e) {
+ reportWtf("performing boot dexopt", e);
+ }
+
+ try {
+ ActivityManagerNative.getDefault().showBootMessage(
+ context.getResources().getText(
+ com.android.internal.R.string.android_upgrading_starting_apps),
+ false);
+ } catch (RemoteException e) {
+ }
+
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
Slog.i(TAG, "Device Policy");
devicePolicy = new DevicePolicyManagerService(context);
ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting DevicePolicyService", e);
+ reportWtf("starting DevicePolicyService", e);
}
try {
@@ -249,7 +294,7 @@ class ServerThread extends Thread {
statusBar = new StatusBarManagerService(context, wm);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting StatusBarManagerService", e);
+ reportWtf("starting StatusBarManagerService", e);
}
try {
@@ -257,15 +302,7 @@ class ServerThread extends Thread {
ServiceManager.addService(Context.CLIPBOARD_SERVICE,
new ClipboardService(context));
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Clipboard Service", e);
- }
-
- try {
- Slog.i(TAG, "Input Method Service");
- imm = new InputMethodManagerService(context, statusBar);
- ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
- } catch (Throwable e) {
- Slog.e(TAG, "Failure starting Input Manager Service", e);
+ reportWtf("starting Clipboard Service", e);
}
try {
@@ -273,7 +310,7 @@ class ServerThread extends Thread {
networkManagement = NetworkManagementService.create(context);
ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting NetworkManagement Service", e);
+ reportWtf("starting NetworkManagement Service", e);
}
try {
@@ -281,7 +318,7 @@ class ServerThread extends Thread {
tsms = new TextServicesManagerService(context);
ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Text Service Manager Service", e);
+ reportWtf("starting Text Service Manager Service", e);
}
try {
@@ -289,7 +326,7 @@ class ServerThread extends Thread {
networkStats = new NetworkStatsService(context, networkManagement, alarm);
ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting NetworkStats Service", e);
+ reportWtf("starting NetworkStats Service", e);
}
try {
@@ -299,7 +336,7 @@ class ServerThread extends Thread {
networkStats, networkManagement);
ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting NetworkPolicy Service", e);
+ reportWtf("starting NetworkPolicy Service", e);
}
try {
@@ -307,7 +344,7 @@ class ServerThread extends Thread {
wifiP2p = new WifiP2pService(context);
ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Wi-Fi P2pService", e);
+ reportWtf("starting Wi-Fi P2pService", e);
}
try {
@@ -316,7 +353,7 @@ class ServerThread extends Thread {
ServiceManager.addService(Context.WIFI_SERVICE, wifi);
wifi.checkAndStartWifi();
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Wi-Fi Service", e);
+ reportWtf("starting Wi-Fi Service", e);
}
try {
@@ -327,7 +364,7 @@ class ServerThread extends Thread {
networkPolicy.bindConnectivityManager(connectivity);
wifiP2p.connectivityServiceReady();
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Connectivity Service", e);
+ reportWtf("starting Connectivity Service", e);
}
try {
@@ -336,15 +373,7 @@ class ServerThread extends Thread {
ServiceManager.addService(
Context.THROTTLE_SERVICE, throttle);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting ThrottleService", e);
- }
-
- try {
- Slog.i(TAG, "Accessibility Manager");
- ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
- new AccessibilityManagerService(context));
- } catch (Throwable e) {
- Slog.e(TAG, "Failure starting Accessibility Manager", e);
+ reportWtf("starting ThrottleService", e);
}
try {
@@ -355,7 +384,7 @@ class ServerThread extends Thread {
Slog.i(TAG, "Mount Service");
ServiceManager.addService("mount", new MountService(context));
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Mount Service", e);
+ reportWtf("starting Mount Service", e);
}
try {
@@ -364,7 +393,7 @@ class ServerThread extends Thread {
ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
networkPolicy.bindNotificationManager(notification);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Notification Manager", e);
+ reportWtf("starting Notification Manager", e);
}
try {
@@ -372,7 +401,7 @@ class ServerThread extends Thread {
ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
new DeviceStorageMonitorService(context));
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting DeviceStorageMonitor service", e);
+ reportWtf("starting DeviceStorageMonitor service", e);
}
try {
@@ -380,7 +409,7 @@ class ServerThread extends Thread {
location = new LocationManagerService(context);
ServiceManager.addService(Context.LOCATION_SERVICE, location);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Location Manager", e);
+ reportWtf("starting Location Manager", e);
}
try {
@@ -388,7 +417,7 @@ class ServerThread extends Thread {
countryDetector = new CountryDetectorService(context);
ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Country Detector", e);
+ reportWtf("starting Country Detector", e);
}
try {
@@ -396,7 +425,7 @@ class ServerThread extends Thread {
ServiceManager.addService(Context.SEARCH_SERVICE,
new SearchManagerService(context));
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Search Service", e);
+ reportWtf("starting Search Service", e);
}
try {
@@ -404,7 +433,7 @@ class ServerThread extends Thread {
ServiceManager.addService(Context.DROPBOX_SERVICE,
new DropBoxManagerService(context, new File("/data/system/dropbox")));
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting DropBoxManagerService", e);
+ reportWtf("starting DropBoxManagerService", e);
}
try {
@@ -412,14 +441,14 @@ class ServerThread extends Thread {
wallpaper = new WallpaperManagerService(context);
ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Wallpaper Service", e);
+ reportWtf("starting Wallpaper Service", e);
}
try {
Slog.i(TAG, "Audio Service");
ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Audio Service", e);
+ reportWtf("starting Audio Service", e);
}
try {
@@ -427,15 +456,15 @@ class ServerThread extends Thread {
// Listen for dock station changes
dock = new DockObserver(context, power);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting DockObserver", e);
+ reportWtf("starting DockObserver", e);
}
try {
Slog.i(TAG, "Wired Accessory Observer");
// Listen for wired headset changes
- wiredAccessory = new WiredAccessoryObserver(context);
+ new WiredAccessoryObserver(context);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting WiredAccessoryObserver", e);
+ reportWtf("starting WiredAccessoryObserver", e);
}
try {
@@ -444,7 +473,7 @@ class ServerThread extends Thread {
usb = new UsbService(context);
ServiceManager.addService(Context.USB_SERVICE, usb);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting UsbService", e);
+ reportWtf("starting UsbService", e);
}
try {
@@ -452,7 +481,7 @@ class ServerThread extends Thread {
// Listen for UI mode changes
uiMode = new UiModeManagerService(context);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting UiModeManagerService", e);
+ reportWtf("starting UiModeManagerService", e);
}
try {
@@ -468,21 +497,21 @@ class ServerThread extends Thread {
appWidget = new AppWidgetService(context);
ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting AppWidget Service", e);
+ reportWtf("starting AppWidget Service", e);
}
try {
Slog.i(TAG, "Recognition Service");
recognition = new RecognitionManagerService(context);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting Recognition Service", e);
+ reportWtf("starting Recognition Service", e);
}
try {
Slog.i(TAG, "DiskStats Service");
ServiceManager.addService("diskstats", new DiskStatsService(context));
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting DiskStats Service", e);
+ reportWtf("starting DiskStats Service", e);
}
try {
@@ -494,14 +523,14 @@ class ServerThread extends Thread {
ServiceManager.addService("samplingprofiler",
new SamplingProfilerService(context));
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting SamplingProfiler Service", e);
+ reportWtf("starting SamplingProfiler Service", e);
}
try {
Slog.i(TAG, "NetworkTimeUpdateService");
networkTimeUpdater = new NetworkTimeUpdateService(context);
} catch (Throwable e) {
- Slog.e(TAG, "Failure starting NetworkTimeUpdate service");
+ reportWtf("starting NetworkTimeUpdate service", e);
}
}
@@ -522,14 +551,26 @@ class ServerThread extends Thread {
// It is now time to start up the app processes...
if (devicePolicy != null) {
- devicePolicy.systemReady();
+ try {
+ devicePolicy.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Device Policy Service ready", e);
+ }
}
if (notification != null) {
- notification.systemReady();
+ try {
+ notification.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Notification Service ready", e);
+ }
}
- wm.systemReady();
+ try {
+ wm.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Window Manager Service ready", e);
+ }
if (safeMode) {
ActivityManagerService.self().showSafeModeOverlay();
@@ -547,7 +588,8 @@ class ServerThread extends Thread {
power.systemReady();
try {
pm.systemReady();
- } catch (RemoteException e) {
+ } catch (Throwable e) {
+ reportWtf("making Package Manager Service ready", e);
}
// These are needed to propagate to the runnable below.
@@ -569,6 +611,7 @@ class ServerThread extends Thread {
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
final TextServicesManagerService textServiceManagerServiceF = tsms;
+ final StatusBarManagerService statusBarF = statusBar;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
@@ -581,28 +624,96 @@ class ServerThread extends Thread {
Slog.i(TAG, "Making services ready");
startSystemUi(contextF);
- if (batteryF != null) batteryF.systemReady();
- if (networkManagementF != null) networkManagementF.systemReady();
- if (networkStatsF != null) networkStatsF.systemReady();
- if (networkPolicyF != null) networkPolicyF.systemReady();
- if (connectivityF != null) connectivityF.systemReady();
- if (dockF != null) dockF.systemReady();
- if (usbF != null) usbF.systemReady();
- if (uiModeF != null) uiModeF.systemReady();
- if (recognitionF != null) recognitionF.systemReady();
+ try {
+ if (batteryF != null) batteryF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Battery Service ready", e);
+ }
+ try {
+ if (networkManagementF != null) networkManagementF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Network Managment Service ready", e);
+ }
+ try {
+ if (networkStatsF != null) networkStatsF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Network Stats Service ready", e);
+ }
+ try {
+ if (networkPolicyF != null) networkPolicyF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Network Policy Service ready", e);
+ }
+ try {
+ if (connectivityF != null) connectivityF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Connectivity Service ready", e);
+ }
+ try {
+ if (dockF != null) dockF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Dock Service ready", e);
+ }
+ try {
+ if (usbF != null) usbF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making USB Service ready", e);
+ }
+ try {
+ if (uiModeF != null) uiModeF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making UI Mode Service ready", e);
+ }
+ try {
+ if (recognitionF != null) recognitionF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Recognition Service ready", e);
+ }
Watchdog.getInstance().start();
// It is now okay to let the various system services start their
// third party code...
- if (appWidgetF != null) appWidgetF.systemReady(safeMode);
- if (wallpaperF != null) wallpaperF.systemReady();
- if (immF != null) immF.systemReady();
- if (locationF != null) locationF.systemReady();
- if (countryDetectorF != null) countryDetectorF.systemReady();
- if (throttleF != null) throttleF.systemReady();
- if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemReady();
- if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
+ try {
+ if (appWidgetF != null) appWidgetF.systemReady(safeMode);
+ } catch (Throwable e) {
+ reportWtf("making App Widget Service ready", e);
+ }
+ try {
+ if (wallpaperF != null) wallpaperF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Wallpaper Service ready", e);
+ }
+ try {
+ if (immF != null) immF.systemReady(statusBarF);
+ } catch (Throwable e) {
+ reportWtf("making Input Method Service ready", e);
+ }
+ try {
+ if (locationF != null) locationF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Location Service ready", e);
+ }
+ try {
+ if (countryDetectorF != null) countryDetectorF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Country Detector Service ready", e);
+ }
+ try {
+ if (throttleF != null) throttleF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Throttle Service ready", e);
+ }
+ try {
+ if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Network Time Service ready", e);
+ }
+ try {
+ if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Text Services Manager Service ready", e);
+ }
}
});
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 90824a6..321274f 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -41,6 +41,7 @@ import android.service.textservice.SpellCheckerService;
import android.text.TextUtils;
import android.util.Slog;
import android.view.textservice.SpellCheckerInfo;
+import android.view.textservice.SpellCheckerSubtype;
import java.io.IOException;
import java.util.ArrayList;
@@ -172,9 +173,9 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
@Override
public SpellCheckerInfo getCurrentSpellChecker(String locale) {
synchronized (mSpellCheckerMap) {
- String curSpellCheckerId =
+ final String curSpellCheckerId =
Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.SPELL_CHECKER_SERVICE);
+ Settings.Secure.SELECTED_SPELL_CHECKER);
if (DBG) {
Slog.w(TAG, "getCurrentSpellChecker: " + curSpellCheckerId);
}
@@ -185,6 +186,47 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
}
+ // TODO: Save SpellCheckerSubtype by supported languages.
+ @Override
+ public SpellCheckerSubtype getCurrentSpellCheckerSubtype(String locale) {
+ synchronized (mSpellCheckerMap) {
+ final String subtypeHashCodeStr =
+ Settings.Secure.getString(mContext.getContentResolver(),
+ Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE);
+ if (DBG) {
+ Slog.w(TAG, "getCurrentSpellChecker: " + subtypeHashCodeStr);
+ }
+ final SpellCheckerInfo sci = getCurrentSpellChecker(null);
+ if (sci == null || sci.getSubtypeCount() == 0) {
+ if (DBG) {
+ Slog.w(TAG, "Subtype not found.");
+ }
+ return null;
+ }
+ if (TextUtils.isEmpty(subtypeHashCodeStr)) {
+ if (DBG) {
+ Slog.w(TAG, "Return first subtype in " + sci.getId());
+ }
+ // Return the first Subtype if there is no settings for the current subtype.
+ return sci.getSubtypeAt(0);
+ }
+ final int hashCode = Integer.valueOf(subtypeHashCodeStr);
+ for (int i = 0; i < sci.getSubtypeCount(); ++i) {
+ final SpellCheckerSubtype scs = sci.getSubtypeAt(i);
+ if (scs.hashCode() == hashCode) {
+ if (DBG) {
+ Slog.w(TAG, "Return subtype " + scs.hashCode());
+ }
+ return scs;
+ }
+ }
+ if (DBG) {
+ Slog.w(TAG, "Return first subtype in " + sci.getId());
+ }
+ return sci.getSubtypeAt(0);
+ }
+ }
+
@Override
public void getSpellCheckerService(String sciId, String locale,
ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
@@ -253,6 +295,13 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
return;
}
+ @Override
+ public boolean isSpellCheckerEnabled() {
+ synchronized(mSpellCheckerMap) {
+ return isSpellCheckerEnabledLocked();
+ }
+ }
+
private void startSpellCheckerServiceInnerLocked(SpellCheckerInfo info, String locale,
ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
int uid, Bundle bundle) {
@@ -301,7 +350,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
@Override
- public void setCurrentSpellChecker(String sciId) {
+ public void setCurrentSpellChecker(String locale, String sciId) {
synchronized(mSpellCheckerMap) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_SECURE_SETTINGS)
@@ -314,6 +363,34 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
}
+ @Override
+ public void setCurrentSpellCheckerSubtype(String locale, int hashCode) {
+ synchronized(mSpellCheckerMap) {
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires permission "
+ + android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ }
+ setCurrentSpellCheckerSubtypeLocked(hashCode);
+ }
+ }
+
+ @Override
+ public void setSpellCheckerEnabled(boolean enabled) {
+ synchronized(mSpellCheckerMap) {
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires permission "
+ + android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ }
+ setSpellCheckerEnabledLocked(enabled);
+ }
+ }
+
private void setCurrentSpellCheckerLocked(String sciId) {
if (DBG) {
Slog.w(TAG, "setCurrentSpellChecker: " + sciId);
@@ -322,7 +399,59 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
final long ident = Binder.clearCallingIdentity();
try {
Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.SPELL_CHECKER_SERVICE, sciId);
+ Settings.Secure.SELECTED_SPELL_CHECKER, sciId);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void setCurrentSpellCheckerSubtypeLocked(int hashCode) {
+ if (DBG) {
+ Slog.w(TAG, "setCurrentSpellCheckerSubtype: " + hashCode);
+ }
+ final SpellCheckerInfo sci = getCurrentSpellChecker(null);
+ if (sci == null) return;
+ boolean found = false;
+ for (int i = 0; i < sci.getSubtypeCount(); ++i) {
+ if(sci.getSubtypeAt(i).hashCode() == hashCode) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return;
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, String.valueOf(hashCode));
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void setSpellCheckerEnabledLocked(boolean enabled) {
+ if (DBG) {
+ Slog.w(TAG, "setSpellCheckerEnabled: " + enabled);
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_ENABLED, enabled ? 1 : 0);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private boolean isSpellCheckerEnabledLocked() {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ final boolean retval = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_ENABLED, 1) == 1;
+ if (DBG) {
+ Slog.w(TAG, "getSpellCheckerEnabled: " + retval);
+ }
+ return retval;
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 9765f2a..6ceccaf 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -75,7 +75,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
static final String TAG = "WallpaperService";
static final boolean DEBUG = false;
- Object mLock = new Object();
+ final Object mLock = new Object[0];
/**
* Minimum time between crashes of a wallpaper service for us to consider
@@ -118,9 +118,10 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
File changedFile = new File(WALLPAPER_DIR, path);
if (WALLPAPER_FILE.equals(changedFile)) {
notifyCallbacksLocked();
- if (mWallpaperComponent == null ||
- mWallpaperComponent.equals(mImageWallpaperComponent)) {
- bindWallpaperComponentLocked(mWallpaperComponent, true);
+ if (mWallpaperComponent == null || mImageWallpaperPending) {
+ mImageWallpaperPending = false;
+ bindWallpaperComponentLocked(mImageWallpaperComponent, true);
+ saveSettingsLocked();
}
}
}
@@ -133,7 +134,12 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
int mWidth = -1;
int mHeight = -1;
-
+
+ /**
+ * Client is currently writing a new image wallpaper.
+ */
+ boolean mImageWallpaperPending;
+
/**
* Resource name if using a picture from the wallpaper gallery
*/
@@ -343,6 +349,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
final long ident = Binder.clearCallingIdentity();
try {
+ mImageWallpaperPending = false;
bindWallpaperComponentLocked(null, false);
} catch (IllegalArgumentException e) {
// This can happen if the default wallpaper component doesn't
@@ -433,9 +440,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
try {
ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
if (pfd != null) {
- // Bind the wallpaper to an ImageWallpaper
- bindWallpaperComponentLocked(mImageWallpaperComponent, false);
- saveSettingsLocked();
+ mImageWallpaperPending = true;
}
return pfd;
} finally {
@@ -463,6 +468,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
synchronized (mLock) {
final long ident = Binder.clearCallingIdentity();
try {
+ mImageWallpaperPending = false;
bindWallpaperComponentLocked(name, false);
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 800c4fc..7232a94 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -91,6 +91,7 @@ import android.os.Environment;
import android.os.FileObserver;
import android.os.FileUtils;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IPermissionController;
import android.os.Looper;
@@ -3748,6 +3749,10 @@ public final class ActivityManagerService extends ActivityManagerNative
mWindowManager.enableScreenAfterBoot();
}
+ public void showBootMessage(final CharSequence msg, final boolean always) {
+ mWindowManager.showBootMessage(msg, always);
+ }
+
final void finishBooting() {
IntentFilter pkgFilter = new IntentFilter();
pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
@@ -6446,7 +6451,9 @@ public final class ActivityManagerService extends ActivityManagerNative
File fname = new File(systemDir, "called_pre_boots.dat");
return fname;
}
-
+
+ static final int LAST_DONE_VERSION = 10000;
+
private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
File file = getCalledPreBootReceiversFile();
@@ -6454,16 +6461,21 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
fis = new FileInputStream(file);
DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
- int vers = dis.readInt();
- String codename = dis.readUTF();
- if (vers == android.os.Build.VERSION.SDK_INT
- && codename.equals(android.os.Build.VERSION.CODENAME)) {
- int num = dis.readInt();
- while (num > 0) {
- num--;
- String pkg = dis.readUTF();
- String cls = dis.readUTF();
- lastDoneReceivers.add(new ComponentName(pkg, cls));
+ int fvers = dis.readInt();
+ if (fvers == LAST_DONE_VERSION) {
+ String vers = dis.readUTF();
+ String codename = dis.readUTF();
+ String build = dis.readUTF();
+ if (android.os.Build.VERSION.RELEASE.equals(vers)
+ && android.os.Build.VERSION.CODENAME.equals(codename)
+ && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
+ int num = dis.readInt();
+ while (num > 0) {
+ num--;
+ String pkg = dis.readUTF();
+ String cls = dis.readUTF();
+ lastDoneReceivers.add(new ComponentName(pkg, cls));
+ }
}
}
} catch (FileNotFoundException e) {
@@ -6488,8 +6500,10 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
fos = new FileOutputStream(file);
dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
- dos.writeInt(android.os.Build.VERSION.SDK_INT);
+ dos.writeInt(LAST_DONE_VERSION);
+ dos.writeUTF(android.os.Build.VERSION.RELEASE);
dos.writeUTF(android.os.Build.VERSION.CODENAME);
+ dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
dos.writeInt(list.size());
for (int i=0; i<list.size(); i++) {
dos.writeUTF(list.get(i).getPackageName());
@@ -6550,7 +6564,7 @@ public final class ActivityManagerService extends ActivityManagerNative
i--;
}
}
-
+
for (int i=0; i<ris.size(); i++) {
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
@@ -6571,6 +6585,9 @@ public final class ActivityManagerService extends ActivityManagerNative
mDidUpdate = true;
}
writeLastDonePreBootReceivers(doneReceivers);
+ showBootMessage(mContext.getText(
+ R.string.android_upgrading_complete),
+ false);
systemReady(goingCallback);
}
});
@@ -9009,6 +9026,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final static class MemItem {
final String label;
final long pss;
+ ArrayList<MemItem> subitems;
public MemItem(String _label, long _pss) {
label = _label;
@@ -9034,7 +9052,10 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<items.size(); i++) {
MemItem mi = items.get(i);
- pw.print(prefix); pw.printf("%8d Kb: ", mi.pss); pw.println(mi.label);
+ pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
+ if (mi.subitems != null) {
+ dumpMemItems(pw, prefix + " ", mi.subitems, true);
+ }
}
}
@@ -9102,6 +9123,7 @@ public final class ActivityManagerService extends ActivityManagerNative
"Backup", "Services", "Home", "Background"
};
long oomPss[] = new long[oomLabel.length];
+ ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
long totalPss = 0;
@@ -9130,7 +9152,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!isCheckinRequest && mi != null) {
long myTotalPss = mi.getTotalPss();
totalPss += myTotalPss;
- procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")", myTotalPss));
+ MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
+ myTotalPss);
+ procMems.add(pssItem);
nativePss += mi.nativePss;
dalvikPss += mi.dalvikPss;
@@ -9144,6 +9168,10 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
oomPss[oomIndex] += myTotalPss;
+ if (oomProcs[oomIndex] == null) {
+ oomProcs[oomIndex] = new ArrayList<MemItem>();
+ }
+ oomProcs[oomIndex].add(pssItem);
break;
}
}
@@ -9164,7 +9192,9 @@ public final class ActivityManagerService extends ActivityManagerNative
ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
for (int j=0; j<oomPss.length; j++) {
if (oomPss[j] != 0) {
- oomMems.add(new MemItem(oomLabel[j], oomPss[j]));
+ MemItem item = new MemItem(oomLabel[j], oomPss[j]);
+ item.subitems = oomProcs[j];
+ oomMems.add(item);
}
}
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 6f0779f..4ad0f45 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -3163,7 +3163,7 @@ final class ActivityStack {
//Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
if (mMainStack) {
- if (!mService.mBooted && !fromTimeout) {
+ if (!mService.mBooted) {
mService.mBooted = true;
enableScreen = true;
}
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index e61a7f4..87129ea 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -116,6 +116,8 @@ class TaskRecord extends ThumbnailHolder {
if (!askedCompatMode) {
pw.print(prefix); pw.print("askedCompatMode="); pw.println(askedCompatMode);
}
+ pw.print(prefix); pw.print("lastThumbnail="); pw.print(lastThumbnail);
+ pw.print(" lastDescription="); pw.println(lastDescription);
pw.print(prefix); pw.print("lastActiveTime="); pw.print(lastActiveTime);
pw.print(" (inactive for ");
pw.print((getInactiveDuration()/1000)); pw.println("s)");
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 6b65e07..55e0678 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -388,6 +388,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
private final VpnConfig mConfig;
private final String[] mDaemons;
private final String[][] mArguments;
+ private final LocalSocket[] mSockets;
private final String mOuterInterface;
private final LegacyVpnInfo mInfo;
@@ -398,6 +399,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
mConfig = config;
mDaemons = new String[] {"racoon", "mtpd"};
mArguments = new String[][] {racoon, mtpd};
+ mSockets = new LocalSocket[mDaemons.length];
mInfo = new LegacyVpnInfo();
// This is the interface which VPN is running on.
@@ -416,10 +418,14 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
}
public void exit() {
- // We assume that everything is reset after the daemons die.
+ // We assume that everything is reset after stopping the daemons.
interrupt();
- for (String daemon : mDaemons) {
- SystemProperties.set("ctl.stop", daemon);
+ for (LocalSocket socket : mSockets) {
+ try {
+ socket.close();
+ } catch (Exception e) {
+ // ignore
+ }
}
}
@@ -462,15 +468,10 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
checkpoint(false);
mInfo.state = LegacyVpnInfo.STATE_INITIALIZING;
- // First stop the daemons.
- for (String daemon : mDaemons) {
- SystemProperties.set("ctl.stop", daemon);
- }
-
// Wait for the daemons to stop.
for (String daemon : mDaemons) {
String key = "init.svc." + daemon;
- while (!"stopped".equals(SystemProperties.get(key))) {
+ while (!"stopped".equals(SystemProperties.get(key, "stopped"))) {
checkpoint(true);
}
}
@@ -511,27 +512,27 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
}
// Create the control socket.
- LocalSocket socket = new LocalSocket();
+ mSockets[i] = new LocalSocket();
LocalSocketAddress address = new LocalSocketAddress(
daemon, LocalSocketAddress.Namespace.RESERVED);
// Wait for the socket to connect.
while (true) {
try {
- socket.connect(address);
+ mSockets[i].connect(address);
break;
} catch (Exception e) {
// ignore
}
checkpoint(true);
}
- socket.setSoTimeout(500);
+ mSockets[i].setSoTimeout(500);
// Send over the arguments.
- OutputStream out = socket.getOutputStream();
+ OutputStream out = mSockets[i].getOutputStream();
for (String argument : arguments) {
byte[] bytes = argument.getBytes(Charsets.UTF_8);
- if (bytes.length > 0xFFFF) {
+ if (bytes.length >= 0xFFFF) {
throw new IllegalArgumentException("Argument is too large");
}
out.write(bytes.length >> 8);
@@ -539,11 +540,12 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
out.write(bytes);
checkpoint(false);
}
+ out.write(0xFF);
+ out.write(0xFF);
out.flush();
- socket.shutdownOutput();
// Wait for End-of-File.
- InputStream in = socket.getInputStream();
+ InputStream in = mSockets[i].getInputStream();
while (true) {
try {
if (in.read() == -1) {
@@ -554,7 +556,6 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
}
checkpoint(true);
}
- socket.close();
}
// Wait for the daemons to create the new state.
@@ -631,6 +632,13 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
Log.i(TAG, "Aborting", e);
exit();
} finally {
+ // Kill the daemons if they fail to stop.
+ if (mInfo.state == LegacyVpnInfo.STATE_INITIALIZING) {
+ for (String daemon : mDaemons) {
+ SystemProperties.set("ctl.stop", daemon);
+ }
+ }
+
// Do not leave an unstable state.
if (mInfo.state == LegacyVpnInfo.STATE_INITIALIZING ||
mInfo.state == LegacyVpnInfo.STATE_CONNECTING) {
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 14d9665..84880f9 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -27,7 +27,10 @@ import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
+import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.ConnectivityManager.TYPE_WIMAX;
import static android.net.NetworkPolicy.LIMIT_DISABLED;
import static android.net.NetworkPolicy.SNOOZE_NEVER;
import static android.net.NetworkPolicy.WARNING_DISABLED;
@@ -40,8 +43,11 @@ import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
import static android.net.NetworkPolicyManager.dumpPolicy;
import static android.net.NetworkPolicyManager.dumpRules;
import static android.net.NetworkPolicyManager.isUidValidForPolicy;
+import static android.net.NetworkTemplate.MATCH_ETHERNET;
import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
+import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
+import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static com.android.internal.util.Preconditions.checkNotNull;
@@ -104,6 +110,7 @@ import android.util.Xml;
import com.android.internal.R;
import com.android.internal.os.AtomicFile;
import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.Objects;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
import com.google.android.collect.Sets;
@@ -129,8 +136,8 @@ import java.util.List;
import libcore.io.IoUtils;
/**
- * Service that maintains low-level network policy rules and collects usage
- * statistics to drive those rules.
+ * Service that maintains low-level network policy rules, using
+ * {@link NetworkStatsService} statistics to drive those rules.
* <p>
* Derives active rules by combining a given policy with other system status,
* and delivers to listeners, such as {@link ConnectivityManager}, for
@@ -195,6 +202,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private volatile boolean mScreenOn;
private volatile boolean mRestrictBackground;
+ private final boolean mSuppressDefaultPolicy;
+
/** Defined network policies. */
private HashMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = Maps.newHashMap();
/** Currently active network rules for ifaces. */
@@ -210,6 +219,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** Set of over-limit templates that have been notified. */
private HashSet<NetworkTemplate> mOverLimitNotified = Sets.newHashSet();
+ /** Set of currently active {@link Notification} tags. */
+ private HashSet<String> mActiveNotifs = Sets.newHashSet();
+ /** Current values from {@link #setPolicyDataEnable(int, boolean)}. */
+ private SparseBooleanArray mActiveNetworkEnabled = new SparseBooleanArray();
+
/** Foreground at both UID and PID granularity. */
private SparseBooleanArray mUidForeground = new SparseBooleanArray();
private SparseArray<SparseBooleanArray> mUidPidForeground = new SparseArray<
@@ -232,7 +246,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
IPowerManager powerManager, INetworkStatsService networkStats,
INetworkManagementService networkManagement) {
this(context, activityManager, powerManager, networkStats, networkManagement,
- NtpTrustedTime.getInstance(context), getSystemDir());
+ NtpTrustedTime.getInstance(context), getSystemDir(), false);
}
private static File getSystemDir() {
@@ -241,8 +255,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
IPowerManager powerManager, INetworkStatsService networkStats,
- INetworkManagementService networkManagement,
- TrustedTime time, File systemDir) {
+ INetworkManagementService networkManagement, TrustedTime time, File systemDir,
+ boolean suppressDefaultPolicy) {
mContext = checkNotNull(context, "missing context");
mActivityManager = checkNotNull(activityManager, "missing activityManager");
mPowerManager = checkNotNull(powerManager, "missing powerManager");
@@ -254,6 +268,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
+ mSuppressDefaultPolicy = suppressDefaultPolicy;
+
mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
}
@@ -408,6 +424,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// READ_NETWORK_USAGE_HISTORY permission above.
synchronized (mRulesLock) {
+ updateNetworkEnabledLocked();
updateNotificationsLocked();
}
}
@@ -446,6 +463,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Slog.w(TAG, "problem updating network stats");
}
+ updateNetworkEnabledLocked();
updateNotificationsLocked();
}
}
@@ -459,74 +477,70 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private void updateNotificationsLocked() {
if (LOGV) Slog.v(TAG, "updateNotificationsLocked()");
- // try refreshing time source when stale
- if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
- mTime.forceRefresh();
- }
-
- final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
- : System.currentTimeMillis();
+ // keep track of previously active notifications
+ final HashSet<String> beforeNotifs = Sets.newHashSet();
+ beforeNotifs.addAll(mActiveNotifs);
+ mActiveNotifs.clear();
// TODO: when switching to kernel notifications, compute next future
// cycle boundary to recompute notifications.
// examine stats for each active policy
- for (NetworkPolicy policy : mNetworkRules.keySet()) {
+ final long currentTime = currentTimeMillis(true);
+ for (NetworkPolicy policy : mNetworkPolicy.values()) {
+ // ignore policies that aren't relevant to user
+ if (!isTemplateRelevant(policy.template)) continue;
+
final long start = computeLastCycleBoundary(currentTime, policy);
final long end = currentTime;
- final long totalBytes;
- try {
- final NetworkStats stats = mNetworkStats.getSummaryForNetwork(
- policy.template, start, end);
- final NetworkStats.Entry entry = stats.getValues(0, null);
- totalBytes = entry.rxBytes + entry.txBytes;
- } catch (RemoteException e) {
- Slog.w(TAG, "problem reading summary for template " + policy.template);
- continue;
- }
+ final long totalBytes = getTotalBytes(policy.template, start, end);
+ if (totalBytes == UNKNOWN_BYTES) continue;
if (policy.limitBytes != LIMIT_DISABLED && totalBytes >= policy.limitBytes) {
- cancelNotification(policy, TYPE_WARNING);
-
if (policy.lastSnooze >= start) {
- cancelNotification(policy, TYPE_LIMIT);
enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
} else {
- cancelNotification(policy, TYPE_LIMIT_SNOOZED);
enqueueNotification(policy, TYPE_LIMIT, totalBytes);
notifyOverLimitLocked(policy.template);
}
} else {
- cancelNotification(policy, TYPE_LIMIT);
- cancelNotification(policy, TYPE_LIMIT_SNOOZED);
notifyUnderLimitLocked(policy.template);
if (policy.warningBytes != WARNING_DISABLED && totalBytes >= policy.warningBytes) {
enqueueNotification(policy, TYPE_WARNING, totalBytes);
- } else {
- cancelNotification(policy, TYPE_WARNING);
}
}
}
- // clear notifications for non-active policies
- for (NetworkPolicy policy : mNetworkPolicy.values()) {
- if (!mNetworkRules.containsKey(policy)) {
- cancelNotification(policy, TYPE_WARNING);
- cancelNotification(policy, TYPE_LIMIT);
- cancelNotification(policy, TYPE_LIMIT_SNOOZED);
- notifyUnderLimitLocked(policy.template);
- }
- }
-
// ongoing notification when restricting background data
if (mRestrictBackground) {
enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND);
- } else {
- cancelNotification(TAG_ALLOW_BACKGROUND);
}
+
+ // cancel stale notifications that we didn't renew above
+ for (String tag : beforeNotifs) {
+ if (!mActiveNotifs.contains(tag)) {
+ cancelNotification(tag);
+ }
+ }
+ }
+
+ /**
+ * Test if given {@link NetworkTemplate} is relevant to user based on
+ * current device state, such as when {@link #getActiveSubscriberId()}
+ * matches. This is regardless of data connection status.
+ */
+ private boolean isTemplateRelevant(NetworkTemplate template) {
+ switch (template.getMatchRule()) {
+ case MATCH_MOBILE_3G_LOWER:
+ case MATCH_MOBILE_4G:
+ case MATCH_MOBILE_ALL:
+ // mobile templates are relevant when subscriberid is active
+ return Objects.equal(getActiveSubscriberId(), template.getSubscriberId());
+ }
+ return true;
}
/**
@@ -590,9 +604,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
case MATCH_MOBILE_4G:
title = res.getText(R.string.data_usage_4g_limit_title);
break;
- default:
+ case MATCH_MOBILE_ALL:
title = res.getText(R.string.data_usage_mobile_limit_title);
break;
+ case MATCH_WIFI:
+ title = res.getText(R.string.data_usage_wifi_limit_title);
+ break;
+ default:
+ title = null;
+ break;
}
builder.setSmallIcon(com.android.internal.R.drawable.ic_menu_block);
@@ -618,9 +638,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
case MATCH_MOBILE_4G:
title = res.getText(R.string.data_usage_4g_limit_snoozed_title);
break;
- default:
+ case MATCH_MOBILE_ALL:
title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
break;
+ case MATCH_WIFI:
+ title = res.getText(R.string.data_usage_wifi_limit_snoozed_title);
+ break;
+ default:
+ title = null;
+ break;
}
builder.setSmallIcon(R.drawable.ic_menu_info_details);
@@ -641,6 +667,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int[] idReceived = new int[1];
mNotifManager.enqueueNotificationWithTag(
packageName, tag, 0x0, builder.getNotification(), idReceived);
+ mActiveNotifs.add(tag);
} catch (RemoteException e) {
Slog.w(TAG, "problem during enqueueNotification: " + e);
}
@@ -674,19 +701,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int[] idReceived = new int[1];
mNotifManager.enqueueNotificationWithTag(packageName, tag,
0x0, builder.getNotification(), idReceived);
+ mActiveNotifs.add(tag);
} catch (RemoteException e) {
Slog.w(TAG, "problem during enqueueNotification: " + e);
}
}
- /**
- * Cancel any notification for combined {@link NetworkPolicy} and specific
- * type, like {@link #TYPE_LIMIT}.
- */
- private void cancelNotification(NetworkPolicy policy, int type) {
- cancelNotification(buildNotificationTag(policy, type));
- }
-
private void cancelNotification(String tag) {
// TODO: move to NotificationManager once we can mock it
try {
@@ -709,6 +729,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// permission above.
synchronized (mRulesLock) {
ensureActiveMobilePolicyLocked();
+ updateNetworkEnabledLocked();
updateNetworkRulesLocked();
updateNotificationsLocked();
}
@@ -716,6 +737,65 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
};
/**
+ * Proactively control network data connections when they exceed
+ * {@link NetworkPolicy#limitBytes}.
+ */
+ private void updateNetworkEnabledLocked() {
+ if (LOGV) Slog.v(TAG, "updateNetworkEnabledLocked()");
+
+ // TODO: reset any policy-disabled networks when any policy is removed
+ // completely, which is currently rare case.
+
+ final long currentTime = currentTimeMillis(true);
+ for (NetworkPolicy policy : mNetworkPolicy.values()) {
+ // shortcut when policy has no limit
+ if (policy.limitBytes == LIMIT_DISABLED) {
+ setNetworkTemplateEnabled(policy.template, true);
+ continue;
+ }
+
+ final long start = computeLastCycleBoundary(currentTime, policy);
+ final long end = currentTime;
+
+ final long totalBytes = getTotalBytes(policy.template, start, end);
+ if (totalBytes == UNKNOWN_BYTES) continue;
+
+ // disable data connection when over limit and not snoozed
+ final boolean overLimit = policy.limitBytes != LIMIT_DISABLED
+ && totalBytes > policy.limitBytes && policy.lastSnooze < start;
+ setNetworkTemplateEnabled(policy.template, !overLimit);
+ }
+ }
+
+ /**
+ * Control {@link IConnectivityManager#setPolicyDataEnable(int, boolean)}
+ * for the given {@link NetworkTemplate}.
+ */
+ private void setNetworkTemplateEnabled(NetworkTemplate template, boolean enabled) {
+ if (LOGD) Slog.d(TAG, "setting template=" + template + " enabled=" + enabled);
+ switch (template.getMatchRule()) {
+ case MATCH_MOBILE_3G_LOWER:
+ case MATCH_MOBILE_4G:
+ case MATCH_MOBILE_ALL:
+ // TODO: offer more granular control over radio states once
+ // 4965893 is available.
+ if (Objects.equal(getActiveSubscriberId(), template.getSubscriberId())) {
+ setPolicyDataEnable(TYPE_MOBILE, enabled);
+ setPolicyDataEnable(TYPE_WIMAX, enabled);
+ }
+ break;
+ case MATCH_WIFI:
+ setPolicyDataEnable(TYPE_WIFI, enabled);
+ break;
+ case MATCH_ETHERNET:
+ setPolicyDataEnable(TYPE_ETHERNET, enabled);
+ break;
+ default:
+ throw new IllegalArgumentException("unexpected template");
+ }
+ }
+
+ /**
* Examine all connected {@link NetworkState}, looking for
* {@link NetworkPolicy} that need to be enforced. When matches found, set
* remaining quota based on usage cycle and historical stats.
@@ -763,34 +843,19 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
- // try refreshing time source when stale
- if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
- mTime.forceRefresh();
- }
-
- final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
- : System.currentTimeMillis();
-
final HashSet<String> newMeteredIfaces = Sets.newHashSet();
// apply each policy that we found ifaces for; compute remaining data
// based on current cycle and historical stats, and push to kernel.
+ final long currentTime = currentTimeMillis(true);
for (NetworkPolicy policy : mNetworkRules.keySet()) {
final String[] ifaces = mNetworkRules.get(policy);
final long start = computeLastCycleBoundary(currentTime, policy);
final long end = currentTime;
- final NetworkStats stats;
- final long total;
- try {
- stats = mNetworkStats.getSummaryForNetwork(policy.template, start, end);
- final NetworkStats.Entry entry = stats.getValues(0, null);
- total = entry.rxBytes + entry.txBytes;
- } catch (RemoteException e) {
- Slog.w(TAG, "problem reading summary for template " + policy.template);
- continue;
- }
+ final long totalBytes = getTotalBytes(policy.template, start, end);
+ if (totalBytes == UNKNOWN_BYTES) continue;
if (LOGD) {
Slog.d(TAG, "applying policy " + policy.toString() + " to ifaces "
@@ -798,11 +863,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
- final boolean hasWarning = policy.warningBytes != WARNING_DISABLED;
-
if (hasLimit) {
- // remaining "quota" is based on usage in current cycle
- final long quotaBytes = Math.max(0, policy.limitBytes - total);
+ final long quotaBytes;
+ if (policy.lastSnooze >= start) {
+ // snoozing past quota, but we still need to restrict apps,
+ // so push really high quota.
+ quotaBytes = Long.MAX_VALUE;
+ } else {
+ // remaining "quota" bytes are based on total usage in
+ // current cycle. kernel doesn't like 0-byte rules, so we
+ // set 1-byte quota and disable the radio later.
+ quotaBytes = Math.max(1, policy.limitBytes - totalBytes);
+ }
if (ifaces.length > 1) {
// TODO: switch to shared quota once NMS supports
@@ -811,10 +883,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
for (String iface : ifaces) {
removeInterfaceQuota(iface);
- if (quotaBytes > 0) {
- setInterfaceQuota(iface, quotaBytes);
- newMeteredIfaces.add(iface);
- }
+ setInterfaceQuota(iface, quotaBytes);
+ newMeteredIfaces.add(iface);
}
}
}
@@ -837,6 +907,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
*/
private void ensureActiveMobilePolicyLocked() {
if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyLocked()");
+ if (mSuppressDefaultPolicy) return;
+
final String subscriberId = getActiveSubscriberId();
final NetworkIdentity probeIdent = new NetworkIdentity(
TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, false);
@@ -1073,6 +1145,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mNetworkPolicy.put(policy.template, policy);
}
+ updateNetworkEnabledLocked();
updateNetworkRulesLocked();
updateNotificationsLocked();
writePolicyLocked();
@@ -1093,14 +1166,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
public void snoozePolicy(NetworkTemplate template) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
- // try refreshing time source when stale
- if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
- mTime.forceRefresh();
- }
-
- final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
- : System.currentTimeMillis();
-
+ final long currentTime = currentTimeMillis(true);
synchronized (mRulesLock) {
// find and snooze local policy that matches
final NetworkPolicy policy = mNetworkPolicy.get(template);
@@ -1110,6 +1176,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
policy.lastSnooze = currentTime;
+ updateNetworkEnabledLocked();
updateNetworkRulesLocked();
updateNotificationsLocked();
writePolicyLocked();
@@ -1173,22 +1240,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
return null;
}
- final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
- : System.currentTimeMillis();
+ final long currentTime = currentTimeMillis(false);
final long start = computeLastCycleBoundary(currentTime, policy);
final long end = currentTime;
// find total bytes used under policy
- long totalBytes = 0;
- try {
- final NetworkStats stats = mNetworkStats.getSummaryForNetwork(
- policy.template, start, end);
- final NetworkStats.Entry entry = stats.getValues(0, null);
- totalBytes = entry.rxBytes + entry.txBytes;
- } catch (RemoteException e) {
- Slog.w(TAG, "problem reading summary for template " + policy.template);
- }
+ final long totalBytes = getTotalBytes(policy.template, start, end);
+ if (totalBytes == UNKNOWN_BYTES) return null;
// report soft and hard limits under policy
final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes
@@ -1481,12 +1540,54 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ /**
+ * Control {@link IConnectivityManager#setPolicyDataEnable(int, boolean)},
+ * dispatching only when actually changed.
+ */
+ private void setPolicyDataEnable(int networkType, boolean enabled) {
+ synchronized (mActiveNetworkEnabled) {
+ final boolean prevEnabled = mActiveNetworkEnabled.get(networkType, true);
+ if (prevEnabled == enabled) return;
+
+ try {
+ mConnManager.setPolicyDataEnable(networkType, enabled);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "problem setting network enabled", e);
+ }
+
+ mActiveNetworkEnabled.put(networkType, enabled);
+ }
+ }
+
private String getActiveSubscriberId() {
final TelephonyManager telephony = (TelephonyManager) mContext.getSystemService(
Context.TELEPHONY_SERVICE);
return telephony.getSubscriberId();
}
+ private static final long UNKNOWN_BYTES = -1;
+
+ private long getTotalBytes(NetworkTemplate template, long start, long end) {
+ try {
+ final NetworkStats stats = mNetworkStats.getSummaryForNetwork(
+ template, start, end);
+ final NetworkStats.Entry entry = stats.getValues(0, null);
+ return entry.rxBytes + entry.txBytes;
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem reading summary for template " + template);
+ return UNKNOWN_BYTES;
+ }
+ }
+
+ private long currentTimeMillis(boolean allowRefresh) {
+ // try refreshing time source when stale
+ if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE && allowRefresh) {
+ mTime.forceRefresh();
+ }
+
+ return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
+ }
+
private static Intent buildAllowBackgroundDataIntent() {
return new Intent(ACTION_ALLOW_BACKGROUND);
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index dbb8164..b8797d1 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -187,13 +187,15 @@ public class PackageManagerService extends IPackageManager.Stub {
static final int SCAN_NEW_INSTALL = 1<<4;
static final int SCAN_NO_PATHS = 1<<5;
static final int SCAN_UPDATE_TIME = 1<<6;
+ static final int SCAN_DEFER_DEX = 1<<7;
static final int REMOVE_CHATTY = 1<<16;
/**
* Whether verification is enabled by default.
*/
- private static final boolean DEFAULT_VERIFY_ENABLE = true;
+ // STOPSHIP: change this to true
+ private static final boolean DEFAULT_VERIFY_ENABLE = false;
/**
* The default maximum time to wait for the verification agent to return in
@@ -349,6 +351,9 @@ public class PackageManagerService extends IPackageManager.Stub {
/** List of packages waiting for verification. */
final SparseArray<InstallArgs> mPendingVerification = new SparseArray<InstallArgs>();
+ final ArrayList<PackageParser.Package> mDeferredDexOpt =
+ new ArrayList<PackageParser.Package>();
+
/** Token for keys in mPendingVerification. */
private int mPendingVerificationToken = 0;
@@ -907,7 +912,7 @@ public class PackageManagerService extends IPackageManager.Stub {
// Set flag to monitor and not change apk file paths when
// scanning install directories.
- int scanMode = SCAN_MONITOR | SCAN_NO_PATHS;
+ int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX;
if (mNoDexOpt) {
Slog.w(TAG, "Running ENG build: no pre-dexopt!");
scanMode |= SCAN_NO_DEX;
@@ -2899,6 +2904,33 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ public void performBootDexOpt() {
+ ArrayList<PackageParser.Package> pkgs = null;
+ synchronized (mPackages) {
+ if (mDeferredDexOpt.size() > 0) {
+ pkgs = new ArrayList<PackageParser.Package>(mDeferredDexOpt);
+ mDeferredDexOpt.clear();
+ }
+ }
+ if (pkgs != null) {
+ for (int i=0; i<pkgs.size(); i++) {
+ try {
+ ActivityManagerNative.getDefault().showBootMessage(
+ mContext.getResources().getString(
+ com.android.internal.R.string.android_upgrading_apk,
+ i+1, pkgs.size()), true);
+ } catch (RemoteException e) {
+ }
+ PackageParser.Package p = pkgs.get(i);
+ synchronized (mInstallLock) {
+ if (!p.mDidDexOpt) {
+ performDexOptLI(p, false, false);
+ }
+ }
+ }
+ }
+ }
+
public boolean performDexOpt(String packageName) {
enforceSystemOrRoot("Only the system can request dexopt be performed");
@@ -2914,25 +2946,32 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
synchronized (mInstallLock) {
- return performDexOptLI(p, false) == DEX_OPT_PERFORMED;
+ return performDexOptLI(p, false, false) == DEX_OPT_PERFORMED;
}
}
static final int DEX_OPT_SKIPPED = 0;
static final int DEX_OPT_PERFORMED = 1;
+ static final int DEX_OPT_DEFERRED = 2;
static final int DEX_OPT_FAILED = -1;
- private int performDexOptLI(PackageParser.Package pkg, boolean forceDex) {
+ private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer) {
boolean performed = false;
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
String path = pkg.mScanPath;
int ret = 0;
try {
if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
- ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
- !isForwardLocked(pkg));
- pkg.mDidDexOpt = true;
- performed = true;
+ if (!forceDex && defer) {
+ mDeferredDexOpt.add(pkg);
+ return DEX_OPT_DEFERRED;
+ } else {
+ Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
+ ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
+ !isForwardLocked(pkg));
+ pkg.mDidDexOpt = true;
+ performed = true;
+ }
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Apk not found for dexopt: " + path);
@@ -3487,7 +3526,8 @@ public class PackageManagerService extends IPackageManager.Stub {
pkg.mScanPath = path;
if ((scanMode&SCAN_NO_DEX) == 0) {
- if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) {
+ if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0)
+ == DEX_OPT_FAILED) {
mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
return null;
}
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index a01c975..8f51466 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -568,12 +568,9 @@ public class UsbDeviceManager {
notification.sound = null;
notification.vibrate = null;
- Intent intent = new Intent(
- Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- intent.setComponent(new ComponentName("com.android.settings",
- "com.android.settings.UsbSettings"));
+ Intent intent = Intent.makeRestartActivityTask(
+ new ComponentName("com.android.settings",
+ "com.android.settings.UsbSettings"));
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
intent, 0);
notification.setLatestEventInfo(mContext, title, message, pi);
@@ -604,12 +601,9 @@ public class UsbDeviceManager {
notification.sound = null;
notification.vibrate = null;
- Intent intent = new Intent(
- Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- intent.setComponent(new ComponentName("com.android.settings",
- "com.android.settings.DevelopmentSettings"));
+ Intent intent = Intent.makeRestartActivityTask(
+ new ComponentName("com.android.settings",
+ "com.android.settings.DevelopmentSettings"));
PendingIntent pi = PendingIntent.getActivity(mContext, 0,
intent, 0);
notification.setLatestEventInfo(mContext, title, message, pi);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 8fd4f95..e258b1a 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -53,7 +53,6 @@ import android.app.IActivityManager;
import android.app.StatusBarManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -163,6 +162,8 @@ public class WindowManagerService extends IWindowManager.Stub
static final boolean DEBUG_REORDER = false;
static final boolean DEBUG_WALLPAPER = false;
static final boolean DEBUG_DRAG = false;
+ static final boolean DEBUG_SCREEN_ON = false;
+ static final boolean DEBUG_SCREENSHOT = false;
static final boolean SHOW_SURFACE_ALLOC = false;
static final boolean SHOW_TRANSACTIONS = false;
static final boolean HIDE_STACK_CRAWLS = true;
@@ -407,6 +408,8 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mSafeMode;
boolean mDisplayEnabled = false;
boolean mSystemBooted = false;
+ boolean mForceDisplayEnabled = false;
+ boolean mShowingBootMessages = false;
int mInitialDisplayWidth = 0;
int mInitialDisplayHeight = 0;
int mBaseDisplayWidth = 0;
@@ -2187,7 +2190,7 @@ public class WindowManagerService extends IWindowManager.Stub
// to hold off on removing the window until the animation is done.
// If the display is frozen, just remove immediately, since the
// animation wouldn't be seen.
- if (win.mSurface != null && !mDisplayFrozen && mPolicy.isScreenOn()) {
+ if (win.mSurface != null && !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
// If we are not currently running the exit animation, we
// need to see about starting one.
if (wasVisible=win.isWinVisibleLw()) {
@@ -2534,6 +2537,12 @@ public class WindowManagerService extends IWindowManager.Stub
win.mRelayoutCalled = true;
final int oldVisibility = win.mViewVisibility;
win.mViewVisibility = viewVisibility;
+ if (DEBUG_SCREEN_ON) {
+ RuntimeException stack = new RuntimeException();
+ stack.fillInStackTrace();
+ Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
+ + " newVis=" + viewVisibility, stack);
+ }
if (viewVisibility == View.VISIBLE &&
(win.mAppToken == null || !win.mAppToken.clientHidden)) {
displayed = !win.isVisibleLw();
@@ -2554,7 +2563,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (displayed) {
if (win.mSurface != null && !win.mDrawPending
&& !win.mCommitDrawPending && !mDisplayFrozen
- && mPolicy.isScreenOn()) {
+ && mDisplayEnabled && mPolicy.isScreenOn()) {
applyEnterAnimationLocked(win);
}
if ((win.mAttrs.flags
@@ -2847,7 +2856,7 @@ public class WindowManagerService extends IWindowManager.Stub
// frozen, there is no reason to animate and it can cause strange
// artifacts when we unfreeze the display if some different animation
// is running.
- if (!mDisplayFrozen && mPolicy.isScreenOn()) {
+ if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
int anim = mPolicy.selectAnimationLw(win, transit);
int attr = -1;
Animation a = null;
@@ -2933,7 +2942,7 @@ public class WindowManagerService extends IWindowManager.Stub
// frozen, there is no reason to animate and it can cause strange
// artifacts when we unfreeze the display if some different animation
// is running.
- if (!mDisplayFrozen && mPolicy.isScreenOn()) {
+ if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
Animation a;
if (mNextAppTransitionPackage != null) {
a = loadAnimation(mNextAppTransitionPackage, enter ?
@@ -3499,7 +3508,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Prepare app transition: transit=" + transit
+ " mNextAppTransition=" + mNextAppTransition);
- if (!mDisplayFrozen && mPolicy.isScreenOn()) {
+ if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
|| mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
mNextAppTransition = transit;
@@ -3583,7 +3592,7 @@ public class WindowManagerService extends IWindowManager.Stub
// If the display is frozen, we won't do anything until the
// actual window is displayed so there is no reason to put in
// the starting window.
- if (mDisplayFrozen || !mPolicy.isScreenOn()) {
+ if (mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOn()) {
return;
}
@@ -3865,7 +3874,7 @@ public class WindowManagerService extends IWindowManager.Stub
// If we are preparing an app transition, then delay changing
// the visibility of this token until we execute that transition.
- if (!mDisplayFrozen && mPolicy.isScreenOn()
+ if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()
&& mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
// Already in requested state, don't do anything more.
if (wtoken.hiddenRequested != visible) {
@@ -4685,43 +4694,95 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
mSystemBooted = true;
+ hideBootMessagesLocked();
+ // If the screen still doesn't come up after 30 seconds, give
+ // up and turn it on.
+ Message msg = mH.obtainMessage(H.BOOT_TIMEOUT);
+ mH.sendMessageDelayed(msg, 30*1000);
}
performEnableScreen();
}
- public void enableScreenIfNeededLocked() {
+ void enableScreenIfNeededLocked() {
if (mDisplayEnabled) {
return;
}
- if (!mSystemBooted) {
+ if (!mSystemBooted && !mShowingBootMessages) {
return;
}
mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
}
+ public void performBootTimeout() {
+ synchronized(mWindowMap) {
+ if (mDisplayEnabled) {
+ return;
+ }
+ Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
+ mForceDisplayEnabled = true;
+ }
+ performEnableScreen();
+ }
+
public void performEnableScreen() {
synchronized(mWindowMap) {
if (mDisplayEnabled) {
return;
}
- if (!mSystemBooted) {
+ if (!mSystemBooted && !mShowingBootMessages) {
return;
}
- // Don't enable the screen until all existing windows
- // have been drawn.
- final int N = mWindows.size();
- for (int i=0; i<N; i++) {
- WindowState w = mWindows.get(i);
- if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
+ if (!mForceDisplayEnabled) {
+ // Don't enable the screen until all existing windows
+ // have been drawn.
+ boolean haveBootMsg = false;
+ boolean haveApp = false;
+ boolean haveWallpaper = false;
+ boolean haveKeyguard = false;
+ final int N = mWindows.size();
+ for (int i=0; i<N; i++) {
+ WindowState w = mWindows.get(i);
+ if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
+ return;
+ }
+ if (w.isDrawnLw()) {
+ if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) {
+ haveBootMsg = true;
+ } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION) {
+ haveApp = true;
+ } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER) {
+ haveWallpaper = true;
+ } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
+ haveKeyguard = true;
+ }
+ }
+ }
+
+ if (DEBUG_SCREEN_ON) {
+ Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
+ + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
+ + " haveWall=" + haveWallpaper + " haveKeyguard=" + haveKeyguard);
+ }
+
+ // If we are turning on the screen to show the boot message,
+ // don't do it until the boot message is actually displayed.
+ if (!mSystemBooted && !haveBootMsg) {
+ return;
+ }
+
+ // If we are turning on the screen after the boot is completed
+ // normally, don't do so until we have the application and
+ // wallpaper.
+ if (mSystemBooted && ((!haveApp && !haveKeyguard) || !haveWallpaper)) {
return;
}
}
mDisplayEnabled = true;
+ if (DEBUG_SCREEN_ON) Slog.i(TAG, "******************** ENABLING SCREEN!");
if (false) {
- Slog.i(TAG, "ENABLING SCREEN!");
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
this.dump(null, pw, null);
@@ -4749,6 +4810,33 @@ public class WindowManagerService extends IWindowManager.Stub
mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
}
+ public void showBootMessage(final CharSequence msg, final boolean always) {
+ boolean first = false;
+ synchronized(mWindowMap) {
+ if (!mShowingBootMessages) {
+ if (!always) {
+ return;
+ }
+ first = true;
+ }
+ if (mSystemBooted) {
+ return;
+ }
+ mShowingBootMessages = true;
+ mPolicy.showBootMessage(msg, always);
+ }
+ if (first) {
+ performEnableScreen();
+ }
+ }
+
+ public void hideBootMessagesLocked() {
+ if (mShowingBootMessages) {
+ mShowingBootMessages = false;
+ mPolicy.hideBootMessages();
+ }
+ }
+
public void setInTouchMode(boolean mode) {
synchronized(mWindowMap) {
mInTouchMode = mode;
@@ -4909,6 +4997,14 @@ public class WindowManagerService extends IWindowManager.Stub
dh = tmp;
rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
}
+ if (DEBUG_SCREENSHOT) {
+ Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from 0 to " + maxLayer);
+ for (int i=0; i<mWindows.size(); i++) {
+ Slog.i(TAG, mWindows.get(i) + ": " + mWindows.get(i).mLayer
+ + " animLayer=" + mWindows.get(i).mAnimLayer
+ + " surfaceLayer=" + mWindows.get(i).mSurfaceLayer);
+ }
+ }
rawss = Surface.screenshot(dw, dh, 0, maxLayer);
}
@@ -6136,7 +6232,7 @@ public class WindowManagerService extends IWindowManager.Stub
return mSafeMode;
}
- public void systemReady() {
+ public void displayReady() {
synchronized(mWindowMap) {
if (mDisplay != null) {
throw new IllegalStateException("Display already initialized");
@@ -6165,14 +6261,16 @@ public class WindowManagerService extends IWindowManager.Stub
mActivityManager.updateConfiguration(null);
} catch (RemoteException e) {
}
-
- mPolicy.systemReady();
-
+
synchronized (mWindowMap) {
readForcedDisplaySizeLocked();
}
}
+ public void systemReady() {
+ mPolicy.systemReady();
+ }
+
// This is an animation that does nothing: it just immediately finishes
// itself every time it is called. It is used as a stub animation in cases
// where we want to synchronize multiple things that may be animating.
@@ -6207,6 +6305,7 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int DRAG_START_TIMEOUT = 20;
public static final int DRAG_END_TIMEOUT = 21;
public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
+ public static final int BOOT_TIMEOUT = 23;
private Session mLastReportedHold;
@@ -6517,6 +6616,11 @@ public class WindowManagerService extends IWindowManager.Stub
break;
}
+ case BOOT_TIMEOUT: {
+ performBootTimeout();
+ break;
+ }
+
case APP_FREEZE_TIMEOUT: {
synchronized (mWindowMap) {
Slog.w(TAG, "App freeze timeout expired.");
@@ -8268,7 +8372,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (mDimAnimator != null && mDimAnimator.mDimShown) {
animating |= mDimAnimator.updateSurface(dimming, currentTime,
- mDisplayFrozen || !mPolicy.isScreenOn());
+ mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOn());
}
if (!blurring && mBlurShown) {
@@ -8466,12 +8570,44 @@ public class WindowManagerService extends IWindowManager.Stub
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
}
}
-
+
+ mWindowMap.notifyAll();
+
// Check to see if we are now in a state where the screen should
// be enabled, because the window obscured flags have changed.
enableScreenIfNeededLocked();
}
-
+
+ public void waitForAllDrawn() {
+ synchronized (mWindowMap) {
+ while (true) {
+ final int N = mWindows.size();
+ boolean okay = true;
+ for (int i=0; i<N && okay; i++) {
+ WindowState w = mWindows.get(i);
+ if (DEBUG_SCREEN_ON) {
+ Slog.i(TAG, "Window " + w + " vis=" + w.isVisibleLw()
+ + " obscured=" + w.mObscured + " drawn=" + w.isDrawnLw());
+ }
+ if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
+ if (DEBUG_SCREEN_ON) {
+ Slog.i(TAG, "Window not yet drawn: " + w);
+ }
+ okay = false;
+ break;
+ }
+ }
+ if (okay) {
+ return;
+ }
+ try {
+ mWindowMap.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+
/**
* Must be called with the main window manager lock held.
*/
diff --git a/services/sensorservice/Fusion.cpp b/services/sensorservice/Fusion.cpp
index ff4786b..0ab86c3 100644
--- a/services/sensorservice/Fusion.cpp
+++ b/services/sensorservice/Fusion.cpp
@@ -47,9 +47,46 @@ static const float biasVAR = 1e-8; // (rad/s)^2 / s (guessed)
static const float accSTDEV = 0.05f; // m/s^2 (measured 0.08 / CDD 0.05)
static const float magSTDEV = 0.5f; // uT (measured 0.7 / CDD 0.5)
-static const float FREE_FALL_THRESHOLD = 0.981f;
static const float SYMMETRY_TOLERANCE = 1e-10f;
+/*
+ * Accelerometer updates will not be performed near free fall to avoid
+ * ill-conditioning and div by zeros.
+ * Threshhold: 10% of g, in m/s^2
+ */
+static const float FREE_FALL_THRESHOLD = 0.981f;
+static const float FREE_FALL_THRESHOLD_SQ =
+ FREE_FALL_THRESHOLD*FREE_FALL_THRESHOLD;
+
+/*
+ * The geomagnetic-field should be between 30uT and 60uT.
+ * Fields strengths greater than this likely indicate a local magnetic
+ * disturbance which we do not want to update into the fused frame.
+ */
+static const float MAX_VALID_MAGNETIC_FIELD = 100; // uT
+static const float MAX_VALID_MAGNETIC_FIELD_SQ =
+ MAX_VALID_MAGNETIC_FIELD*MAX_VALID_MAGNETIC_FIELD;
+
+/*
+ * Values of the field smaller than this should be ignored in fusion to avoid
+ * ill-conditioning. This state can happen with anomalous local magnetic
+ * disturbances canceling the Earth field.
+ */
+static const float MIN_VALID_MAGNETIC_FIELD = 10; // uT
+static const float MIN_VALID_MAGNETIC_FIELD_SQ =
+ MIN_VALID_MAGNETIC_FIELD*MIN_VALID_MAGNETIC_FIELD;
+
+/*
+ * If the cross product of two vectors has magnitude squared less than this,
+ * we reject it as invalid due to alignment of the vectors.
+ * This threshold is used to check for the case where the magnetic field sample
+ * is parallel to the gravity field, which can happen in certain places due
+ * to magnetic field disturbances.
+ */
+static const float MIN_VALID_CROSS_PRODUCT_MAG = 1.0e-3;
+static const float MIN_VALID_CROSS_PRODUCT_MAG_SQ =
+ MIN_VALID_CROSS_PRODUCT_MAG*MIN_VALID_CROSS_PRODUCT_MAG;
+
// -----------------------------------------------------------------------
template <typename TYPE, size_t C, size_t R>
@@ -240,8 +277,9 @@ void Fusion::handleGyro(const vec3_t& w, float dT) {
status_t Fusion::handleAcc(const vec3_t& a) {
// ignore acceleration data if we're close to free-fall
- if (length(a) < FREE_FALL_THRESHOLD)
+ if (length_squared(a) < FREE_FALL_THRESHOLD_SQ) {
return BAD_VALUE;
+ }
if (!checkInitComplete(ACC, a))
return BAD_VALUE;
@@ -253,15 +291,34 @@ status_t Fusion::handleAcc(const vec3_t& a) {
status_t Fusion::handleMag(const vec3_t& m) {
// the geomagnetic-field should be between 30uT and 60uT
- // reject obviously wrong magnetic-fields
- if (length(m) > 100)
+ // reject if too large to avoid spurious magnetic sources
+ const float magFieldSq = length_squared(m);
+ if (magFieldSq > MAX_VALID_MAGNETIC_FIELD_SQ) {
+ return BAD_VALUE;
+ } else if (magFieldSq < MIN_VALID_MAGNETIC_FIELD_SQ) {
+ // Also reject if too small since we will get ill-defined (zero mag)
+ // cross-products below
return BAD_VALUE;
+ }
if (!checkInitComplete(MAG, m))
return BAD_VALUE;
+ // Orthogonalize the magnetic field to the gravity field, mapping it into
+ // tangent to Earth.
const vec3_t up( getRotationMatrix() * Ba );
const vec3_t east( cross_product(m, up) );
+
+ // If the m and up vectors align, the cross product magnitude will
+ // approach 0.
+ // Reject this case as well to avoid div by zero problems and
+ // ill-conditioning below.
+ if (length_squared(east) < MIN_VALID_CROSS_PRODUCT_MAG_SQ) {
+ return BAD_VALUE;
+ }
+
+ // If we have created an orthogonal magnetic field successfully,
+ // then pass it in as the update.
vec3_t north( cross_product(up, east) );
const float l = 1 / length(north);
diff --git a/services/sensorservice/vec.h b/services/sensorservice/vec.h
index f74ccc5..24f30ff 100644
--- a/services/sensorservice/vec.h
+++ b/services/sensorservice/vec.h
@@ -212,6 +212,15 @@ template <
typename TYPE,
size_t SIZE
>
+TYPE PURE length_squared(const V<TYPE, SIZE>& v) {
+ return dot_product(v, v);
+}
+
+template <
+ template<typename T, size_t S> class V,
+ typename TYPE,
+ size_t SIZE
+>
V<TYPE, SIZE> PURE normalize(const V<TYPE, SIZE>& v) {
return v * (1/length(v));
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 19c7ddd..f8925b8 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -244,9 +244,6 @@ void Layer::setPerFrameData(hwc_layer_t* hwcl) {
}
}
-static inline uint16_t pack565(int r, int g, int b) {
- return (r<<11)|(g<<5)|b;
-}
void Layer::onDraw(const Region& clip) const
{
if (CC_UNLIKELY(mActiveBuffer == 0)) {
@@ -260,7 +257,8 @@ void Layer::onDraw(const Region& clip) const
// figure out if there is something below us
Region under;
- const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
+ const SurfaceFlinger::LayerVector& drawingLayers(
+ mFlinger->mDrawingState.layersSortedByZ);
const size_t count = drawingLayers.size();
for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(drawingLayers[i]);
@@ -276,7 +274,7 @@ void Layer::onDraw(const Region& clip) const
return;
}
- GLenum target = mSurfaceTexture->getCurrentTextureTarget();
+ const GLenum target = GL_TEXTURE_EXTERNAL_OES;
glBindTexture(target, mTextureName);
if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
// TODO: we could be more subtle with isFixedSize()
@@ -439,9 +437,8 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
recomputeVisibleRegions = true;
}
- const GLenum target(mSurfaceTexture->getCurrentTextureTarget());
- glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// update the layer size and release freeze-lock
const Layer::State& front(drawingState());
@@ -541,9 +538,9 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
snprintf(buffer, SIZE,
" "
"format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
- " freezeLock=%p, queued-frames=%d\n",
+ " freezeLock=%p, transform-hint=0x%02x, queued-frames=%d\n",
mFormat, w0, h0, s0,f0,
- getFreezeLock().get(), mQueuedFrames);
+ getFreezeLock().get(), getTransformHint(), mQueuedFrames);
result.append(buffer);
@@ -559,9 +556,21 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const
// need a hardware-protected path to external video sink
usage |= GraphicBuffer::USAGE_PROTECTED;
}
+ usage |= GraphicBuffer::USAGE_HW_COMPOSER;
return usage;
}
+uint32_t Layer::getTransformHint() const {
+ uint32_t orientation = 0;
+ if (!mFlinger->mDebugDisableTransformHint) {
+ orientation = getOrientation();
+ if (orientation & Transform::ROT_INVALID) {
+ orientation = 0;
+ }
+ }
+ return orientation;
+}
+
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5f0be80..d06a35f 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -89,6 +89,7 @@ private:
void onFrameQueued();
virtual sp<ISurface> createSurface();
uint32_t getEffectiveUsage(uint32_t usage) const;
+ uint32_t getTransformHint() const;
bool isCropped() const;
static bool getOpacityForFormat(uint32_t format);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 50afb3d..6fde361 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -93,6 +93,7 @@ SurfaceFlinger::SurfaceFlinger()
mDebugBackground(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
+ mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
@@ -822,7 +823,7 @@ void SurfaceFlinger::handleWorkList()
hwc_layer_t* const cur(hwc.getLayers());
for (size_t i=0 ; cur && i<count ; i++) {
currentLayers[i]->setGeometry(&cur[i]);
- if (mDebugDisableHWC) {
+ if (mDebugDisableHWC || mDebugRegion) {
cur[i].compositionType = HWC_FRAMEBUFFER;
cur[i].flags |= HWC_SKIP_LAYER;
}
@@ -974,6 +975,10 @@ void SurfaceFlinger::debugFlashRegions()
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const uint32_t flags = hw.getFlags();
+ const int32_t height = hw.getHeight();
+ if (mInvalidRegion.isEmpty()) {
+ return;
+ }
if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
(flags & DisplayHardware::BUFFER_PRESERVED))) {
@@ -999,26 +1004,21 @@ void SurfaceFlinger::debugFlashRegions()
while (it != end) {
const Rect& r = *it++;
GLfloat vertices[][2] = {
- { r.left, r.top },
- { r.left, r.bottom },
- { r.right, r.bottom },
- { r.right, r.top }
+ { r.left, height - r.top },
+ { r.left, height - r.bottom },
+ { r.right, height - r.bottom },
+ { r.right, height - r.top }
};
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
- if (mInvalidRegion.isEmpty()) {
- mDirtyRegion.dump("mDirtyRegion");
- mInvalidRegion.dump("mInvalidRegion");
- }
hw.flip(mInvalidRegion);
if (mDebugRegion > 1)
usleep(mDebugRegion * 1000);
glEnable(GL_SCISSOR_TEST);
- //mDirtyRegion.dump("mDirtyRegion");
}
void SurfaceFlinger::drawWormhole() const
@@ -1581,7 +1581,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
HWComposer& hwc(hw.getHwComposer());
snprintf(buffer, SIZE, " h/w composer %s and %s\n",
hwc.initCheck()==NO_ERROR ? "present" : "not present",
- mDebugDisableHWC ? "disabled" : "enabled");
+ (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
result.append(buffer);
hwc.dump(result, buffer, SIZE);
@@ -1660,21 +1660,15 @@ status_t SurfaceFlinger::onTransact(
case 1002: // SHOW_UPDATES
n = data.readInt32();
mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
+ invalidateHwcGeometry();
+ repaintEverything();
return NO_ERROR;
case 1003: // SHOW_BACKGROUND
n = data.readInt32();
mDebugBackground = n ? 1 : 0;
return NO_ERROR;
- case 1008: // toggle use of hw composer
- n = data.readInt32();
- mDebugDisableHWC = n ? 1 : 0;
- invalidateHwcGeometry();
- // fall-through...
case 1004:{ // repaint everything
- Mutex::Autolock _l(mStateLock);
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
- signalEvent();
+ repaintEverything();
return NO_ERROR;
}
case 1005:{ // force transaction
@@ -1690,6 +1684,18 @@ status_t SurfaceFlinger::onTransact(
mFreezeCount = data.readInt32();
mFreezeDisplayTime = 0;
return NO_ERROR;
+ case 1008: // toggle use of hw composer
+ n = data.readInt32();
+ mDebugDisableHWC = n ? 1 : 0;
+ invalidateHwcGeometry();
+ repaintEverything();
+ return NO_ERROR;
+ case 1009: // toggle use of transform hint
+ n = data.readInt32();
+ mDebugDisableTransformHint = n ? 1 : 0;
+ invalidateHwcGeometry();
+ repaintEverything();
+ return NO_ERROR;
case 1010: // interrogate.
reply->writeInt32(0);
reply->writeInt32(0);
@@ -1707,6 +1713,13 @@ status_t SurfaceFlinger::onTransact(
return err;
}
+void SurfaceFlinger::repaintEverything() {
+ Mutex::Autolock _l(mStateLock);
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
+ signalEvent();
+}
+
// ---------------------------------------------------------------------------
status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
@@ -2194,7 +2207,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
return BAD_VALUE;
// make sure none of the layers are protected
- const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+ const LayerVector& layers(mDrawingState.layersSortedByZ);
const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(layers[i]);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1738238..5f8eb08 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -278,6 +278,7 @@ private:
void handleRepaint();
void postFramebuffer();
void composeSurfaces(const Region& dirty);
+ void repaintEverything();
ssize_t addClientLayer(const sp<Client>& client,
@@ -373,6 +374,7 @@ private:
int mDebugBackground;
int mDebugDDMS;
int mDebugDisableHWC;
+ int mDebugDisableTransformHint;
volatile nsecs_t mDebugInSwapBuffers;
nsecs_t mLastSwapBufferTime;
volatile nsecs_t mDebugInTransaction;
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index 79cd0c3..4390ca1 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -57,16 +57,10 @@ status_t SurfaceTextureLayer::queueBuffer(int buf, int64_t timestamp,
status_t res = SurfaceTexture::queueBuffer(buf, timestamp,
outWidth, outHeight, outTransform);
-
sp<Layer> layer(mLayer.promote());
if (layer != NULL) {
- uint32_t orientation = layer->getOrientation();
- if (orientation & Transform::ROT_INVALID) {
- orientation = 0;
- }
- *outTransform = orientation;
+ *outTransform = layer->getTransformHint();
}
-
return res;
}
diff --git a/services/surfaceflinger/TextureManager.cpp b/services/surfaceflinger/TextureManager.cpp
deleted file mode 100644
index bb63c37..0000000
--- a/services/surfaceflinger/TextureManager.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include <hardware/hardware.h>
-
-#include "clz.h"
-#include "DisplayHardware/DisplayHardware.h"
-#include "GLExtensions.h"
-#include "TextureManager.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-TextureManager::TextureManager()
- : mGLExtensions(GLExtensions::getInstance())
-{
-}
-
-GLenum TextureManager::getTextureTarget(const Image* image) {
-#if defined(GL_OES_EGL_image_external)
- switch (image->target) {
- case Texture::TEXTURE_EXTERNAL:
- return GL_TEXTURE_EXTERNAL_OES;
- }
-#endif
- return GL_TEXTURE_2D;
-}
-
-status_t TextureManager::initTexture(Texture* texture)
-{
- if (texture->name != -1UL)
- return INVALID_OPERATION;
-
- GLuint textureName = -1;
- glGenTextures(1, &textureName);
- texture->name = textureName;
- texture->width = 0;
- texture->height = 0;
-
- const GLenum target = GL_TEXTURE_2D;
- glBindTexture(target, textureName);
- glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- return NO_ERROR;
-}
-
-status_t TextureManager::initTexture(Image* pImage, int32_t format)
-{
- if (pImage->name != -1UL)
- return INVALID_OPERATION;
-
- GLuint textureName = -1;
- glGenTextures(1, &textureName);
- pImage->name = textureName;
- pImage->width = 0;
- pImage->height = 0;
-
- GLenum target = GL_TEXTURE_2D;
-#if defined(GL_OES_EGL_image_external)
- if (GLExtensions::getInstance().haveTextureExternal()) {
- if (format && isYuvFormat(format)) {
- target = GL_TEXTURE_EXTERNAL_OES;
- pImage->target = Texture::TEXTURE_EXTERNAL;
- }
- }
-#endif
-
- glBindTexture(target, textureName);
- glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- return NO_ERROR;
-}
-
-bool TextureManager::isSupportedYuvFormat(int format)
-{
- switch (format) {
- case HAL_PIXEL_FORMAT_YV12:
- return true;
- }
- return false;
-}
-
-bool TextureManager::isYuvFormat(int format)
-{
- switch (format) {
- // supported YUV formats
- case HAL_PIXEL_FORMAT_YV12:
- // Legacy/deprecated YUV formats
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- return true;
- }
-
- // Any OEM format needs to be considered
- if (format>=0x100 && format<=0x1FF)
- return true;
-
- return false;
-}
-
-status_t TextureManager::initEglImage(Image* pImage,
- EGLDisplay dpy, const sp<GraphicBuffer>& buffer)
-{
- status_t err = NO_ERROR;
- if (!pImage->dirty) return err;
-
- // free the previous image
- if (pImage->image != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(dpy, pImage->image);
- pImage->image = EGL_NO_IMAGE_KHR;
- }
-
- // construct an EGL_NATIVE_BUFFER_ANDROID
- ANativeWindowBuffer* clientBuf = buffer->getNativeBuffer();
-
- // create the new EGLImageKHR
- const EGLint attrs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_NONE, EGL_NONE
- };
- pImage->image = eglCreateImageKHR(
- dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
- (EGLClientBuffer)clientBuf, attrs);
-
- if (pImage->image != EGL_NO_IMAGE_KHR) {
- if (pImage->name == -1UL) {
- initTexture(pImage, buffer->format);
- }
- const GLenum target = getTextureTarget(pImage);
- glBindTexture(target, pImage->name);
- glEGLImageTargetTexture2DOES(target, (GLeglImageOES)pImage->image);
- GLint error = glGetError();
- if (error != GL_NO_ERROR) {
- LOGE("glEGLImageTargetTexture2DOES(%p) failed err=0x%04x",
- pImage->image, error);
- err = INVALID_OPERATION;
- } else {
- // Everything went okay!
- pImage->dirty = false;
- pImage->width = clientBuf->width;
- pImage->height = clientBuf->height;
- }
- } else {
- LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError());
- err = INVALID_OPERATION;
- }
- return err;
-}
-
-status_t TextureManager::loadTexture(Texture* texture,
- const Region& dirty, const GGLSurface& t)
-{
- if (texture->name == -1UL) {
- status_t err = initTexture(texture);
- LOGE_IF(err, "loadTexture failed in initTexture (%s)", strerror(err));
- if (err != NO_ERROR) return err;
- }
-
- if (texture->target != Texture::TEXTURE_2D)
- return INVALID_OPERATION;
-
- glBindTexture(GL_TEXTURE_2D, texture->name);
-
- /*
- * In OpenGL ES we can't specify a stride with glTexImage2D (however,
- * GL_UNPACK_ALIGNMENT is a limited form of stride).
- * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
- * need to do something reasonable (here creating a bigger texture).
- *
- * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
- *
- * This situation doesn't happen often, but some h/w have a limitation
- * for their framebuffer (eg: must be multiple of 8 pixels), and
- * we need to take that into account when using these buffers as
- * textures.
- *
- * This should never be a problem with POT textures
- */
-
- int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
- unpack = 1 << ((unpack > 3) ? 3 : unpack);
- glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
-
- /*
- * round to POT if needed
- */
- if (!mGLExtensions.haveNpot()) {
- texture->NPOTAdjust = true;
- }
-
- if (texture->NPOTAdjust) {
- // find the smallest power-of-two that will accommodate our surface
- texture->potWidth = 1 << (31 - clz(t.width));
- texture->potHeight = 1 << (31 - clz(t.height));
- if (texture->potWidth < t.width) texture->potWidth <<= 1;
- if (texture->potHeight < t.height) texture->potHeight <<= 1;
- texture->wScale = float(t.width) / texture->potWidth;
- texture->hScale = float(t.height) / texture->potHeight;
- } else {
- texture->potWidth = t.width;
- texture->potHeight = t.height;
- }
-
- Rect bounds(dirty.bounds());
- GLvoid* data = 0;
- if (texture->width != t.width || texture->height != t.height) {
- texture->width = t.width;
- texture->height = t.height;
-
- // texture size changed, we need to create a new one
- bounds.set(Rect(t.width, t.height));
- if (t.width == texture->potWidth &&
- t.height == texture->potHeight) {
- // we can do it one pass
- data = t.data;
- }
-
- if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGB, texture->potWidth, texture->potHeight, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
- } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGBA, texture->potWidth, texture->potHeight, 0,
- GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
- } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
- t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGBA, texture->potWidth, texture->potHeight, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, data);
- } else if (isSupportedYuvFormat(t.format)) {
- // just show the Y plane of YUV buffers
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
- GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
- } else {
- // oops, we don't handle this format!
- LOGE("texture=%d, using format %d, which is not "
- "supported by the GL", texture->name, t.format);
- }
- }
- if (!data) {
- if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
- t.data + bounds.top*t.stride*2);
- } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
- t.data + bounds.top*t.stride*2);
- } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
- t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGBA, GL_UNSIGNED_BYTE,
- t.data + bounds.top*t.stride*4);
- } else if (isSupportedYuvFormat(t.format)) {
- // just show the Y plane of YUV buffers
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_LUMINANCE, GL_UNSIGNED_BYTE,
- t.data + bounds.top*t.stride);
- }
- }
- return NO_ERROR;
-}
-
-void TextureManager::activateTexture(const Texture& texture, bool filter)
-{
- const GLenum target = getTextureTarget(&texture);
- if (target == GL_TEXTURE_2D) {
- glBindTexture(GL_TEXTURE_2D, texture.name);
- glEnable(GL_TEXTURE_2D);
-#if defined(GL_OES_EGL_image_external)
- if (GLExtensions::getInstance().haveTextureExternal()) {
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- }
- } else {
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture.name);
- glEnable(GL_TEXTURE_EXTERNAL_OES);
- glDisable(GL_TEXTURE_2D);
-#endif
- }
-
- if (filter) {
- glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- } else {
- glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
-}
-
-void TextureManager::deactivateTextures()
-{
- glDisable(GL_TEXTURE_2D);
-#if defined(GL_OES_EGL_image_external)
- if (GLExtensions::getInstance().haveTextureExternal()) {
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- }
-#endif
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/surfaceflinger/TextureManager.h b/services/surfaceflinger/TextureManager.h
deleted file mode 100644
index 18c4348..0000000
--- a/services/surfaceflinger/TextureManager.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_TEXTURE_MANAGER_H
-#define ANDROID_TEXTURE_MANAGER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-
-#include <ui/Region.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class GLExtensions;
-class GraphicBuffer;
-
-// ---------------------------------------------------------------------------
-
-struct Image {
- enum { TEXTURE_2D=0, TEXTURE_EXTERNAL=1 };
- Image() : name(-1U), image(EGL_NO_IMAGE_KHR), width(0), height(0),
- dirty(1), target(TEXTURE_2D) { }
- GLuint name;
- EGLImageKHR image;
- GLuint width;
- GLuint height;
- unsigned dirty : 1;
- unsigned target : 1;
-};
-
-struct Texture : public Image {
- Texture() : Image(), NPOTAdjust(0) { }
- GLuint potWidth;
- GLuint potHeight;
- GLfloat wScale;
- GLfloat hScale;
- unsigned NPOTAdjust : 1;
-};
-
-// ---------------------------------------------------------------------------
-
-class TextureManager {
- const GLExtensions& mGLExtensions;
- static status_t initTexture(Image* texture, int32_t format);
- static status_t initTexture(Texture* texture);
- static bool isSupportedYuvFormat(int format);
- static bool isYuvFormat(int format);
- static GLenum getTextureTarget(const Image* pImage);
-public:
-
- TextureManager();
-
- // load bitmap data into the active buffer
- status_t loadTexture(Texture* texture,
- const Region& dirty, const GGLSurface& t);
-
- // make active buffer an EGLImage if needed
- status_t initEglImage(Image* texture,
- EGLDisplay dpy, const sp<GraphicBuffer>& buffer);
-
- // activate a texture
- static void activateTexture(const Texture& texture, bool filter);
-
- // deactivate a texture
- static void deactivateTextures();
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_TEXTURE_MANAGER_H
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 845aa3f..f67d251 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -79,6 +79,7 @@ import com.google.common.util.concurrent.AbstractFuture;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
+import org.easymock.IExpectationSetters;
import java.io.File;
import java.util.LinkedHashSet;
@@ -87,6 +88,8 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import libcore.io.IoUtils;
+
/**
* Tests for {@link NetworkPolicyManagerService}.
*/
@@ -117,6 +120,9 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
private Binder mStubBinder = new Binder();
+ private long mStartTime;
+ private long mElapsedRealtime;
+
private static final int UID_A = android.os.Process.FIRST_APPLICATION_UID + 800;
private static final int UID_B = android.os.Process.FIRST_APPLICATION_UID + 801;
@@ -128,6 +134,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
public void setUp() throws Exception {
super.setUp();
+ setCurrentTimeMillis(TEST_START);
+
// intercept various broadcasts, and pretend that uids have packages
mServiceContext = new BroadcastInterceptingContext(getContext()) {
@Override
@@ -160,8 +168,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
};
mPolicyDir = getContext().getFilesDir();
- for (File file : mPolicyDir.listFiles()) {
- file.delete();
+ if (mPolicyDir.exists()) {
+ IoUtils.deleteContents(mPolicyDir);
}
mActivityManager = createMock(IActivityManager.class);
@@ -173,9 +181,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
mConnManager = createMock(IConnectivityManager.class);
mNotifManager = createMock(INotificationManager.class);
- mService = new NetworkPolicyManagerService(
- mServiceContext, mActivityManager, mPowerManager, mStatsService,
- mNetworkManager, mTime, mPolicyDir);
+ mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mPowerManager,
+ mStatsService, mNetworkManager, mTime, mPolicyDir, true);
mService.bindConnectivityManager(mConnManager);
mService.bindNotificationManager(mNotifManager);
@@ -198,7 +205,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
// expect to answer screen status during systemReady()
expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
- expectTime(System.currentTimeMillis());
+ expectCurrentTime();
replay();
mService.systemReady();
@@ -485,7 +492,6 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
public void testNetworkPolicyAppliedCycleLastMonth() throws Exception {
- long elapsedRealtime = 0;
NetworkState[] state = null;
NetworkStats stats = null;
Future<Void> future;
@@ -494,11 +500,13 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
final long TIME_MAR_10 = 1173484800000L;
final int CYCLE_DAY = 15;
+ setCurrentTimeMillis(TIME_MAR_10);
+
// first, pretend that wifi network comes online. no policy active,
// which means we shouldn't push limit to interface.
state = new NetworkState[] { buildWifi() };
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
- expectTime(TIME_MAR_10 + elapsedRealtime);
+ expectCurrentTime();
expectClearNotifications();
future = expectMeteredIfacesChanged();
@@ -510,10 +518,10 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
// now change cycle to be on 15th, and test in early march, to verify we
// pick cycle day in previous month.
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
- expectTime(TIME_MAR_10 + elapsedRealtime);
+ expectCurrentTime();
// pretend that 512 bytes total have happened
- stats = new NetworkStats(elapsedRealtime, 1)
+ stats = new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, TIME_MAR_10))
.andReturn(stats).atLeastOnce();
@@ -521,8 +529,6 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
// TODO: consider making strongly ordered mock
expectRemoveInterfaceQuota(TEST_IFACE);
expectSetInterfaceQuota(TEST_IFACE, 1536L);
- expectRemoveInterfaceAlert(TEST_IFACE);
- expectSetInterfaceAlert(TEST_IFACE, 512L);
expectClearNotifications();
future = expectMeteredIfacesChanged(TEST_IFACE);
@@ -558,8 +564,6 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
public void testOverWarningLimitNotification() throws Exception {
- long elapsedRealtime = 0;
- long currentTime = 0;
NetworkState[] state = null;
NetworkStats stats = null;
Future<Void> future;
@@ -569,14 +573,18 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
final long TIME_MAR_10 = 1173484800000L;
final int CYCLE_DAY = 15;
+ setCurrentTimeMillis(TIME_MAR_10);
+
// assign wifi policy
- elapsedRealtime = 0;
- currentTime = TIME_MAR_10 + elapsedRealtime;
state = new NetworkState[] {};
+ stats = new NetworkStats(getElapsedRealtime(), 1)
+ .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
{
- expectTime(currentTime);
+ expectCurrentTime();
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
+ expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
+ .andReturn(stats).atLeastOnce();
expectClearNotifications();
future = expectMeteredIfacesChanged();
@@ -589,22 +597,19 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
// bring up wifi network
- elapsedRealtime += MINUTE_IN_MILLIS;
- currentTime = TIME_MAR_10 + elapsedRealtime;
- stats = new NetworkStats(elapsedRealtime, 1)
- .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
+ incrementCurrentTime(MINUTE_IN_MILLIS);
state = new NetworkState[] { buildWifi() };
+ stats = new NetworkStats(getElapsedRealtime(), 1)
+ .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L);
{
- expectTime(currentTime);
+ expectCurrentTime();
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
- expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTime))
+ expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
expectRemoveInterfaceQuota(TEST_IFACE);
expectSetInterfaceQuota(TEST_IFACE, 2048L);
- expectRemoveInterfaceAlert(TEST_IFACE);
- expectSetInterfaceAlert(TEST_IFACE, 1024L);
expectClearNotifications();
future = expectMeteredIfacesChanged(TEST_IFACE);
@@ -616,14 +621,13 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
// go over warning, which should kick notification
- elapsedRealtime += MINUTE_IN_MILLIS;
- currentTime = TIME_MAR_10 + elapsedRealtime;
- stats = new NetworkStats(elapsedRealtime, 1)
+ incrementCurrentTime(MINUTE_IN_MILLIS);
+ stats = new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 1536L, 15L, 0L, 0L);
{
- expectTime(currentTime);
- expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTime))
+ expectCurrentTime();
+ expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
expectForceUpdate();
@@ -637,15 +641,15 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
// go over limit, which should kick notification and dialog
- elapsedRealtime += MINUTE_IN_MILLIS;
- currentTime = TIME_MAR_10 + elapsedRealtime;
- stats = new NetworkStats(elapsedRealtime, 1)
+ incrementCurrentTime(MINUTE_IN_MILLIS);
+ stats = new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 5120L, 512L, 0L, 0L);
{
- expectTime(currentTime);
- expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTime))
+ expectCurrentTime();
+ expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
+ expectPolicyDataEnable(TYPE_WIFI, false).atLeastOnce();
expectForceUpdate();
expectClearNotifications();
@@ -658,21 +662,23 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
}
// now snooze policy, which should remove quota
- elapsedRealtime += MINUTE_IN_MILLIS;
- currentTime = TIME_MAR_10 + elapsedRealtime;
+ incrementCurrentTime(MINUTE_IN_MILLIS);
{
- expectTime(currentTime);
+ expectCurrentTime();
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
- expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTime))
+ expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
+ expectPolicyDataEnable(TYPE_WIFI, true).atLeastOnce();
+ // snoozed interface still has high quota so background data is
+ // still restricted.
expectRemoveInterfaceQuota(TEST_IFACE);
- expectRemoveInterfaceAlert(TEST_IFACE);
+ expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
expectClearNotifications();
tag = expectEnqueueNotification();
- future = expectMeteredIfacesChanged();
+ future = expectMeteredIfacesChanged(TEST_IFACE);
replay();
mService.snoozePolicy(sTemplateWifi);
@@ -700,10 +706,10 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
return new NetworkState(info, prop, null);
}
- private void expectTime(long currentTime) throws Exception {
+ private void expectCurrentTime() throws Exception {
expect(mTime.forceRefresh()).andReturn(false).anyTimes();
expect(mTime.hasCache()).andReturn(true).anyTimes();
- expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes();
+ expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes();
expect(mTime.getCacheAge()).andReturn(0L).anyTimes();
expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
}
@@ -770,6 +776,12 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
return future;
}
+ private <T> IExpectationSetters<T> expectPolicyDataEnable(int type, boolean enabled)
+ throws Exception {
+ mConnManager.setPolicyDataEnable(type, enabled);
+ return expectLastCall();
+ }
+
private static class FutureAnswer extends AbstractFuture<Void> implements IAnswer<Void> {
@Override
public Void get() throws InterruptedException, ExecutionException {
@@ -818,6 +830,23 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
Integer.toString(expected), actualTag.substring(actualTag.lastIndexOf(':') + 1));
}
+ private long getElapsedRealtime() {
+ return mElapsedRealtime;
+ }
+
+ private void setCurrentTimeMillis(long currentTimeMillis) {
+ mStartTime = currentTimeMillis;
+ mElapsedRealtime = 0L;
+ }
+
+ private long currentTimeMillis() {
+ return mStartTime + mElapsedRealtime;
+ }
+
+ private void incrementCurrentTime(long duration) {
+ mElapsedRealtime += duration;
+ }
+
private void replay() {
EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
mNetworkManager, mTime, mConnManager, mNotifManager);