Merge change 5386 into donut
* changes:
Fixes #1940839. Prevents NPE in RelativeLayout when a non-existing View is targeted.
diff --git a/api/current.xml b/api/current.xml
index 658a87c..66bdb28 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -22088,6 +22088,19 @@
<parameter name="position" type="int">
</parameter>
</method>
+<method name="itemForPosition"
+ return="android.app.LauncherActivity.ListItem"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="position" type="int">
+</parameter>
+</method>
<method name="makeListItems"
return="java.util.List<android.app.LauncherActivity.ListItem>"
abstract="false"
@@ -22196,6 +22209,16 @@
visibility="public"
>
</field>
+<field name="resolveInfo"
+ type="android.content.pm.ResolveInfo"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="ListActivity"
extends="android.app.Activity"
@@ -180577,7 +180600,7 @@
<method name="startMethodTracing"
return="void"
abstract="false"
- native="true"
+ native="false"
synchronized="false"
static="true"
final="false"
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index e945056..105d4d2 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -98,7 +98,7 @@
LOGD("CameraService::connect E (pid %d, client %p)", callingPid,
cameraClient->asBinder().get());
- Mutex::Autolock lock(mLock);
+ Mutex::Autolock lock(mServiceLock);
sp<Client> client;
if (mClient != 0) {
sp<Client> currentClient = mClient.promote();
@@ -125,13 +125,14 @@
LOGD("New client (pid %d) connecting, old reference was dangling...",
callingPid);
mClient.clear();
- if (mUsers > 0) {
- LOGD("Still have client, rejected");
- return client;
- }
}
}
+ if (mUsers > 0) {
+ LOGD("Still have client, rejected");
+ return client;
+ }
+
// create a new Client object
client = new Client(this, cameraClient, callingPid);
mClient = client;
@@ -152,7 +153,7 @@
// destructor won't be called with the lock held.
sp<Client> client;
- Mutex::Autolock lock(mLock);
+ Mutex::Autolock lock(mServiceLock);
if (mClient == 0) {
// This happens when we have already disconnected.
@@ -390,8 +391,6 @@
// from the user directly, or called by the destructor.
if (mHardware == 0) return;
- mCameraService->removeClient(mCameraClient);
-
LOGD("hardware teardown");
// Before destroying mHardware, we must make sure it's in the
// idle state.
@@ -402,6 +401,7 @@
mHardware->release();
mHardware.clear();
+ mCameraService->removeClient(mCameraClient);
mCameraService->decUsers();
LOGD("Client::disconnect() X (pid %d)", callingPid);
@@ -661,7 +661,7 @@
sp<Client> client = 0;
CameraService *service = static_cast<CameraService*>(user);
if (service != NULL) {
- Mutex::Autolock ourLock(service->mLock);
+ Mutex::Autolock ourLock(service->mServiceLock);
if (service->mClient != 0) {
client = service->mClient.promote();
if (client == 0) {
@@ -1104,7 +1104,7 @@
result.append(buffer);
write(fd, result.string(), result.size());
} else {
- AutoMutex lock(&mLock);
+ AutoMutex lock(&mServiceLock);
if (mClient != 0) {
sp<Client> currentClient = mClient.promote();
sprintf(buffer, "Client (%p) PID: %d\n",
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 729e539..8b8b54c 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -199,7 +199,7 @@
virtual void incUsers();
virtual void decUsers();
- mutable Mutex mLock;
+ mutable Mutex mServiceLock;
wp<Client> mClient;
#if DEBUG_HEAP_LEAKS
diff --git a/core/java/android/app/LauncherActivity.java b/core/java/android/app/LauncherActivity.java
index 8d249da..accdda9 100644
--- a/core/java/android/app/LauncherActivity.java
+++ b/core/java/android/app/LauncherActivity.java
@@ -60,26 +60,20 @@
* An item in the list
*/
public static class ListItem {
+ public ResolveInfo resolveInfo;
public CharSequence label;
- //public CharSequence description;
public Drawable icon;
public String packageName;
public String className;
public Bundle extras;
ListItem(PackageManager pm, ResolveInfo resolveInfo, IconResizer resizer) {
+ this.resolveInfo = resolveInfo;
label = resolveInfo.loadLabel(pm);
if (label == null && resolveInfo.activityInfo != null) {
label = resolveInfo.activityInfo.name;
}
- /*
- if (resolveInfo.activityInfo != null &&
- resolveInfo.activityInfo.applicationInfo != null) {
- description = resolveInfo.activityInfo.applicationInfo.loadDescription(pm);
- }
- */
-
icon = resizer.createIconThumbnail(resolveInfo.loadIcon(pm));
packageName = resolveInfo.activityInfo.applicationInfo.packageName;
className = resolveInfo.activityInfo.name;
@@ -122,6 +116,14 @@
return intent;
}
+ public ListItem itemForPosition(int position) {
+ if (mActivitiesList == null) {
+ return null;
+ }
+
+ return mActivitiesList.get(position);
+ }
+
public int getCount() {
return mActivitiesList != null ? mActivitiesList.size() : 0;
}
@@ -354,6 +356,16 @@
}
/**
+ * Return the {@link ListItem} for a specific position in our
+ * {@link android.widget.ListView}.
+ * @param position The item to return
+ */
+ protected ListItem itemForPosition(int position) {
+ ActivityAdapter adapter = (ActivityAdapter) mAdapter;
+ return adapter.itemForPosition(position);
+ }
+
+ /**
* Get the base intent to use when running
* {@link PackageManager#queryIntentActivities(Intent, int)}.
*/
diff --git a/core/java/android/backup/AbsoluteFileBackupHelper.java b/core/java/android/backup/AbsoluteFileBackupHelper.java
new file mode 100644
index 0000000..ab24675
--- /dev/null
+++ b/core/java/android/backup/AbsoluteFileBackupHelper.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+package android.backup;
+
+import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileDescriptor;
+
+/**
+ * Like FileBackupHelper, but takes absolute paths for the files instead of
+ * subpaths of getFilesDir()
+ *
+ * @hide
+ */
+public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements BackupHelper {
+ private static final String TAG = "AbsoluteFileBackupHelper";
+
+ Context mContext;
+ String[] mFiles;
+
+ public AbsoluteFileBackupHelper(Context context, String... files) {
+ super(context);
+
+ mContext = context;
+ mFiles = files;
+ }
+
+ /**
+ * Based on oldState, determine which of the files from the application's data directory
+ * need to be backed up, write them to the data stream, and fill in newState with the
+ * state as it exists now.
+ */
+ public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) {
+ // use the file paths as the keys, too
+ performBackup_checked(oldState, data, newState, mFiles, mFiles);
+ }
+
+ public void restoreEntity(BackupDataInputStream data) {
+ // TODO: turn this off before ship
+ Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
+ String key = data.getKey();
+ if (isKeyInList(key, mFiles)) {
+ File f = new File(key);
+ writeFile(f, data);
+ }
+ }
+}
+
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 680fef8..179b9bd 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -17,8 +17,15 @@
package android.content.res;
import android.content.pm.ApplicationInfo;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.Region;
import android.util.DisplayMetrics;
+import android.util.Log;
import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
/**
* CompatibilityInfo class keeps the information about compatibility mode that the application is
@@ -27,6 +34,9 @@
* {@hide}
*/
public class CompatibilityInfo {
+ private static final boolean DBG = false;
+ private static final String TAG = "CompatibilityInfo";
+
/** default compatibility info object for compatible applications */
public static final CompatibilityInfo DEFAULT_COMPATIBILITY_INFO = new CompatibilityInfo();
@@ -41,36 +51,75 @@
public static final int DEFAULT_PORTRAIT_HEIGHT = 480;
/**
+ * The x-shift mode that controls the position of the content or the window under
+ * compatibility mode.
+ * {@see getTranslator}
+ * {@see Translator#mShiftMode}
+ */
+ private static final int X_SHIFT_NONE = 0;
+ private static final int X_SHIFT_CONTENT = 1;
+ private static final int X_SHIFT_AND_CLIP_CONTENT = 2;
+ private static final int X_SHIFT_WINDOW = 3;
+
+
+ /**
+ * A compatibility flags
+ */
+ private int compatibilityFlags;
+
+ /**
+ * A flag mask to tell if the application needs scaling (when mApplicationScale != 1.0f)
+ * {@see compatibilityFlag}
+ */
+ private static final int SCALING_REQUIRED = 1;
+
+ /**
+ * A flag mask to indicates that the application can expand over the original size.
+ * The flag is set to true if
+ * 1) Application declares its expandable in manifest file using <expandable /> or
+ * 2) The screen size is same as (320 x 480) * density.
+ * {@see compatibilityFlag}
+ */
+ private static final int EXPANDABLE = 2;
+
+ /**
+ * A flag mask to tell if the application is configured to be expandable. This differs
+ * from EXPANDABLE in that the application that is not expandable will be
+ * marked as expandable if it runs in (320x 480) * density screen size.
+ */
+ private static final int CONFIGURED_EXPANDABLE = 4;
+
+ private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE;
+
+ /**
* Application's scale.
*/
- public final float mApplicationScale;
+ public final float applicationScale;
/**
* Application's inverted scale.
*/
- public final float mApplicationInvertedScale;
-
- /**
- * A boolean flag to indicates that the application can expand over the original size.
- * The flag is set to true if
- * 1) Application declares its expandable in manifest file using <expandable /> or
- * 2) The screen size is same as (320 x 480) * density.
- */
- public boolean mExpandable;
+ public final float applicationInvertedScale;
+
/**
- * A expandable flag in the configuration.
+ * Window size in Compatibility Mode, in real pixels. This is updated by
+ * {@link DisplayMetrics#updateMetrics}.
*/
- public final boolean mConfiguredExpandable;
+ private int mWidth;
+ private int mHeight;
/**
- * A boolean flag to tell if the application needs scaling (when mApplicationScale != 1.0f)
+ * The x offset to center the window content. In X_SHIFT_WINDOW mode, the offset is added
+ * to the window's layout. In X_SHIFT_CONTENT/X_SHIFT_AND_CLIP_CONTENT mode, the offset
+ * is used to translate the Canvas.
*/
- public final boolean mScalingRequired;
+ private int mXOffset;
public CompatibilityInfo(ApplicationInfo appInfo) {
- mExpandable = mConfiguredExpandable =
- (appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0;
+ if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
+ compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
+ }
float packageDensityScale = -1.0f;
if (appInfo.supportsDensities != null) {
@@ -93,23 +142,323 @@
}
}
if (packageDensityScale > 0.0f) {
- mApplicationScale = packageDensityScale;
+ applicationScale = packageDensityScale;
} else {
- mApplicationScale = DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
+ applicationScale =
+ DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
}
- mApplicationInvertedScale = 1.0f / mApplicationScale;
- mScalingRequired = mApplicationScale != 1.0f;
+ applicationInvertedScale = 1.0f / applicationScale;
+ if (applicationScale != 1.0f) {
+ compatibilityFlags |= SCALING_REQUIRED;
+ }
}
private CompatibilityInfo() {
- mApplicationScale = mApplicationInvertedScale = 1.0f;
- mExpandable = mConfiguredExpandable = true;
- mScalingRequired = false;
+ applicationScale = applicationInvertedScale = 1.0f;
+ compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
}
+ /**
+ * Sets the application's visible rect in compatibility mode.
+ * @param xOffset the application's x offset that is added to center the content.
+ * @param widthPixels the application's width in real pixels on the screen.
+ * @param heightPixels the application's height in real pixels on the screen.
+ */
+ public void setVisibleRect(int xOffset, int widthPixels, int heightPixels) {
+ this.mXOffset = xOffset;
+ mWidth = widthPixels;
+ mHeight = heightPixels;
+ }
+
+ /**
+ * Sets expandable bit in the compatibility flag.
+ */
+ public void setExpandable(boolean expandable) {
+ if (expandable) {
+ compatibilityFlags |= CompatibilityInfo.EXPANDABLE;
+ } else {
+ compatibilityFlags &= ~CompatibilityInfo.EXPANDABLE;
+ }
+ }
+
+ /**
+ * @return true if the application is configured to be expandable.
+ */
+ public boolean isConfiguredExpandable() {
+ return (compatibilityFlags & CompatibilityInfo.CONFIGURED_EXPANDABLE) != 0;
+ }
+
+ /**
+ * @return true if the scaling is required
+ */
+ public boolean isScalingRequired() {
+ return (compatibilityFlags & SCALING_REQUIRED) != 0;
+ }
+
@Override
public String toString() {
- return "CompatibilityInfo{scale=" + mApplicationScale +
- ", expandable=" + mExpandable + "}";
+ return "CompatibilityInfo{scale=" + applicationScale +
+ ", compatibility flag=" + compatibilityFlags + "}";
}
-}
+
+ /**
+ * Returns the translator which can translate the coordinates of the window.
+ * There are five different types of Translator.
+ *
+ * 1) {@link CompatibilityInfo#X_SHIFT_AND_CLIP_CONTENT}
+ * Shift and clip the content of the window at drawing time. Used for activities'
+ * main window (with no gravity).
+ * 2) {@link CompatibilityInfo#X_SHIFT_CONTENT}
+ * Shift the content of the window at drawing time. Used for windows that is created by
+ * an application and expected to be aligned with the application window.
+ * 3) {@link CompatibilityInfo#X_SHIFT_WINDOW}
+ * Create the window with adjusted x- coordinates. This is typically used
+ * in popup window, where it has to be placed relative to main window.
+ * 4) {@link CompatibilityInfo#X_SHIFT_NONE}
+ * No adjustment required, such as dialog.
+ * 5) Same as X_SHIFT_WINDOW, but no scaling. This is used by {@link SurfaceView}, which
+ * does not require scaling, but its window's location has to be adjusted.
+ *
+ * @param params the window's parameter
+ */
+ public Translator getTranslator(WindowManager.LayoutParams params) {
+ if ( (compatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
+ == CompatibilityInfo.EXPANDABLE) {
+ if (DBG) Log.d(TAG, "no translation required");
+ return null;
+ }
+
+ if ((compatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
+ if ((params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) {
+ if (DBG) Log.d(TAG, "translation for surface view selected");
+ return new Translator(X_SHIFT_WINDOW, false, 1.0f, 1.0f);
+ } else {
+ int shiftMode;
+ if (params.gravity == Gravity.NO_GRAVITY) {
+ // For Regular Application window
+ shiftMode = X_SHIFT_AND_CLIP_CONTENT;
+ if (DBG) Log.d(TAG, "shift and clip translator");
+ } else if (params.width == WindowManager.LayoutParams.FILL_PARENT) {
+ // For Regular Application window
+ shiftMode = X_SHIFT_CONTENT;
+ if (DBG) Log.d(TAG, "shift content translator");
+ } else if ((params.gravity & Gravity.LEFT) != 0 && params.x > 0) {
+ shiftMode = X_SHIFT_WINDOW;
+ if (DBG) Log.d(TAG, "shift window translator");
+ } else {
+ shiftMode = X_SHIFT_NONE;
+ if (DBG) Log.d(TAG, "no content/window translator");
+ }
+ return new Translator(shiftMode);
+ }
+ } else if (isScalingRequired()) {
+ return new Translator();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * A helper object to translate the screen and window coordinates back and forth.
+ * @hide
+ */
+ public class Translator {
+ final private int mShiftMode;
+ final public boolean scalingRequired;
+ final public float applicationScale;
+ final public float applicationInvertedScale;
+
+ private Rect mContentInsetsBuffer = null;
+ private Rect mVisibleInsets = null;
+
+ Translator(int shiftMode, boolean scalingRequired, float applicationScale,
+ float applicationInvertedScale) {
+ mShiftMode = shiftMode;
+ this.scalingRequired = scalingRequired;
+ this.applicationScale = applicationScale;
+ this.applicationInvertedScale = applicationInvertedScale;
+ }
+
+ Translator(int shiftMode) {
+ this(shiftMode,
+ isScalingRequired(),
+ CompatibilityInfo.this.applicationScale,
+ CompatibilityInfo.this.applicationInvertedScale);
+ }
+
+ Translator() {
+ this(X_SHIFT_NONE);
+ }
+
+ /**
+ * Translate the screen rect to the application frame.
+ */
+ public void translateRectInScreenToAppWinFrame(Rect rect) {
+ if (rect.isEmpty()) return; // skip if the window size is empty.
+ switch (mShiftMode) {
+ case X_SHIFT_AND_CLIP_CONTENT:
+ rect.intersect(0, 0, mWidth, mHeight);
+ break;
+ case X_SHIFT_CONTENT:
+ rect.intersect(0, 0, mWidth + mXOffset, mHeight);
+ break;
+ case X_SHIFT_WINDOW:
+ case X_SHIFT_NONE:
+ break;
+ }
+ if (scalingRequired) {
+ rect.scale(applicationInvertedScale);
+ }
+ }
+
+ /**
+ * Translate the region in window to screen.
+ */
+ public void translateRegionInWindowToScreen(Region transparentRegion) {
+ switch (mShiftMode) {
+ case X_SHIFT_AND_CLIP_CONTENT:
+ case X_SHIFT_CONTENT:
+ transparentRegion.scale(applicationScale);
+ transparentRegion.translate(mXOffset, 0);
+ break;
+ case X_SHIFT_WINDOW:
+ case X_SHIFT_NONE:
+ transparentRegion.scale(applicationScale);
+ }
+ }
+
+ /**
+ * Apply translation to the canvas that is necessary to draw the content.
+ */
+ public void translateCanvas(Canvas canvas) {
+ if (mShiftMode == X_SHIFT_CONTENT ||
+ mShiftMode == X_SHIFT_AND_CLIP_CONTENT) {
+ // TODO: clear outside when rotation is changed.
+
+ // Translate x-offset only when the content is shifted.
+ canvas.translate(mXOffset, 0);
+ }
+ if (scalingRequired) {
+ canvas.scale(applicationScale, applicationScale);
+ }
+ }
+
+ /**
+ * Translate the motion event captured on screen to the application's window.
+ */
+ public void translateEventInScreenToAppWindow(MotionEvent event) {
+ if (mShiftMode == X_SHIFT_CONTENT ||
+ mShiftMode == X_SHIFT_AND_CLIP_CONTENT) {
+ event.translate(-mXOffset, 0);
+ }
+ if (scalingRequired) {
+ event.scale(applicationInvertedScale);
+ }
+ }
+
+ /**
+ * Translate the window's layout parameter, from application's view to
+ * Screen's view.
+ */
+ public void translateWindowLayout(WindowManager.LayoutParams params) {
+ switch (mShiftMode) {
+ case X_SHIFT_NONE:
+ case X_SHIFT_AND_CLIP_CONTENT:
+ case X_SHIFT_CONTENT:
+ params.scale(applicationScale);
+ break;
+ case X_SHIFT_WINDOW:
+ params.scale(applicationScale);
+ params.x += mXOffset;
+ break;
+ }
+ }
+
+ /**
+ * Translate a Rect in application's window to screen.
+ */
+ public void translateRectInAppWindowToScreen(Rect rect) {
+ // TODO Auto-generated method stub
+ if (scalingRequired) {
+ rect.scale(applicationScale);
+ }
+ switch(mShiftMode) {
+ case X_SHIFT_NONE:
+ case X_SHIFT_WINDOW:
+ break;
+ case X_SHIFT_CONTENT:
+ case X_SHIFT_AND_CLIP_CONTENT:
+ rect.offset(mXOffset, 0);
+ break;
+ }
+ }
+
+ /**
+ * Translate a Rect in screen coordinates into the app window's coordinates.
+ */
+ public void translateRectInScreenToAppWindow(Rect rect) {
+ switch (mShiftMode) {
+ case X_SHIFT_NONE:
+ case X_SHIFT_WINDOW:
+ break;
+ case X_SHIFT_CONTENT: {
+ rect.intersects(mXOffset, 0, rect.right, rect.bottom);
+ int dx = Math.min(mXOffset, rect.left);
+ rect.offset(-dx, 0);
+ break;
+ }
+ case X_SHIFT_AND_CLIP_CONTENT: {
+ rect.intersects(mXOffset, 0, mWidth + mXOffset, mHeight);
+ int dx = Math.min(mXOffset, rect.left);
+ rect.offset(-dx, 0);
+ break;
+ }
+ }
+ if (scalingRequired) {
+ rect.scale(applicationInvertedScale);
+ }
+ }
+
+ /**
+ * Translate the location of the sub window.
+ * @param params
+ */
+ public void translateLayoutParamsInAppWindowToScreen(LayoutParams params) {
+ if (scalingRequired) {
+ params.scale(applicationScale);
+ }
+ switch (mShiftMode) {
+ // the window location on these mode does not require adjustmenet.
+ case X_SHIFT_NONE:
+ case X_SHIFT_WINDOW:
+ break;
+ case X_SHIFT_CONTENT:
+ case X_SHIFT_AND_CLIP_CONTENT:
+ params.x += mXOffset;
+ break;
+ }
+ }
+
+ /**
+ * Translate the content insets in application window to Screen. This uses
+ * the internal buffer for content insets to avoid extra object allocation.
+ */
+ public Rect getTranslatedContentInsets(Rect contentInsets) {
+ if (mContentInsetsBuffer == null) mContentInsetsBuffer = new Rect();
+ mContentInsetsBuffer.set(contentInsets);
+ translateRectInAppWindowToScreen(mContentInsetsBuffer);
+ return mContentInsetsBuffer;
+ }
+
+ /**
+ * Translate the visible insets in application window to Screen. This uses
+ * the internal buffer for content insets to avoid extra object allocation.
+ */
+ public Rect getTranslatedVisbileInsets(Rect visibleInsets) {
+ if (mVisibleInsets == null) mVisibleInsets = new Rect();
+ mVisibleInsets.set(visibleInsets);
+ translateRectInAppWindowToScreen(mVisibleInsets);
+ return mVisibleInsets;
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 71dbd38..cb9d46e 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -158,10 +158,10 @@
}
updateConfiguration(config, metrics);
assets.ensureStringBlocks();
- if (!mCompatibilityInfo.mScalingRequired) {
- mPreloadedDrawables = sPreloadedDrawables;
- } else {
+ if (mCompatibilityInfo.isScalingRequired()) {
mPreloadedDrawables = emptySparseArray();
+ } else {
+ mPreloadedDrawables = sPreloadedDrawables;
}
}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 333c7cb..1214abc 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -573,7 +573,21 @@
* directly to a gid.
*/
public static final native int getGidForName(String name);
-
+
+ /**
+ * Returns a uid for a currently running process.
+ * @param pid the process id
+ * @return the uid of the process, or -1 if the process is not running.
+ * @hide pending API council review
+ */
+ public static final int getUidForPid(int pid) {
+ String[] procStatusLabels = { "Uid:" };
+ long[] procStatusValues = new long[1];
+ procStatusValues[0] = -1;
+ Process.readProcLines("/proc/" + pid + "/status", procStatusLabels, procStatusValues);
+ return (int) procStatusValues[0];
+ }
+
/**
* Set the priority of a thread, based on Linux priorities.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5dc03eb..7356326 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1274,6 +1274,50 @@
public static final String DTMF_TONE_WHEN_DIALING = "dtmf_tone";
/**
+ * CDMA only settings
+ * DTMF tone type played by the dialer when dialing.
+ * 0 = Normal
+ * 1 = Long
+ * @hide
+ */
+ public static final String DTMF_TONE_TYPE_WHEN_DIALING = "dtmf_tone_type";
+
+ /**
+ * CDMA only settings
+ * Emergency Tone 0 = Off
+ * 1 = Alert
+ * 2 = Vibrate
+ * @hide
+ */
+ public static final String EMERGENCY_TONE = "emergency_tone";
+
+ /**
+ * CDMA only settings
+ * Whether the auto retry is enabled. The value is
+ * boolean (1 or 0).
+ * @hide
+ */
+ public static final String CALL_AUTO_RETRY = "call_auto_retry";
+
+ /**
+ * Whether the hearing aid is enabled. The value is
+ * boolean (1 or 0).
+ * @hide
+ */
+ public static final String HEARING_AID = "hearing_aid";
+
+ /**
+ * CDMA only settings
+ * TTY Mode
+ * 0 = OFF
+ * 1 = FULL
+ * 2 = VCO
+ * 3 = HCO
+ * @hide
+ */
+ public static final String TTY_MODE = "tty_mode";
+
+ /**
* Whether the sounds effects (key clicks, lid open ...) are enabled. The value is
* boolean (1 or 0).
*/
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index a095913..d89ada0 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -106,16 +106,8 @@
* {@hide}
*/
public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation) {
- if (compatibilityInfo.mScalingRequired) {
- float invertedRatio = compatibilityInfo.mApplicationInvertedScale;
- density *= invertedRatio;
- scaledDensity *= invertedRatio;
- xdpi *= invertedRatio;
- ydpi *= invertedRatio;
- widthPixels *= invertedRatio;
- heightPixels *= invertedRatio;
- }
- if (!compatibilityInfo.mConfiguredExpandable) {
+ int xOffset = 0;
+ if (!compatibilityInfo.isConfiguredExpandable()) {
// Note: this assume that configuration is updated before calling
// updateMetrics method.
int defaultWidth;
@@ -141,11 +133,13 @@
if (defaultWidth == widthPixels && defaultHeight == heightPixels) {
// the screen size is same as expected size. make it expandable
- compatibilityInfo.mExpandable = true;
+ compatibilityInfo.setExpandable(true);
} else {
- compatibilityInfo.mExpandable = false;
+ compatibilityInfo.setExpandable(false);
// adjust the size only when the device's screen is bigger.
if (defaultWidth < widthPixels) {
+ // content/window's x offset in original pixels
+ xOffset = ((widthPixels - defaultWidth) / 2);
widthPixels = defaultWidth;
}
if (defaultHeight < heightPixels) {
@@ -153,8 +147,19 @@
}
}
}
+ compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels);
+ if (compatibilityInfo.isScalingRequired()) {
+ float invertedRatio = compatibilityInfo.applicationInvertedScale;
+ density *= invertedRatio;
+ scaledDensity *= invertedRatio;
+ xdpi *= invertedRatio;
+ ydpi *= invertedRatio;
+ widthPixels *= invertedRatio;
+ heightPixels *= invertedRatio;
+ }
}
+ @Override
public String toString() {
return "DisplayMetrics{density=" + density + ", width=" + widthPixels +
", height=" + heightPixels + ", scaledDensity=" + scaledDensity +
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ca01448..a224ed3 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -212,28 +212,47 @@
}
/**
- * Scales down the cood of this event by the given scale.
+ * Scales down the coordination of this event by the given scale.
*
* @hide
*/
public void scale(float scale) {
- if (scale != 1.0f) {
- mX *= scale;
- mY *= scale;
- mRawX *= scale;
- mRawY *= scale;
- mSize *= scale;
- mXPrecision *= scale;
- mYPrecision *= scale;
- if (mHistory != null) {
- float[] history = mHistory;
- int length = history.length;
- for (int i = 0; i < length; i += 4) {
- history[i] *= scale; // X
- // history[i + 2] == pressure
- history[i + 1] *= scale; // Y
- history[i + 3] *= scale; // Size, TODO: square this?
- }
+ mX *= scale;
+ mY *= scale;
+ mRawX *= scale;
+ mRawY *= scale;
+ mSize *= scale;
+ mXPrecision *= scale;
+ mYPrecision *= scale;
+ if (mHistory != null) {
+ float[] history = mHistory;
+ int length = history.length;
+ for (int i = 0; i < length; i += 4) {
+ history[i] *= scale; // X
+ history[i + 1] *= scale; // Y
+ // no need to scale pressure ([i+2])
+ history[i + 3] *= scale; // Size, TODO: square this?
+ }
+ }
+ }
+
+ /**
+ * Translate the coordination of the event by given x and y.
+ *
+ * @hide
+ */
+ public void translate(float dx, float dy) {
+ mX += dx;
+ mY += dy;
+ mRawX += dx;
+ mRawY += dx;
+ if (mHistory != null) {
+ float[] history = mHistory;
+ int length = history.length;
+ for (int i = 0; i < length; i += 4) {
+ history[i] += dx; // X
+ history[i + 1] += dy; // Y
+ // no need to translate pressure (i+2) and size (i+3)
}
}
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 082cca2..45b0f0a 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.res.CompatibilityInfo;
+import android.content.res.CompatibilityInfo.Translator;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
@@ -138,24 +139,21 @@
int mFormat = -1;
int mType = -1;
final Rect mSurfaceFrame = new Rect();
- private final CompatibilityInfo mCompatibilityInfo;
+ private Translator mTranslator;
public SurfaceView(Context context) {
super(context);
setWillNotDraw(true);
- mCompatibilityInfo = context.getResources().getCompatibilityInfo();
}
public SurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(true);
- mCompatibilityInfo = context.getResources().getCompatibilityInfo();
}
public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setWillNotDraw(true);
- mCompatibilityInfo = context.getResources().getCompatibilityInfo();
}
/**
@@ -258,9 +256,9 @@
public boolean dispatchTouchEvent(MotionEvent event) {
// SurfaceView uses pre-scaled size unless fixed size is requested. This hook
// scales the event back to the pre-scaled coordinates for such surface.
- if (mRequestedWidth < 0 && mCompatibilityInfo.mScalingRequired) {
+ if (mRequestedWidth < 0 && mTranslator != null) {
MotionEvent scaledBack = MotionEvent.obtain(event);
- scaledBack.scale(mCompatibilityInfo.mApplicationScale);
+ scaledBack.scale(mTranslator.applicationScale);
try {
return super.dispatchTouchEvent(scaledBack);
} finally {
@@ -297,15 +295,18 @@
if (!mHaveFrame) {
return;
}
- float appScale = mCompatibilityInfo.mApplicationScale;
+ mTranslator = ((ViewRoot)getRootView().getParent()).mTranslator;
+
+ float appScale = mTranslator == null ? 1.0f : mTranslator.applicationScale;
int myWidth = mRequestedWidth;
if (myWidth <= 0) myWidth = getWidth();
int myHeight = mRequestedHeight;
if (myHeight <= 0) myHeight = getHeight();
- // Use original size for surface unless fixed size is requested.
- if (mRequestedWidth <= 0 && mCompatibilityInfo.mScalingRequired) {
+ // Use original size if the app specified the size of the view,
+ // and let the flinger to scale up.
+ if (mRequestedWidth <= 0 && mTranslator != null && mTranslator.scalingRequired) {
myWidth *= appScale;
myHeight *= appScale;
}
@@ -325,7 +326,7 @@
+ " visible=" + visibleChanged
+ " left=" + (mLeft != mLocation[0])
+ " top=" + (mTop != mLocation[1]));
-
+
try {
final boolean visible = mVisible = mRequestedVisible;
mLeft = mLocation[0];
@@ -335,16 +336,23 @@
mFormat = mRequestedFormat;
mType = mRequestedType;
- // Scaling window's layout here because mLayout is not used elsewhere.
- mLayout.x = (int) (mLeft * appScale);
- mLayout.y = (int) (mTop * appScale);
- mLayout.width = (int) (getWidth() * appScale);
- mLayout.height = (int) (getHeight() * appScale);
+ // Scaling/Translate window's layout here because mLayout is not used elsewhere.
+
+ // Places the window relative
+ mLayout.x = mLeft;
+ mLayout.y = mTop;
+ mLayout.width = getWidth();
+ mLayout.height = getHeight();
+ if (mTranslator != null) {
+ mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
+ }
+
mLayout.format = mRequestedFormat;
mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_SCALED
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING
;
mLayout.memoryType = mRequestedType;
@@ -371,13 +379,6 @@
visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
mVisibleInsets, mSurface);
- if (mCompatibilityInfo.mScalingRequired) {
- float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
- mContentInsets.scale(invertedScale);
- mVisibleInsets.scale(invertedScale);
- mWinFrame.scale(invertedScale);
- }
-
if (localLOGV) Log.i(TAG, "New surface: " + mSurface
+ ", vis=" + visible + ", frame=" + mWinFrame);
mSurfaceFrame.left = 0;
@@ -446,24 +447,14 @@
private static class MyWindow extends IWindow.Stub {
private final WeakReference<SurfaceView> mSurfaceView;
- private final CompatibilityInfo mCompatibilityInfo;
public MyWindow(SurfaceView surfaceView) {
mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
- mCompatibilityInfo = surfaceView.getContext().getResources().getCompatibilityInfo();
}
public void resized(int w, int h, Rect coveredInsets,
Rect visibleInsets, boolean reportDraw) {
SurfaceView surfaceView = mSurfaceView.get();
- if (mCompatibilityInfo.mScalingRequired) {
- float scale = mCompatibilityInfo.mApplicationInvertedScale;
- w *= scale;
- h *= scale;
- coveredInsets.scale(scale);
- visibleInsets.scale(scale);
- }
-
if (surfaceView != null) {
if (localLOGV) Log.v(
"SurfaceView", surfaceView + " got resized: w=" +
@@ -626,9 +617,6 @@
Canvas c = null;
if (!mDrawingStopped && mWindow != null) {
Rect frame = dirty != null ? dirty : mSurfaceFrame;
- if (mCompatibilityInfo.mScalingRequired) {
- frame.scale(mCompatibilityInfo.mApplicationScale);
- }
try {
c = mSurface.lockCanvas(frame);
} catch (Exception e) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f17f0e4..3bfdde8 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6543,7 +6543,7 @@
boolean changed = false;
if (DBG) {
- System.out.println(this + " View.setFrame(" + left + "," + top + ","
+ Log.d("View", this + " View.setFrame(" + left + "," + top + ","
+ right + "," + bottom + ")");
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index d35b048..65457c5 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -128,13 +128,12 @@
Rect mDirty; // will be a graphics.Region soon
boolean mIsAnimating;
- private CompatibilityInfo mCompatibilityInfo;
+ CompatibilityInfo.Translator mTranslator;
final View.AttachInfo mAttachInfo;
final Rect mTempRect; // used in the transaction to not thrash the heap.
final Rect mVisRect; // used to retrieve visible rect of focused view.
- final Point mVisPoint; // used to retrieve global offset of focused view.
boolean mTraversalScheduled;
boolean mWillDrawSoon;
@@ -218,7 +217,6 @@
mDirty = new Rect();
mTempRect = new Rect();
mVisRect = new Rect();
- mVisPoint = new Point();
mWinFrame = new Rect();
mWindow = new W(this, context);
mInputMethodCallback = new InputMethodCallback(this);
@@ -387,20 +385,25 @@
if (mView == null) {
mView = view;
mWindowAttributes.copyFrom(attrs);
- mCompatibilityInfo = mView.getContext().getResources().getCompatibilityInfo();
+
+ CompatibilityInfo compatibilityInfo =
+ mView.getContext().getResources().getCompatibilityInfo();
+ mTranslator = compatibilityInfo.getTranslator(attrs);
boolean restore = false;
- if (mCompatibilityInfo.mScalingRequired || !mCompatibilityInfo.mExpandable) {
+ if (attrs != null && mTranslator != null) {
restore = true;
- mWindowAttributes.backup();
+ attrs.backup();
+ mTranslator.translateWindowLayout(attrs);
}
- if (!mCompatibilityInfo.mExpandable) {
- adjustWindowAttributesForCompatibleMode(mWindowAttributes);
- }
+ if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs);
+
mSoftInputMode = attrs.softInputMode;
mWindowAttributesChanged = true;
mAttachInfo.mRootView = view;
- mAttachInfo.mScalingRequired = mCompatibilityInfo.mScalingRequired;
- mAttachInfo.mApplicationScale = mCompatibilityInfo.mApplicationScale;
+ mAttachInfo.mScalingRequired =
+ mTranslator == null ? false : mTranslator.scalingRequired;
+ mAttachInfo.mApplicationScale =
+ mTranslator == null ? 1.0f : mTranslator.applicationScale;
if (panelParentView != null) {
mAttachInfo.mPanelParentWindowToken
= panelParentView.getApplicationWindowToken();
@@ -421,15 +424,14 @@
mAttachInfo.mRootView = null;
unscheduleTraversals();
throw new RuntimeException("Adding window failed", e);
+ } finally {
+ if (restore) {
+ attrs.restore();
+ }
}
- if (restore) {
- mWindowAttributes.restore();
- }
-
- if (mCompatibilityInfo.mScalingRequired) {
- mAttachInfo.mContentInsets.scale(
- mCompatibilityInfo.mApplicationInvertedScale);
+ if (mTranslator != null) {
+ mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);
}
mPendingContentInsets.set(mAttachInfo.mContentInsets);
mPendingVisibleInsets.set(0, 0, 0, 0);
@@ -541,14 +543,14 @@
public void invalidateChild(View child, Rect dirty) {
checkThread();
- if (LOCAL_LOGV) Log.v(TAG, "Invalidate child: " + dirty);
- if (mCurScrollY != 0 || mCompatibilityInfo.mScalingRequired) {
+ if (DEBUG_DRAW) Log.v(TAG, "Invalidate child: " + dirty);
+ if (mCurScrollY != 0 || mTranslator != null) {
mTempRect.set(dirty);
if (mCurScrollY != 0) {
mTempRect.offset(0, -mCurScrollY);
}
- if (mCompatibilityInfo.mScalingRequired) {
- mTempRect.scale(mCompatibilityInfo.mApplicationScale);
+ if (mTranslator != null) {
+ mTranslator.translateRectInAppWindowToScreen(mTempRect);
}
dirty = mTempRect;
}
@@ -567,7 +569,7 @@
return null;
}
- public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
+ public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
if (child != mView) {
throw new RuntimeException("child is not mine, honest!");
}
@@ -628,14 +630,14 @@
boolean viewVisibilityChanged = mViewVisibility != viewVisibility
|| mNewSurfaceNeeded;
- float appScale = mCompatibilityInfo.mApplicationScale;
+ float appScale = mAttachInfo.mApplicationScale;
WindowManager.LayoutParams params = null;
if (mWindowAttributesChanged) {
mWindowAttributesChanged = false;
params = lp;
}
-
+ Rect frame = mWinFrame;
if (mFirst) {
fullRedrawNeeded = true;
mLayoutRequested = true;
@@ -660,11 +662,11 @@
//Log.i(TAG, "Screen on initialized: " + attachInfo.mKeepScreenOn);
} else {
- desiredWindowWidth = mWinFrame.width();
- desiredWindowHeight = mWinFrame.height();
+ desiredWindowWidth = frame.width();
+ desiredWindowHeight = frame.height();
if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) {
if (DEBUG_ORIENTATION) Log.v("ViewRoot",
- "View " + host + " resized to: " + mWinFrame);
+ "View " + host + " resized to: " + frame);
fullRedrawNeeded = true;
mLayoutRequested = true;
windowResizesToFitContent = true;
@@ -810,7 +812,6 @@
}
}
- final Rect frame = mWinFrame;
boolean initialized = false;
boolean contentInsetsChanged = false;
boolean visibleInsetsChanged;
@@ -883,7 +884,7 @@
} catch (RemoteException e) {
}
if (DEBUG_ORIENTATION) Log.v(
- "ViewRoot", "Relayout returned: frame=" + mWinFrame + ", surface=" + mSurface);
+ "ViewRoot", "Relayout returned: frame=" + frame + ", surface=" + mSurface);
attachInfo.mWindowLeft = frame.left;
attachInfo.mWindowTop = frame.top;
@@ -958,7 +959,6 @@
if (Config.DEBUG && ViewDebug.profileLayout) {
startTime = SystemClock.elapsedRealtime();
}
-
host.layout(0, 0, host.mMeasuredWidth, host.mMeasuredHeight);
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
@@ -985,7 +985,10 @@
mTmpLocation[1] + host.mBottom - host.mTop);
host.gatherTransparentRegion(mTransparentRegion);
- mTransparentRegion.scale(appScale);
+ if (mTranslator != null) {
+ mTranslator.translateRegionInWindowToScreen(mTransparentRegion);
+ }
+
if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
mPreviousTransparentRegion.set(mTransparentRegion);
// reconfigure window manager
@@ -1016,15 +1019,17 @@
= givenContent.bottom = givenVisible.left = givenVisible.top
= givenVisible.right = givenVisible.bottom = 0;
attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets);
- if (mCompatibilityInfo.mScalingRequired) {
- insets.contentInsets.scale(appScale);
- insets.visibleInsets.scale(appScale);
+ Rect contentInsets = insets.contentInsets;
+ Rect visibleInsets = insets.visibleInsets;
+ if (mTranslator != null) {
+ contentInsets = mTranslator.getTranslatedContentInsets(contentInsets);
+ visibleInsets = mTranslator.getTranslatedVisbileInsets(visibleInsets);
}
if (insetsPending || !mLastGivenInsets.equals(insets)) {
mLastGivenInsets.set(insets);
try {
sWindowSession.setInsets(mWindow, insets.mTouchableInsets,
- insets.contentInsets, insets.visibleInsets);
+ contentInsets, visibleInsets);
} catch (RemoteException e) {
}
}
@@ -1167,8 +1172,8 @@
mCurScrollY = yoff;
fullRedrawNeeded = true;
}
- float appScale = mCompatibilityInfo.mApplicationScale;
- boolean scalingRequired = mCompatibilityInfo.mScalingRequired;
+ float appScale = mAttachInfo.mApplicationScale;
+ boolean scalingRequired = mAttachInfo.mScalingRequired;
Rect dirty = mDirty;
if (mUseGL) {
@@ -1187,8 +1192,8 @@
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
try {
canvas.translate(0, -yoff);
- if (scalingRequired) {
- canvas.scale(appScale, appScale);
+ if (mTranslator != null) {
+ mTranslator.translateCanvas(canvas);
}
mView.draw(canvas);
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
@@ -1239,7 +1244,6 @@
int top = dirty.top;
int right = dirty.right;
int bottom = dirty.bottom;
-
canvas = surface.lockCanvas(dirty);
if (left != dirty.left || top != dirty.top || right != dirty.right ||
@@ -1295,8 +1299,8 @@
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
try {
canvas.translate(0, -yoff);
- if (scalingRequired) {
- canvas.scale(appScale, appScale);
+ if (mTranslator != null) {
+ mTranslator.translateCanvas(canvas);
}
mView.draw(canvas);
} finally {
@@ -1599,10 +1603,9 @@
} else {
didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE;
}
- if (event != null && mCompatibilityInfo.mScalingRequired) {
- event.scale(mCompatibilityInfo.mApplicationInvertedScale);
+ if (event != null && mTranslator != null) {
+ mTranslator.translateEventInScreenToAppWindow(event);
}
-
try {
boolean handled;
if (mView != null && mAdded && event != null) {
@@ -1688,6 +1691,7 @@
case RESIZED:
Rect coveredInsets = ((Rect[])msg.obj)[0];
Rect visibleInsets = ((Rect[])msg.obj)[1];
+
if (mWinFrame.width() == msg.arg1 && mWinFrame.height() == msg.arg2
&& mPendingContentInsets.equals(coveredInsets)
&& mPendingVisibleInsets.equals(visibleInsets)) {
@@ -1722,7 +1726,7 @@
if (mGlWanted && !mUseGL) {
initializeGL();
if (mGlCanvas != null) {
- float appScale = mCompatibilityInfo.mApplicationScale;
+ float appScale = mAttachInfo.mApplicationScale;
mGlCanvas.setViewport(
(int) (mWidth * appScale), (int) (mHeight * appScale));
}
@@ -2356,18 +2360,16 @@
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
+
+ float appScale = mAttachInfo.mApplicationScale;
boolean restore = false;
- float appScale = mCompatibilityInfo.mApplicationScale;
- boolean scalingRequired = mCompatibilityInfo.mScalingRequired;
- if (params != null && !mCompatibilityInfo.mExpandable) {
+ if (params != null && mTranslator != null) {
restore = true;
params.backup();
- adjustWindowAttributesForCompatibleMode(params);
+ mTranslator.translateWindowLayout(params);
}
- if (params != null && scalingRequired) {
- if (!restore) params.backup();
- restore = true;
- params.scale(appScale);
+ if (params != null) {
+ if (DBG) Log.d(TAG, "WindowLayout in layoutWindow:" + params);
}
int relayoutResult = sWindowSession.relayout(
mWindow, params,
@@ -2378,44 +2380,16 @@
if (restore) {
params.restore();
}
- if (scalingRequired) {
- float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
- mPendingContentInsets.scale(invertedScale);
- mPendingVisibleInsets.scale(invertedScale);
- mWinFrame.scale(invertedScale);
+
+ if (mTranslator != null) {
+ mTranslator.translateRectInScreenToAppWinFrame(mWinFrame);
+ mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets);
+ mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets);
}
return relayoutResult;
}
/**
- * Adjust the window's layout parameter for compatibility mode. It replaces FILL_PARENT
- * with the default window size, and centers if the window wanted to fill
- * horizontally.
- *
- * @param attrs the window's layout params to adjust
- */
- private void adjustWindowAttributesForCompatibleMode(WindowManager.LayoutParams attrs) {
- // fix app windows only
- if (attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
- DisplayMetrics metrics = mView.getContext().getResources().getDisplayMetrics();
- // TODO: improve gravity logic
- if (attrs.width == ViewGroup.LayoutParams.FILL_PARENT) {
- attrs.width = metrics.widthPixels;
- attrs.gravity |= Gravity.CENTER_HORIZONTAL;
- mWindowAttributesChanged = attrs == mWindowAttributes;
- }
- if (attrs.height == ViewGroup.LayoutParams.FILL_PARENT) {
- attrs.height = metrics.heightPixels;
- attrs.gravity |= Gravity.TOP;
- mWindowAttributesChanged = attrs == mWindowAttributes;
- }
- if (DEBUG_LAYOUT) {
- Log.d(TAG, "Adjusted Attributes for compatibility : " + attrs);
- }
- }
- }
-
- /**
* {@inheritDoc}
*/
public void playSoundEffect(int effectId) {
@@ -2518,16 +2492,14 @@
+ " visibleInsets=" + visibleInsets.toShortString()
+ " reportDraw=" + reportDraw);
Message msg = obtainMessage(reportDraw ? RESIZED_REPORT :RESIZED);
- if (mCompatibilityInfo.mScalingRequired) {
- float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
- coveredInsets.scale(invertedScale);
- visibleInsets.scale(invertedScale);
- msg.arg1 = (int) (w * invertedScale);
- msg.arg2 = (int) (h * invertedScale);
- } else {
- msg.arg1 = w;
- msg.arg2 = h;
+ if (mTranslator != null) {
+ mTranslator.translateRectInScreenToAppWindow(coveredInsets);
+ mTranslator.translateRectInScreenToAppWindow(visibleInsets);
+ w *= mTranslator.applicationInvertedScale;
+ h *= mTranslator.applicationInvertedScale;
}
+ msg.arg1 = w;
+ msg.arg2 = h;
msg.obj = new Rect[] { new Rect(coveredInsets), new Rect(visibleInsets) };
sendMessage(msg);
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index e295d15..bdb86d7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -483,6 +483,12 @@
* {@hide} */
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
+ /** Window flag: special flag to let a window ignore the compatibility scaling.
+ * This is used by SurfaceView to create a window that does not scale the content.
+ *
+ * {@hide} */
+ public static final int FLAG_NO_COMPATIBILITY_SCALING = 0x00100000;
+
/** Window flag: a special option intended for system dialogs. When
* this flag is set, the window will demand focus unconditionally when
* it is created.
@@ -978,8 +984,9 @@
/**
* Scale the layout params' coordinates and size.
+ * @hide
*/
- void scale(float scale) {
+ public void scale(float scale) {
x *= scale;
y *= scale;
if (width > 0) {
@@ -997,14 +1004,13 @@
void backup() {
int[] backup = mCompatibilityParamsBackup;
if (backup == null) {
- // we backup 5 elements, x, y, width, height and gravity.
- backup = mCompatibilityParamsBackup = new int[5];
+ // we backup 4 elements, x, y, width, height
+ backup = mCompatibilityParamsBackup = new int[4];
}
backup[0] = x;
backup[1] = y;
backup[2] = width;
backup[3] = height;
- backup[4] = gravity;
}
/**
@@ -1018,7 +1024,6 @@
y = backup[1];
width = backup[2];
height = backup[3];
- gravity = backup[4];
}
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index dcba943..ec671d5 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -69,7 +69,24 @@
}
int value;
}
-
+
+ /**
+ * Enum for specifying the WebView's desired density.
+ * FAR makes 100% looking like in 240dpi
+ * MEDIUM makes 100% looking like in 160dpi
+ * CLOSE makes 100% looking like in 120dpi
+ * @hide Pending API council approval
+ */
+ public enum ZoomDensity {
+ FAR(150), // 240dpi
+ MEDIUM(100), // 160dpi
+ CLOSE(75); // 120dpi
+ ZoomDensity(int size) {
+ value = size;
+ }
+ int value;
+ }
+
/**
* Default cache usage pattern Use with {@link #setCacheMode}.
*/
@@ -105,6 +122,8 @@
LOW
}
+ // WebView associated with this WebSettings.
+ private WebView mWebView;
// BrowserFrame used to access the native frame pointer.
private BrowserFrame mBrowserFrame;
// Flag to prevent multiple SYNC messages at one time.
@@ -145,6 +164,7 @@
// Don't need to synchronize the get/set methods as they
// are basic types, also none of these values are used in
// native WebCore code.
+ private ZoomDensity mDefaultZoom = ZoomDensity.MEDIUM;
private RenderPriority mRenderPriority = RenderPriority.NORMAL;
private int mOverrideCacheMode = LOAD_DEFAULT;
private boolean mSaveFormData = true;
@@ -237,9 +257,10 @@
* Package constructor to prevent clients from creating a new settings
* instance.
*/
- WebSettings(Context context) {
+ WebSettings(Context context, WebView webview) {
mEventHandler = new EventHandler();
mContext = context;
+ mWebView = webview;
mDefaultTextEncoding = context.getString(com.android.internal.
R.string.default_text_encoding);
@@ -447,6 +468,31 @@
}
/**
+ * Set the default zoom density of the page. This should be called from UI
+ * thread.
+ * @param zoom A ZoomDensity value
+ * @see WebSettings.ZoomDensity
+ * @hide Pending API council approval
+ */
+ public void setDefaultZoom(ZoomDensity zoom) {
+ if (mDefaultZoom != zoom) {
+ mDefaultZoom = zoom;
+ mWebView.updateDefaultZoomDensity(zoom.value);
+ }
+ }
+
+ /**
+ * Get the default zoom density of the page. This should be called from UI
+ * thread.
+ * @return A ZoomDensity value
+ * @see WebSettings.ZoomDensity
+ * @hide Pending API council approval
+ */
+ public ZoomDensity getDefaultZoom() {
+ return mDefaultZoom;
+ }
+
+ /**
* Enables using light touches to make a selection and activate mouseovers.
*/
public void setLightTouchEnabled(boolean enabled) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 1179c1c..ffd4d90 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -408,7 +408,7 @@
// default scale. Depending on the display density.
static int DEFAULT_SCALE_PERCENT;
- private float DEFAULT_SCALE;
+ private float mDefaultScale;
// set to true temporarily while the zoom control is being dragged
private boolean mPreviewZoomOnly = false;
@@ -640,7 +640,7 @@
mZoomFitPageButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
- zoomWithPreview(DEFAULT_SCALE);
+ zoomWithPreview(mDefaultScale);
updateZoomButtonsEnabled();
}
});
@@ -663,7 +663,7 @@
// or out.
mZoomButtonsController.setZoomInEnabled(canZoomIn);
mZoomButtonsController.setZoomOutEnabled(canZoomOut);
- mZoomFitPageButton.setEnabled(mActualScale != DEFAULT_SCALE);
+ mZoomFitPageButton.setEnabled(mActualScale != mDefaultScale);
}
mZoomOverviewButton.setVisibility(canZoomScrollOut() ? View.VISIBLE:
View.GONE);
@@ -685,7 +685,7 @@
mNavSlop = (int) (16 * density);
// density adjusted scale factors
DEFAULT_SCALE_PERCENT = (int) (100 * density);
- DEFAULT_SCALE = density;
+ mDefaultScale = density;
mActualScale = density;
mInvActualScale = 1 / density;
DEFAULT_MAX_ZOOM_SCALE = 4.0f * density;
@@ -694,6 +694,23 @@
mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE;
}
+ /* package */void updateDefaultZoomDensity(int zoomDensity) {
+ final float density = getContext().getResources().getDisplayMetrics().density
+ * 100 / zoomDensity;
+ if (Math.abs(density - mDefaultScale) > 0.01) {
+ float scaleFactor = density / mDefaultScale;
+ // adjust the limits
+ mNavSlop = (int) (16 * density);
+ DEFAULT_SCALE_PERCENT = (int) (100 * density);
+ DEFAULT_MAX_ZOOM_SCALE = 4.0f * density;
+ DEFAULT_MIN_ZOOM_SCALE = 0.25f * density;
+ mDefaultScale = density;
+ mMaxZoomScale *= scaleFactor;
+ mMinZoomScale *= scaleFactor;
+ setNewZoomScale(mActualScale * scaleFactor, false);
+ }
+ }
+
/* package */ boolean onSavePassword(String schemePlusHost, String username,
String password, final Message resumeMsg) {
boolean rVal = false;
@@ -4172,8 +4189,8 @@
float oldScale = mActualScale;
// snap to DEFAULT_SCALE if it is close
- if (scale > (DEFAULT_SCALE - 0.05) && scale < (DEFAULT_SCALE + 0.05)) {
- scale = DEFAULT_SCALE;
+ if (scale > (mDefaultScale - 0.05) && scale < (mDefaultScale + 0.05)) {
+ scale = mDefaultScale;
}
setNewZoomScale(scale, false);
@@ -4689,7 +4706,7 @@
int initialScale = msg.arg1;
int viewportWidth = msg.arg2;
// start a new page with DEFAULT_SCALE zoom scale.
- float scale = DEFAULT_SCALE;
+ float scale = mDefaultScale;
if (mInitialScale > 0) {
scale = mInitialScale / 100.0f;
} else {
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index e2efb43..e9b2fc0 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -139,7 +139,7 @@
// ready.
mEventHub = new EventHub();
// Create a WebSettings object for maintaining all settings
- mSettings = new WebSettings(mContext);
+ mSettings = new WebSettings(mContext, mWebView);
// The WebIconDatabase needs to be initialized within the UI thread so
// just request the instance here.
WebIconDatabase.getInstance();
@@ -1560,6 +1560,20 @@
// set the viewport settings from WebKit
setViewportSettingsFromNative();
+ // adjust the default scale to match the density
+ if (WebView.DEFAULT_SCALE_PERCENT != 100) {
+ float adjust = WebView.DEFAULT_SCALE_PERCENT / 100;
+ if (mViewportInitialScale > 0) {
+ mViewportInitialScale *= adjust;
+ }
+ if (mViewportMinimumScale > 0) {
+ mViewportMinimumScale *= adjust;
+ }
+ if (mViewportMaximumScale > 0) {
+ mViewportMaximumScale *= adjust;
+ }
+ }
+
// infer the values if they are not defined.
if (mViewportWidth == 0) {
if (mViewportInitialScale == 0) {
@@ -1586,7 +1600,7 @@
mViewportMaximumScale = mViewportInitialScale;
} else if (mViewportInitialScale == 0) {
mViewportInitialScale = mViewportMaximumScale;
- }
+ }
}
if (mViewportWidth < 0
&& mViewportInitialScale == WebView.DEFAULT_SCALE_PERCENT) {
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index bd6edfb..0c2cd55 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -990,7 +990,7 @@
int bottomEdge = displayFrame.bottom;
if (ignoreBottomDecorations) {
- bottomEdge = WindowManagerImpl.getDefault().getDefaultDisplay().getHeight();
+ bottomEdge = anchor.getContext().getResources().getDisplayMetrics().heightPixels;
}
final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
diff --git a/core/java/com/android/internal/backup/SystemBackupAgent.java b/core/java/com/android/internal/backup/SystemBackupAgent.java
new file mode 100644
index 0000000..6b396d7
--- /dev/null
+++ b/core/java/com/android/internal/backup/SystemBackupAgent.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+package com.android.internal.backup;
+
+import android.backup.AbsoluteFileBackupHelper;
+import android.backup.BackupHelperAgent;
+
+/**
+ * Backup agent for various system-managed data
+ */
+public class SystemBackupAgent extends BackupHelperAgent {
+ // the set of files that we back up whole, as absolute paths
+ String[] mFiles = {
+ /* WallpaperService.WALLPAPER_FILE */
+ "/data/data/com.android.settings/files/wallpaper",
+ };
+
+ public void onCreate() {
+ addHelper("system_files", new AbsoluteFileBackupHelper(this, mFiles));
+ }
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index fc4a9c4..a03802d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -2836,14 +2836,12 @@
* @param name process name
* @return the statistics object for the process
*/
- public Uid.Proc getProcessStatsLocked(String name) {
+ public Uid.Proc getProcessStatsLocked(String name, int pid) {
int uid;
if (mUidCache.containsKey(name)) {
uid = mUidCache.get(name);
} else {
- // TODO: Find the actual uid from /proc/pid/status. For now use the hashcode of the
- // process name
- uid = name.hashCode();
+ uid = Process.getUidForPid(pid);
mUidCache.put(name, uid);
}
Uid u = getUidStatsLocked(uid);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index df6151d..7f24dcc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1000,6 +1000,7 @@
android:hasCode="false"
android:label="@string/android_system_label"
android:allowClearUserData="false"
+ android:backupAgent="com.android.internal.backup.SystemBackupAgent"
android:icon="@drawable/ic_launcher_android">
<activity android:name="com.android.internal.app.ChooserActivity"
android:theme="@style/Theme.Dialog.Alert"
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index b2f3557..660b469 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -592,6 +592,21 @@
loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
R.integer.def_screen_off_timeout);
+ // Set default cdma emergency tone
+ loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
+
+ // Set default cdma call auto retry
+ loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
+
+ // Set default cdma DTMF type
+ loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
+
+ // Set default hearing aid
+ loadSetting(stmt, Settings.System.HEARING_AID, 0);
+
+ // Set default tty mode
+ loadSetting(stmt, Settings.System.TTY_MODE, 0);
+
loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
R.bool.def_airplane_mode_on);
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 6fa3141..6e6e121 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -424,6 +424,11 @@
return sr;
}
+ private void broadcastTtsQueueProcessingCompleted(){
+ Intent i = new Intent(Intent.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
+ sendBroadcast(i);
+ }
+
private void dispatchSpeechCompletedCallbacks(String mark) {
Log.i("TTS callback", "dispatch started");
// Broadcast to all clients the new value.
@@ -449,11 +454,7 @@
}
if (mSpeechQueue.size() < 1) {
mIsSpeaking = false;
- // Dispatch a completion here as this is the
- // only place where speech completes normally.
- // Nothing left to say in the queue is a special case
- // that is always a "mark" - associated text is null.
- dispatchSpeechCompletedCallbacks("");
+ broadcastTtsQueueProcessingCompleted();
return;
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index fdd4617b..efa6179 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -76,8 +76,7 @@
private static final boolean DEBUG = true;
// Default time to wait after data changes before we back up the data
- private static final long COLLECTION_INTERVAL = 1000;
- //private static final long COLLECTION_INTERVAL = 3 * 60 * 1000;
+ private static final long COLLECTION_INTERVAL = 3 * 60 * 1000;
private static final int MSG_RUN_BACKUP = 1;
private static final int MSG_RUN_FULL_BACKUP = 2;
@@ -360,7 +359,8 @@
if (DEBUG) {
Log.v(TAG, "Adding " + targetPkgs.size() + " backup participants:");
for (PackageInfo p : targetPkgs) {
- Log.v(TAG, " " + p + " agent=" + p.applicationInfo.backupAgentName);
+ Log.v(TAG, " " + p + " agent=" + p.applicationInfo.backupAgentName
+ + " uid=" + p.applicationInfo.uid);
}
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 048669a..972aa98 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -968,35 +968,7 @@
if (Config.LOGV) Log.v(TAG, "getActivityInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLP(a.info, flags)) {
- ActivityInfo ainfo = PackageParser.generateActivityInfo(a, flags);
- if (ainfo != null) {
- ApplicationInfo appInfo = getApplicationInfo(component.getPackageName(),
- PackageManager.GET_SUPPORTS_DENSITIES);
- if (appInfo != null &&
- (appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) == 0) {
- // Check if the screen size is same as what the application expect.
- CompatibilityInfo info = new CompatibilityInfo(appInfo);
- DisplayMetrics metrics = new DisplayMetrics();
- metrics.setTo(mMetrics);
- int orientation = mMetrics.widthPixels > mMetrics.heightPixels ?
- Configuration.ORIENTATION_LANDSCAPE :
- Configuration.ORIENTATION_PORTRAIT;
- metrics.updateMetrics(info, orientation);
- if (!info.mExpandable) {
- // Don't allow an app that cannot expand to handle rotation.
- ainfo.configChanges &= ~ ActivityInfo.CONFIG_ORIENTATION;
- } else {
- appInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
- }
- if (DEBUG_SETTINGS) {
- Log.d(TAG, "component=" + component +
- ", expandable:" +
- ((appInfo.flags &
- ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0));
- }
- }
- }
- return ainfo;
+ return PackageParser.generateActivityInfo(a, flags);
}
if (mResolveComponentName.equals(component)) {
return mResolveActivity;
diff --git a/services/java/com/android/server/WallpaperService.java b/services/java/com/android/server/WallpaperService.java
index 5532894..d921baf 100644
--- a/services/java/com/android/server/WallpaperService.java
+++ b/services/java/com/android/server/WallpaperService.java
@@ -18,8 +18,10 @@
import static android.os.FileObserver.*;
import static android.os.ParcelFileDescriptor.*;
+
import android.app.IWallpaperService;
import android.app.IWallpaperServiceCallback;
+import android.backup.BackupManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -154,7 +156,16 @@
public ParcelFileDescriptor setWallpaper() {
checkPermission(android.Manifest.permission.SET_WALLPAPER);
try {
- return ParcelFileDescriptor.open(WALLPAPER_FILE, MODE_CREATE|MODE_READ_WRITE);
+ ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE,
+ MODE_CREATE|MODE_READ_WRITE);
+
+ // changing the wallpaper means we'll need to back up the new one
+ long origId = Binder.clearCallingIdentity();
+ BackupManager bm = new BackupManager(mContext);
+ bm.dataChanged();
+ Binder.restoreCallingIdentity(origId);
+
+ return fd;
} catch (FileNotFoundException e) {
if (Config.LOGD) Log.d(TAG, "Error setting wallpaper", e);
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0d9d2b0..fd1dfc8 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1518,8 +1518,7 @@
}
}
- final BatteryStatsImpl bstats =
- (BatteryStatsImpl) mBatteryStatsService.getActiveStatistics();
+ final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
synchronized(bstats) {
synchronized(mPidsSelfLocked) {
if (haveNewCpuStats) {
@@ -1534,7 +1533,7 @@
ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
} else {
BatteryStatsImpl.Uid.Proc ps =
- bstats.getProcessStatsLocked(st.name);
+ bstats.getProcessStatsLocked(st.name, st.pid);
if (ps != null) {
ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a79eb3a..bf5df88 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -612,6 +612,21 @@
}
/**
+ * Returns the voice mail count.
+ * <p>
+ * Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * @hide
+ */
+ public int getVoiceMessageCount() {
+ try {
+ return getITelephony().getVoiceMessageCount();
+ } catch (RemoteException ex) {
+ }
+ return 0;
+ }
+
+ /**
* Retrieves the alphabetic identifier associated with the voice
* mail number.
* <p>
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 6e6f64c..d83b135 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -241,7 +241,7 @@
/**
* Returns the unread count of voicemails
*/
- int getCountVoiceMessages();
+ int getVoiceMessageCount();
}
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index 114094b..ea24c25 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -196,7 +196,7 @@
* If not available (eg, on an older CPHS SIM) -1 is returned if
* getVoiceMessageWaiting() is true
*/
- public int getCountVoiceMessages() {
+ public int getVoiceMessageCount() {
return countVoiceMessages;
}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index cdbfd61..c8d384d 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -831,7 +831,7 @@
* Returns unread voicemail count. This count is shown when the voicemail
* notification is expanded.<p>
*/
- int getCountVoiceMessages();
+ int getVoiceMessageCount();
/**
* Returns the alpha tag associated with the voice mail number.
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 0783fe0..a26e729 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -631,6 +631,11 @@
mNotifier.notifyDataActivity(this);
}
+ public void notifyMessageWaitingIndicator() {
+ // This function is added to send the notification to DefaultPhoneNotifier.
+ mNotifier.notifyMessageWaitingChanged(this);
+ }
+
public void notifyDataConnection(String reason) {
mNotifier.notifyDataConnection(this, reason);
}
@@ -638,7 +643,7 @@
public abstract String getPhoneName();
/** @hide */
- public int getCountVoiceMessages(){
+ public int getVoiceMessageCount(){
return 0;
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 4bb24dc..5b3c8dd 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -435,8 +435,8 @@
}
/** @hide */
- public int getCountVoiceMessages(){
- return mActivePhone.getCountVoiceMessages();
+ public int getVoiceMessageCount(){
+ return mActivePhone.getVoiceMessageCount();
}
public String getVoiceMailAlphaTag() {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 9aa7eab..3362de8 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -19,6 +19,7 @@
import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
@@ -26,6 +27,7 @@
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.SystemProperties;
+import android.preference.PreferenceManager;
import android.provider.Settings;
import android.telephony.CellLocation;
import android.telephony.PhoneNumberUtils;
@@ -40,6 +42,7 @@
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccException;
import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccPhoneBookInterfaceManager;
import com.android.internal.telephony.IccSmsInterfaceManager;
@@ -65,6 +68,9 @@
// Default Emergency Callback Mode exit timer
private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 30000;
+ static final String VM_COUNT_CDMA = "vm_count_key_cdma";
+ private static final String VM_NUMBER_CDMA = "vm_number_key_cdma";
+ private String mVmNumber = null;
//***** Instance Variables
CdmaCallTracker mCT;
@@ -147,6 +153,9 @@
// This is needed to handle phone process crashes
String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
mIsPhoneInECMState = inEcm.equals("true");
+
+ // Notify voicemails.
+ notifier.notifyMessageWaitingChanged(this);
}
public void dispose() {
@@ -300,7 +309,7 @@
public boolean
getMessageWaitingIndicator() {
- return mRuimRecords.getVoiceMessageWaiting();
+ return (getVoiceMessageCount() > 0);
}
public List<? extends MmiCode>
@@ -678,22 +687,33 @@
public void setVoiceMailNumber(String alphaTag,
String voiceMailNumber,
Message onComplete) {
- //mSIMRecords.setVoiceMailNumber(alphaTag, voiceMailNumber, onComplete);
- //TODO: Where do we have to store this value has to be clarified with QC
+ Message resp;
+ mVmNumber = voiceMailNumber;
+ resp = h.obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete);
+ mRuimRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp);
}
public String getVoiceMailNumber() {
- //TODO: Where can we get this value has to be clarified with QC
- //return mSIMRecords.getVoiceMailNumber();
-// throw new RuntimeException();
- return "*86";
+ String number = null;
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ // TODO(Moto): The default value of voicemail number should be read from a system property
+ number = sp.getString(VM_NUMBER_CDMA, "*86");
+ return number;
}
/* Returns Number of Voicemails
* @hide
*/
- public int getCountVoiceMessages() {
- return mRuimRecords.getCountVoiceMessages();
+ public int getVoiceMessageCount() {
+ int voicemailCount = mRuimRecords.getVoiceMessageCount();
+ // If mRuimRecords.getVoiceMessageCount returns zero, then there is possibility
+ // that phone was power cycled and would have lost the voicemail count.
+ // So get the count from preferences.
+ if (voicemailCount == 0) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ voicemailCount = sp.getInt(VM_COUNT_CDMA, 0);
+ }
+ return voicemailCount;
}
public String getVoiceMailAlphaTag() {
@@ -820,9 +840,10 @@
mRuimRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0);
}
- public void
- notifyMessageWaitingIndicator() {
- mNotifier.notifyMessageWaitingChanged(this);
+ /* This function is overloaded to send number of voicemails instead of sending true/false */
+ /*package*/ void
+ updateMessageWaitingIndicator(int mwi) {
+ mRuimRecords.setVoiceMessageWaiting(1, mwi);
}
/**
@@ -984,6 +1005,19 @@
}
break;
+ case EVENT_SET_VM_NUMBER_DONE:{
+ ar = (AsyncResult)msg.obj;
+ if (IccException.class.isInstance(ar.exception)) {
+ storeVoiceMailNumber(mVmNumber);
+ ar.exception = null;
+ }
+ onComplete = (Message) ar.userObj;
+ if (onComplete != null) {
+ AsyncResult.forMessage(onComplete, ar.result, ar.exception);
+ onComplete.sendToTarget();
+ }
+ }
+
default:{
throw new RuntimeException("unexpected event not handled");
}
@@ -1198,4 +1232,16 @@
int defRoamInd = getServiceState().getCdmaDefaultRoamingIndicator();
return mEriManager.getCdmaEriText(roamInd, defRoamInd);
}
+
+ /**
+ * Store the voicemail number in preferences
+ */
+ private void storeVoiceMailNumber(String number) {
+ // Update the preference value of voicemail number
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putString(VM_NUMBER_CDMA, number);
+ editor.commit();
+ }
+
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index da9fd0c4..ed2ea90 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -253,11 +253,7 @@
// Always unmute when answering a new call
setMute(false);
cm.acceptCall(obtainCompleteMessage());
- } else if ((foregroundCall.connections.size() > 0) &&
- (ringingCall.getState() == CdmaCall.State.WAITING)) {
- // TODO(Moto): jsh asks, "Is this check necessary? I don't think it should be
- // possible to have no fg connection and a WAITING call, but if we should hit
- // this situation, is a CallStateExcetion appropriate?"
+ } else if (ringingCall.getState() == CdmaCall.State.WAITING) {
CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection());
// Since there is no network response for supplimentary
@@ -530,10 +526,6 @@
CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
droppedDuringPoll.add(cn);
}
- // TODO(Moto): jsh asks, "Are we sure we don't need to do this for
- // ringingCall as well? What if there's a WAITING call (ie, UI timer
- // hasn't expired, moving it to DISCONNECTED)? How/when will it
- // transition to DISCONNECTED?"
}
foregroundCall.setGeneric(false);
// Dropped connections are removed from the CallTracker
@@ -681,8 +673,12 @@
// set the ringing call state to IDLE here to avoid a race condition
// where a new call waiting could get a hang up from an old call
// waiting ringingCall.
- // TODO(Moto): jsh asks, "Should we call conn.ondisconnect() here or Somewhere?"
- ringingCall.detach(conn);
+ //
+ // PhoneApp does the call log itself since only PhoneApp knows
+ // the hangup reason is user ignoring or timing out. So conn.onDisconnect()
+ // is not called here. Instead, conn.onLocalDisconnect() is called.
+ conn.onLocalDisconnect();
+ phone.notifyCallStateChanged();
return;
} else {
try {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 588bdf0..025382d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -452,12 +452,7 @@
this.cause = cause;
if (!disconnected) {
- index = -1;
-
- disconnectTime = System.currentTimeMillis();
- duration = SystemClock.elapsedRealtime() - connectTimeReal;
- disconnected = true;
-
+ doDisconnect();
if (Config.LOGD) Log.d(LOG_TAG,
"[CDMAConn] onDisconnect: cause=" + cause);
@@ -470,6 +465,21 @@
releaseWakeLock();
}
+ /** Called when the call waiting connection has been hung up */
+ /*package*/ void
+ onLocalDisconnect() {
+ if (!disconnected) {
+ doDisconnect();
+ if (Config.LOGD) Log.d(LOG_TAG,
+ "[CDMAConn] onLoalDisconnect" );
+
+ if (parent != null) {
+ parent.detach(this);
+ }
+ }
+ releaseWakeLock();
+ }
+
// Returns true if state has changed, false if nothing changed
/*package*/ boolean
update (DriverCall dc) {
@@ -587,6 +597,14 @@
}
private void
+ doDisconnect() {
+ index = -1;
+ disconnectTime = System.currentTimeMillis();
+ duration = SystemClock.elapsedRealtime() - connectTimeReal;
+ disconnected = true;
+ }
+
+ private void
onStartedHolding() {
holdingStartTime = SystemClock.elapsedRealtime();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 2b4a700..8a0070d 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -20,11 +20,13 @@
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ContentValues;
+import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.SQLException;
import android.os.AsyncResult;
import android.os.Message;
import android.provider.Telephony.Sms.Intents;
+import android.preference.PreferenceManager;
import android.util.Config;
import android.util.Log;
@@ -83,27 +85,6 @@
int teleService = sms.getTeleService();
boolean handled = false;
- // Teleservices W(E)MT and VMN are handled together:
- if ((teleService == SmsEnvelope.TELESERVICE_WMT)
- || (teleService == SmsEnvelope.TELESERVICE_WEMT)
- || (teleService == SmsEnvelope.TELESERVICE_VMN)) {
- // From here on we need decoded BD.
- // Special case the message waiting indicator messages
- if (sms.isMWISetMessage()) {
- mCdmaPhone.updateMessageWaitingIndicator(true);
- handled |= sms.isMwiDontStore();
- if (Config.LOGD) {
- Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled);
- }
- } else if (sms.isMWIClearMessage()) {
- mCdmaPhone.updateMessageWaitingIndicator(false);
- handled |= sms.isMwiDontStore();
- if (Config.LOGD) {
- Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled);
- }
- }
- }
-
if (sms.getUserData() == null) {
if (Config.LOGD) {
Log.d(TAG, "Received SMS without user data");
@@ -116,6 +97,18 @@
if (SmsEnvelope.TELESERVICE_WAP == teleService){
processCdmaWapPdu(sms.getUserData(), sms.messageRef, sms.getOriginatingAddress());
return;
+ } else if (SmsEnvelope.TELESERVICE_VMN == teleService) {
+ // handling Voicemail
+ int voicemailCount = sms.getNumOfVoicemails();
+ Log.d(TAG, "Voicemail count=" + voicemailCount);
+ // Store the voicemail count in preferences.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
+ ((CDMAPhone) mPhone).getContext());
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount);
+ editor.commit();
+ ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
+ return;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 63d2c47..3a92064 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -773,6 +773,12 @@
return asciiDigit;
}
+ /** This function shall be called to get the number of voicemails.
+ * @hide
+ */
+ /*package*/ int getNumOfVoicemails() {
+ return mBearerData.numberOfMessages;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index 70d71fc..d1e4b4f 100755
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -448,11 +448,6 @@
}
public void
- notifyMessageWaitingIndicator() {
- mNotifier.notifyMessageWaitingChanged(this);
- }
-
- public void
notifyCallForwardingIndicator() {
mNotifier.notifyCallForwardingChanged(this);
}
diff --git a/tools/aidl/AST.h b/tools/aidl/AST.h
index 1dedd04..aec2164 100755
--- a/tools/aidl/AST.h
+++ b/tools/aidl/AST.h
@@ -5,6 +5,7 @@
#include <vector>
#include <set>
#include <stdarg.h>
+#include <stdio.h>
using namespace std;
diff --git a/tools/localize/Perforce.cpp b/tools/localize/Perforce.cpp
index 3425668..1c644ed 100644
--- a/tools/localize/Perforce.cpp
+++ b/tools/localize/Perforce.cpp
@@ -1,6 +1,7 @@
#include "Perforce.h"
#include "log.h"
#include <string.h>
+#include <cstdio>
#include <stdlib.h>
#include <sstream>
#include <sys/types.h>
diff --git a/tools/localize/SourcePos.cpp b/tools/localize/SourcePos.cpp
index 9d7c5c6..2533f0a 100644
--- a/tools/localize/SourcePos.cpp
+++ b/tools/localize/SourcePos.cpp
@@ -1,6 +1,7 @@
#include "SourcePos.h"
#include <stdarg.h>
+#include <cstdio>
#include <set>
using namespace std;
diff --git a/tools/localize/Values.cpp b/tools/localize/Values.cpp
index e396f8b..8623b97 100644
--- a/tools/localize/Values.cpp
+++ b/tools/localize/Values.cpp
@@ -1,5 +1,6 @@
#include "Values.h"
#include <stdlib.h>
+#include <cstdio>
// =====================================================================================
diff --git a/tools/localize/XLIFFFile.cpp b/tools/localize/XLIFFFile.cpp
index 51f81de..4e217d9 100644
--- a/tools/localize/XLIFFFile.cpp
+++ b/tools/localize/XLIFFFile.cpp
@@ -3,6 +3,7 @@
#include <algorithm>
#include <sys/time.h>
#include <time.h>
+#include <cstdio>
const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2";
diff --git a/tools/localize/file_utils.cpp b/tools/localize/file_utils.cpp
index 8792b9e..293e50e 100644
--- a/tools/localize/file_utils.cpp
+++ b/tools/localize/file_utils.cpp
@@ -1,4 +1,5 @@
#include <string.h>
+#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "file_utils.h"
diff --git a/tools/localize/localize_test.cpp b/tools/localize/localize_test.cpp
index 63d904c..678cad8 100644
--- a/tools/localize/localize_test.cpp
+++ b/tools/localize/localize_test.cpp
@@ -1,6 +1,7 @@
#include "XLIFFFile.h"
#include "ValuesFile.h"
#include "localize.h"
+#include <stdio.h>
int pseudolocalize_xliff(XLIFFFile* xliff, bool expand);
diff --git a/tools/localize/merge_res_and_xliff.cpp b/tools/localize/merge_res_and_xliff.cpp
index 58a6554..1fdaa0e 100644
--- a/tools/localize/merge_res_and_xliff.cpp
+++ b/tools/localize/merge_res_and_xliff.cpp
@@ -3,6 +3,7 @@
#include "file_utils.h"
#include "Perforce.h"
#include "log.h"
+#include <stdio.h>
static set<StringResource>::const_iterator
find_id(const set<StringResource>& s, const string& id, int index)
diff --git a/tools/localize/merge_res_and_xliff_test.cpp b/tools/localize/merge_res_and_xliff_test.cpp
index 5a2b0f4..e4ab562 100644
--- a/tools/localize/merge_res_and_xliff_test.cpp
+++ b/tools/localize/merge_res_and_xliff_test.cpp
@@ -1,5 +1,5 @@
#include "merge_res_and_xliff.h"
-
+#include <stdio.h>
int
merge_test()
diff --git a/tools/localize/xmb.cpp b/tools/localize/xmb.cpp
index 236705f..d8f6ff0 100644
--- a/tools/localize/xmb.cpp
+++ b/tools/localize/xmb.cpp
@@ -7,6 +7,7 @@
#include "XLIFFFile.h"
#include <map>
+#include <cstdio>
using namespace std;