diff options
71 files changed, 3725 insertions, 1400 deletions
diff --git a/Android.mk b/Android.mk index 5fb66ab512ae..61e8a77dc969 100644 --- a/Android.mk +++ b/Android.mk @@ -114,6 +114,7 @@ LOCAL_SRC_FILES += \ core/java/android/content/pm/IPackageStatsObserver.aidl \ core/java/android/database/IContentObserver.aidl \ core/java/android/hardware/ISerialManager.aidl \ + core/java/android/hardware/display/IDisplayManager.aidl \ core/java/android/hardware/input/IInputManager.aidl \ core/java/android/hardware/input/IInputDevicesChangedListener.aidl \ core/java/android/hardware/usb/IUsbManager.aidl \ diff --git a/api/16.txt b/api/16.txt index 85464ceac46b..984b844c1e6d 100644 --- a/api/16.txt +++ b/api/16.txt @@ -22892,7 +22892,7 @@ package android.view { method protected void onApplyThemeResource(android.content.res.Resources.Theme, int, boolean); } - public class Display { + public final class Display { method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point); method public int getDisplayId(); method public deprecated int getHeight(); diff --git a/api/current.txt b/api/current.txt index 2716d5bf77fc..c910bd02cf40 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5355,6 +5355,7 @@ package android.content { field public static final int CONTEXT_INCLUDE_CODE = 1; // 0x1 field public static final int CONTEXT_RESTRICTED = 4; // 0x4 field public static final java.lang.String DEVICE_POLICY_SERVICE = "device_policy"; + field public static final java.lang.String DISPLAY_SERVICE = "display"; field public static final java.lang.String DOWNLOAD_SERVICE = "download"; field public static final java.lang.String DROPBOX_SERVICE = "dropbox"; field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; @@ -9952,6 +9953,13 @@ package android.hardware { } +package android.hardware.display { + + public final class DisplayManager { + } + +} + package android.hardware.input { public final class InputManager { @@ -23120,13 +23128,15 @@ package android.view { method protected void onApplyThemeResource(android.content.res.Resources.Theme, int, boolean); } - public class Display { + public final class Display { method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point); method public int getDisplayId(); method public deprecated int getHeight(); method public void getMetrics(android.util.DisplayMetrics); method public deprecated int getOrientation(); - method public int getPixelFormat(); + method public deprecated int getPixelFormat(); + method public void getRealMetrics(android.util.DisplayMetrics); + method public void getRealSize(android.graphics.Point); method public void getRectSize(android.graphics.Rect); method public float getRefreshRate(); method public int getRotation(); diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 6b50486074df..2471a2e719f3 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -217,7 +217,7 @@ status_t BootAnimation::readyToRun() { mAssets.addDefaultAssets(); DisplayInfo dinfo; - status_t status = session()->getDisplayInfo(0, &dinfo); + status_t status = SurfaceComposerClient::getDisplayInfo(0, &dinfo); if (status) return -1; diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 9364a575ebb1..74fce628d72c 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -47,6 +47,7 @@ import android.hardware.ISerialManager; import android.hardware.SensorManager; import android.hardware.SerialManager; import android.hardware.SystemSensorManager; +import android.hardware.display.DisplayManager; import android.hardware.input.IInputManager; import android.hardware.input.InputManager; import android.hardware.usb.IUsbManager; @@ -343,6 +344,11 @@ class ContextImpl extends Context { return InputManager.getInstance(); }}); + registerService(DISPLAY_SERVICE, new StaticServiceFetcher() { + public Object createStaticService() { + return DisplayManager.getInstance(); + }}); + registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return InputMethodManager.getInstance(ctx); @@ -477,7 +483,7 @@ class ContextImpl extends Context { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(WIFI_SERVICE); IWifiManager service = IWifiManager.Stub.asInterface(b); - return new WifiManager(service, ctx.mMainThread.getHandler()); + return new WifiManager(ctx.getOuterContext(), service); }}); registerService(WIFI_P2P_SERVICE, new ServiceFetcher() { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 490165d77023..8597993ffecf 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1955,6 +1955,15 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a + * {@link android.hardware.display.DisplayManager} for interacting with display devices. + * + * @see #getSystemService + * @see android.hardware.display.DisplayManager + */ + public static final String DISPLAY_SERVICE = "display"; + + /** + * Use with {@link #getSystemService} to retrieve a * {@link android.os.SchedulingPolicyService} for managing scheduling policy. * * @see #getSystemService diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java new file mode 100644 index 000000000000..640044bfadc3 --- /dev/null +++ b/core/java/android/hardware/display/DisplayManager.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2012 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.hardware.display; + +import android.content.Context; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; +import android.view.DisplayInfo; + +/** + * Manages the properties, media routing and power state of attached displays. + * <p> + * Get an instance of this class by calling + * {@link android.content.Context#getSystemService(java.lang.String) + * Context.getSystemService()} with the argument + * {@link android.content.Context#DISPLAY_SERVICE}. + * </p> + */ +public final class DisplayManager { + private static final String TAG = "DisplayManager"; + + private static DisplayManager sInstance; + + private final IDisplayManager mDm; + + private DisplayManager(IDisplayManager dm) { + mDm = dm; + } + + /** + * Gets an instance of the display manager. + * @return The display manager instance. + * @hide + */ + public static DisplayManager getInstance() { + synchronized (DisplayManager.class) { + if (sInstance == null) { + IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE); + sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b)); + } + return sInstance; + } + } + + /** + * Get information about a particular logical display. + * + * @param displayId The logical display id. + * @param outInfo A structure to populate with the display info. + * @return True if the logical display exists, false otherwise. + * @hide + */ + public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) { + try { + return mDm.getDisplayInfo(displayId, outInfo); + } catch (RemoteException ex) { + Log.e(TAG, "Could not get display information from display manager.", ex); + return false; + } + } +} diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl new file mode 100644 index 000000000000..fd8c35f8d614 --- /dev/null +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012 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.hardware.display; + +import android.view.DisplayInfo; + +/** @hide */ +interface IDisplayManager { + boolean getDisplayInfo(int displayId, out DisplayInfo outInfo); +} diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index ce49268fec72..46e4d6ed5cce 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -17,20 +17,56 @@ package android.view; import android.content.res.CompatibilityInfo; +import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; +import android.hardware.display.DisplayManager; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.SystemClock; import android.util.DisplayMetrics; -import android.util.Slog; +import android.util.Log; /** - * Provides information about the display size and density. + * Provides information about the size and density of a logical display. + * <p> + * The display area is described in two different ways. + * <ul> + * <li>The application display area specifies the part of the display that may contain + * an application window, excluding the system decorations. The application display area may + * be smaller than the real display area because the system subtracts the space needed + * for decor elements such as the status bar. Use the following methods to query the + * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li> + * <li>The real display area specifies the part of the display that contains content + * including the system decorations. Even so, the real display area may be smaller than the + * physical size of the display if the window manager is emulating a smaller display + * using (adb shell am display-size). Use the following methods to query the + * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li> + * </ul> + * </p><p> + * A logical display does not necessarily represent a particular physical display device + * such as the built-in screen or an external monitor. The contents of a logical + * display may be presented on one or more physical displays according to the devices + * that are currently attached and whether mirroring has been enabled. + * </p> */ -public class Display { - static final String TAG = "Display"; - static final boolean DEBUG_DISPLAY_SIZE = false; +public final class Display { + private static final String TAG = "Display"; + + private final int mDisplayId; + private final CompatibilityInfoHolder mCompatibilityInfo; + private final DisplayInfo mDisplayInfo = new DisplayInfo(); + + // Temporary display metrics structure used for compatibility mode. + private final DisplayMetrics mTempMetrics = new DisplayMetrics(); + + // We cache the app width and height properties briefly between calls + // to getHeight() and getWidth() to ensure that applications perceive + // consistent results when the size changes (most of the time). + // Applications should now be using getSize() instead. + private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20; + private long mLastCachedAppSizeUpdate; + private int mCachedAppWidthCompat; + private int mCachedAppHeightCompat; /** * The default Display id. @@ -38,40 +74,29 @@ public class Display { public static final int DEFAULT_DISPLAY = 0; /** - * Use {@link android.view.WindowManager#getDefaultDisplay() - * WindowManager.getDefaultDisplay()} to create a Display object. - * Display gives you access to some information about a particular display - * connected to the device. + * Internal method to create a display. + * Applications should use {@link android.view.WindowManager#getDefaultDisplay()} + * to get a display object for the default display. + * + * @hide */ - Display(int display, CompatibilityInfoHolder compatInfo) { - // initalize the statics when this class is first instansiated. This is - // done here instead of in the static block because Zygote - synchronized (sStaticInit) { - if (!sInitialized) { - nativeClassInit(); - sInitialized = true; - } - } - mCompatibilityInfo = compatInfo != null ? compatInfo : new CompatibilityInfoHolder(); - mDisplay = display; - init(display); + public Display(int displayId, CompatibilityInfoHolder compatibilityInfo) { + mDisplayId = displayId; + mCompatibilityInfo = compatibilityInfo; } /** - * Returns the index of this display. This is currently undefined; do - * not use. + * Gets the display id. + * <p> + * Each logical display has a unique id. + * The default display has id {@link #DEFAULT_DISPLAY}. + * </p> */ public int getDisplayId() { - return mDisplay; + return mDisplayId; } /** - * Returns the number of displays connected to the device. This is - * currently undefined; do not use. - */ - native static int getDisplayCount(); - - /** * Gets the size of the display, in pixels. * <p> * Note that this value should <em>not</em> be used for computing layouts, @@ -84,7 +109,7 @@ public class Display { * </p><p> * The size returned by this method does not necessarily represent the * actual raw size (native resolution) of the display. The returned size may - * be adjusted to exclude certain system decor elements that are always visible. + * be adjusted to exclude certain system decoration elements that are always visible. * It may also be scaled to provide compatibility with older applications that * were originally designed for smaller displays. * </p> @@ -92,43 +117,14 @@ public class Display { * @param outSize A {@link Point} object to receive the size information. */ public void getSize(Point outSize) { - getSizeInternal(outSize, true); - } - - private void getSizeInternal(Point outSize, boolean doCompat) { - try { - IWindowManager wm = getWindowManager(); - if (wm != null) { - wm.getDisplaySize(outSize); - CompatibilityInfo ci; - if (doCompat && (ci=mCompatibilityInfo.getIfNeeded()) != null) { - synchronized (mTmpMetrics) { - mTmpMetrics.noncompatWidthPixels = outSize.x; - mTmpMetrics.noncompatHeightPixels = outSize.y; - mTmpMetrics.density = mDensity; - ci.applyToDisplayMetrics(mTmpMetrics); - outSize.x = mTmpMetrics.widthPixels; - outSize.y = mTmpMetrics.heightPixels; - } - } - } else { - // This is just for boot-strapping, initializing the - // system process before the window manager is up. - outSize.x = getRawWidth(); - outSize.y = getRawHeight(); - } - if (false) { - RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); - Slog.v(TAG, "Returning display size: " + outSize, here); - } - if (DEBUG_DISPLAY_SIZE && doCompat) Slog.v( - TAG, "Returning display size: " + outSize); - } catch (RemoteException e) { - Slog.w("Display", "Unable to get display size", e); + synchronized (this) { + updateDisplayInfoLocked(); + mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo); + outSize.x = mTempMetrics.widthPixels; + outSize.y = mTempMetrics.heightPixels; } } - + /** * Gets the size of the display as a rectangle, in pixels. * @@ -136,9 +132,10 @@ public class Display { * @see #getSize(Point) */ public void getRectSize(Rect outSize) { - synchronized (mTmpPoint) { - getSizeInternal(mTmpPoint, true); - outSize.set(0, 0, mTmpPoint.x, mTmpPoint.y); + synchronized (this) { + updateDisplayInfoLocked(); + mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo); + outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels); } } @@ -173,15 +170,12 @@ public class Display { * for example, screen decorations like the status bar are being hidden. */ public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) { - try { - IWindowManager wm = getWindowManager(); - wm.getCurrentSizeRange(outSmallestSize, outLargestSize); - } catch (RemoteException e) { - Slog.w("Display", "Unable to get display size range", e); - outSmallestSize.x = 0; - outSmallestSize.y = 0; - outLargestSize.x = 0; - outLargestSize.y = 0; + synchronized (this) { + updateDisplayInfoLocked(); + outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth; + outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight; + outLargestSize.x = mDisplayInfo.largestNominalAppWidth; + outLargestSize.y = mDisplayInfo.largestNominalAppHeight; } } @@ -191,12 +185,9 @@ public class Display { * @hide */ public int getMaximumSizeDimension() { - try { - IWindowManager wm = getWindowManager(); - return wm.getMaximumSizeDimension(); - } catch (RemoteException e) { - Slog.w("Display", "Unable to get display maximum size dimension", e); - return 0; + synchronized (this) { + updateDisplayInfoLocked(); + return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); } } @@ -205,13 +196,9 @@ public class Display { */ @Deprecated public int getWidth() { - synchronized (mTmpPoint) { - long now = SystemClock.uptimeMillis(); - if (now > (mLastGetTime+20)) { - getSizeInternal(mTmpPoint, true); - mLastGetTime = now; - } - return mTmpPoint.x; + synchronized (this) { + updateCachedAppSizeIfNeededLocked(); + return mCachedAppWidthCompat; } } @@ -220,76 +207,13 @@ public class Display { */ @Deprecated public int getHeight() { - synchronized (mTmpPoint) { - long now = SystemClock.uptimeMillis(); - if (now > (mLastGetTime+20)) { - getSizeInternal(mTmpPoint, true); - mLastGetTime = now; - } - return mTmpPoint.y; - } - } - - /** - * Gets the real size of the display without subtracting any window decor or - * applying any compatibility scale factors. - * <p> - * The real size may be smaller than the raw size when the window manager - * is emulating a smaller display (using adb shell am display-size). - * </p><p> - * The size is adjusted based on the current rotation of the display. - * </p> - * @hide - */ - public void getRealSize(Point outSize) { - try { - IWindowManager wm = getWindowManager(); - if (wm != null) { - wm.getRealDisplaySize(outSize); - } else { - // This is just for boot-strapping, initializing the - // system process before the window manager is up. - outSize.x = getRawWidth(); - outSize.y = getRawHeight(); - } - if (DEBUG_DISPLAY_SIZE) Slog.v( - TAG, "Returning real display size: " + outSize); - } catch (RemoteException e) { - Slog.w("Display", "Unable to get real display size", e); + synchronized (this) { + updateCachedAppSizeIfNeededLocked(); + return mCachedAppHeightCompat; } } /** - * Gets the raw width of the display, in pixels. - * <p> - * The size is adjusted based on the current rotation of the display. - * </p> - * @hide - */ - public int getRawWidth() { - int w = getRawWidthNative(); - if (DEBUG_DISPLAY_SIZE) Slog.v( - TAG, "Returning raw display width: " + w); - return w; - } - private native int getRawWidthNative(); - - /** - * Gets the raw height of the display, in pixels. - * <p> - * The size is adjusted based on the current rotation of the display. - * </p> - * @hide - */ - public int getRawHeight() { - int h = getRawHeightNative(); - if (DEBUG_DISPLAY_SIZE) Slog.v( - TAG, "Returning raw display height: " + h); - return h; - } - private native int getRawHeightNative(); - - /** * Returns the rotation of the screen from its "natural" orientation. * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0} * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90}, @@ -307,30 +231,43 @@ public class Display { * {@link Surface#ROTATION_90 Surface.ROTATION_90}. */ public int getRotation() { - return getOrientation(); + synchronized (this) { + updateDisplayInfoLocked(); + return mDisplayInfo.rotation; + } } - + /** * @deprecated use {@link #getRotation} * @return orientation of this display. */ - @Deprecated native public int getOrientation(); + @Deprecated + public int getOrientation() { + return getRotation(); + } /** - * Return the native pixel format of the display. The returned value - * may be one of the constants int {@link android.graphics.PixelFormat}. + * Gets the pixel format of the display. + * @return One of the constants defined in {@link android.graphics.PixelFormat}. + * + * @deprecated This method is no longer supported. + * The result is always {@link PixelFormat#RGBA_8888}. */ + @Deprecated public int getPixelFormat() { - return mPixelFormat; + return PixelFormat.RGBA_8888; } - + /** - * Return the refresh rate of this display in frames per second. + * Gets the refresh rate of this display in frames per second. */ public float getRefreshRate() { - return mRefreshRate; + synchronized (this) { + updateDisplayInfoLocked(); + return mDisplayInfo.refreshRate; + } } - + /** * Gets display metrics that describe the size and density of this display. * <p> @@ -346,109 +283,71 @@ public class Display { * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. */ public void getMetrics(DisplayMetrics outMetrics) { - synchronized (mTmpPoint) { - getSizeInternal(mTmpPoint, false); - getMetricsWithSize(outMetrics, mTmpPoint.x, mTmpPoint.y); + synchronized (this) { + updateDisplayInfoLocked(); + mDisplayInfo.getAppMetrics(outMetrics, mCompatibilityInfo); } - CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded(); + final CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded(); if (ci != null) { ci.applyToDisplayMetrics(outMetrics); } - - if (DEBUG_DISPLAY_SIZE) Slog.v(TAG, "Returning DisplayMetrics: " - + outMetrics.widthPixels + "x" + outMetrics.heightPixels - + " " + outMetrics.density); } /** - * Gets display metrics based on the real size of this display. - * @hide + * Gets the real size of the display without subtracting any window decor or + * applying any compatibility scale factors. + * <p> + * The size is adjusted based on the current rotation of the display. + * </p><p> + * The real size may be smaller than the physical size of the screen when the + * window manager is emulating a smaller display (using adb shell am display-size). + * </p> + * + * @param outSize Set to the real size of the display. */ - public void getRealMetrics(DisplayMetrics outMetrics) { - synchronized (mTmpPoint) { - getRealSize(mTmpPoint); - getMetricsWithSize(outMetrics, mTmpPoint.x, mTmpPoint.y); + public void getRealSize(Point outSize) { + synchronized (this) { + updateDisplayInfoLocked(); + outSize.x = mDisplayInfo.logicalWidth; + outSize.y = mDisplayInfo.logicalHeight; } } /** - * If the display is mirrored to an external HDMI display, returns the - * width of that display. - * @hide - */ - public int getRawExternalWidth() { - return 1280; - } - - /** - * If the display is mirrored to an external HDMI display, returns the - * height of that display. - * @hide - */ - public int getRawExternalHeight() { - return 720; - } - - /** - * If the display is mirrored to an external HDMI display, returns the - * rotation of that display relative to its natural orientation. - * @hide + * Gets display metrics based on the real size of this display. + * <p> + * The size is adjusted based on the current rotation of the display. + * </p><p> + * The real size may be smaller than the physical size of the screen when the + * window manager is emulating a smaller display (using adb shell am display-size). + * </p> + * + * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. */ - public int getExternalRotation() { - return Surface.ROTATION_0; + public void getRealMetrics(DisplayMetrics outMetrics) { + synchronized (this) { + updateDisplayInfoLocked(); + mDisplayInfo.getLogicalMetrics(outMetrics, null); + } } - /** - * Gets display metrics based on an explicit assumed display size. - * @hide - */ - public void getMetricsWithSize(DisplayMetrics outMetrics, - int width, int height) { - outMetrics.densityDpi = (int)((mDensity*DisplayMetrics.DENSITY_DEFAULT)+.5f); - - outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width; - outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height; - - outMetrics.density = outMetrics.noncompatDensity = mDensity; - outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density; - outMetrics.xdpi = outMetrics.noncompatXdpi = mDpiX; - outMetrics.ydpi = outMetrics.noncompatYdpi = mDpiY; + private void updateDisplayInfoLocked() { + // TODO: only refresh the display information when needed + if (!DisplayManager.getInstance().getDisplayInfo(mDisplayId, mDisplayInfo)) { + Log.e(TAG, "Could not get information about logical display " + mDisplayId); + } } - static IWindowManager getWindowManager() { - synchronized (sStaticInit) { - if (sWindowManager == null) { - sWindowManager = IWindowManager.Stub.asInterface( - ServiceManager.getService("window")); - } - return sWindowManager; + private void updateCachedAppSizeIfNeededLocked() { + long now = SystemClock.uptimeMillis(); + if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) { + updateDisplayInfoLocked(); + mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo); + mCachedAppWidthCompat = mTempMetrics.widthPixels; + mCachedAppHeightCompat = mTempMetrics.heightPixels; + mLastCachedAppSizeUpdate = now; } } - - /* - * We use a class initializer to allow the native code to cache some - * field offsets. - */ - native private static void nativeClassInit(); - - private native void init(int display); - - private final CompatibilityInfoHolder mCompatibilityInfo; - private final int mDisplay; - // Following fields are initialized from native code - private int mPixelFormat; - private float mRefreshRate; - /*package*/ float mDensity; - /*package*/ float mDpiX; - /*package*/ float mDpiY; - - private final Point mTmpPoint = new Point(); - private final DisplayMetrics mTmpMetrics = new DisplayMetrics(); - private float mLastGetTime; - - private static final Object sStaticInit = new Object(); - private static boolean sInitialized = false; - private static IWindowManager sWindowManager; } diff --git a/core/java/android/view/DisplayInfo.aidl b/core/java/android/view/DisplayInfo.aidl new file mode 100644 index 000000000000..e679208e73f7 --- /dev/null +++ b/core/java/android/view/DisplayInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2012 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.view; + +parcelable DisplayInfo; diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java new file mode 100644 index 000000000000..69b6d6798a3e --- /dev/null +++ b/core/java/android/view/DisplayInfo.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2012 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.view; + +import android.content.res.CompatibilityInfo; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.DisplayMetrics; + +/** + * Describes the characteristics of a particular logical display. + * @hide + */ +public final class DisplayInfo implements Parcelable { + /** + * The width of the portion of the display that is available to applications, in pixels. + * Represents the size of the display minus any system decorations. + */ + public int appWidth; + + /** + * The height of the portion of the display that is available to applications, in pixels. + * Represents the size of the display minus any system decorations. + */ + public int appHeight; + + /** + * The smallest value of {@link #appWidth} that an application is likely to encounter, + * in pixels, excepting cases where the width may be even smaller due to the presence + * of a soft keyboard, for example. + */ + public int smallestNominalAppWidth; + + /** + * The smallest value of {@link #appHeight} that an application is likely to encounter, + * in pixels, excepting cases where the height may be even smaller due to the presence + * of a soft keyboard, for example. + */ + public int smallestNominalAppHeight; + + /** + * The largest value of {@link #appWidth} that an application is likely to encounter, + * in pixels, excepting cases where the width may be even larger due to system decorations + * such as the status bar being hidden, for example. + */ + public int largestNominalAppWidth; + + /** + * The largest value of {@link #appHeight} that an application is likely to encounter, + * in pixels, excepting cases where the height may be even larger due to system decorations + * such as the status bar being hidden, for example. + */ + public int largestNominalAppHeight; + + /** + * The logical width of the display, in pixels. + * Represents the usable size of the display which may be smaller than the + * physical size when the system is emulating a smaller display. + */ + public int logicalWidth; + + /** + * The logical height of the display, in pixels. + * Represents the usable size of the display which may be smaller than the + * physical size when the system is emulating a smaller display. + */ + public int logicalHeight; + + /** + * The rotation of the display relative to its natural orientation. + * May be one of {@link android.view.Surface#ROTATION_0}, + * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180}, + * {@link android.view.Surface#ROTATION_270}. + * <p> + * The value of this field is indeterminate if the logical display is presented on + * more than one physical display. + * </p> + */ + public int rotation; + + /** + * The refresh rate of this display in frames per second. + * <p> + * The value of this field is indeterminate if the logical display is presented on + * more than one physical display. + * </p> + */ + public float refreshRate; + + /** + * The logical display density which represents the scaling factor for + * the Density Independent Pixel unit. + */ + public float logicalDensity; + + /** + * The exact physical pixels per inch of the screen in the X dimension. + * <p> + * The value of this field is indeterminate if the logical display is presented on + * more than one physical display. + * </p> + */ + public float physicalXDpi; + + /** + * The exact physical pixels per inch of the screen in the Y dimension. + * <p> + * The value of this field is indeterminate if the logical display is presented on + * more than one physical display. + * </p> + */ + public float physicalYDpi; + + public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() { + public DisplayInfo createFromParcel(Parcel source) { + return new DisplayInfo(source); + } + + public DisplayInfo[] newArray(int size) { + return new DisplayInfo[size]; + } + }; + + public DisplayInfo() { + } + + private DisplayInfo(Parcel source) { + readFromParcel(source); + } + + @Override + public int describeContents() { + return 0; + } + + public void copyFrom(DisplayInfo other) { + appWidth = other.appWidth; + appHeight = other.appHeight; + smallestNominalAppWidth = other.smallestNominalAppWidth; + smallestNominalAppHeight = other.smallestNominalAppHeight; + largestNominalAppWidth = other.largestNominalAppWidth; + largestNominalAppHeight = other.largestNominalAppHeight; + logicalWidth = other.logicalWidth; + logicalHeight = other.logicalHeight; + rotation = other.rotation; + refreshRate = other.refreshRate; + logicalDensity = other.logicalDensity; + physicalXDpi = other.physicalXDpi; + physicalYDpi = other.physicalYDpi; + } + + public void readFromParcel(Parcel source) { + appWidth = source.readInt(); + appHeight = source.readInt(); + smallestNominalAppWidth = source.readInt(); + smallestNominalAppHeight = source.readInt(); + largestNominalAppWidth = source.readInt(); + largestNominalAppHeight = source.readInt(); + logicalWidth = source.readInt(); + logicalHeight = source.readInt(); + rotation = source.readInt(); + refreshRate = source.readFloat(); + logicalDensity = source.readFloat(); + physicalXDpi = source.readFloat(); + physicalYDpi = source.readFloat(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(appWidth); + dest.writeInt(appHeight); + dest.writeInt(smallestNominalAppWidth); + dest.writeInt(smallestNominalAppHeight); + dest.writeInt(largestNominalAppWidth); + dest.writeInt(largestNominalAppHeight); + dest.writeInt(logicalWidth); + dest.writeInt(logicalHeight); + dest.writeInt(rotation); + dest.writeFloat(refreshRate); + dest.writeFloat(logicalDensity); + dest.writeFloat(physicalXDpi); + dest.writeFloat(physicalYDpi); + } + + public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) { + getMetricsWithSize(outMetrics, cih, appWidth, appHeight); + } + + public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) { + getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight); + } + + private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih, + int width, int height) { + outMetrics.densityDpi = + (int)((logicalDensity * DisplayMetrics.DENSITY_DEFAULT) + .5f); + outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width; + outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height; + + outMetrics.density = outMetrics.noncompatDensity = logicalDensity; + outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density; + outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi; + outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi; + + if (cih != null) { + CompatibilityInfo ci = cih.getIfNeeded(); + if (ci != null) { + ci.applyToDisplayMetrics(outMetrics); + } + } + } +} diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 5941e448d3ff..a65d6f5b934e 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -25,6 +25,7 @@ import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; import android.os.IRemoteCallback; +import android.view.DisplayInfo; import android.view.IApplicationToken; import android.view.IOnKeyguardExitResult; import android.view.IRotationWatcher; @@ -56,11 +57,6 @@ interface IWindowManager IWindowSession openSession(in IInputMethodClient client, in IInputContext inputContext); boolean inputMethodClientHasFocus(IInputMethodClient client); - - void getDisplaySize(out Point size); - void getRealDisplaySize(out Point size); - int getMaximumSizeDimension(); - void getCurrentSizeRange(out Point smallestSize, out Point largestSize); void setForcedDisplaySize(int longDimen, int shortDimen); void clearForcedDisplaySize(); diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 11050385b12e..02ecb65ec1c5 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -403,31 +403,16 @@ public class Surface implements Parcelable { public native void destroy(); private native Canvas lockCanvasNative(Rect dirty); - - /* - * set display parameters & screenshots - */ /** * set the orientation of the given display. * @param display * @param orientation - * @param flags Currently unused, set to 0. * @hide */ - public static native void setOrientation(int display, int orientation, int flags); + public static native void setOrientation(int display, int orientation); /** - * set the orientation of the given display. - * @param display - * @param orientation - * @hide - */ - public static void setOrientation(int display, int orientation) { - setOrientation(display, orientation, 0); - } - - /** * Like {@link #screenshot(int, int, int, int)} but includes all * Surfaces in the screenshot. * diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 107f1cce73a7..3082976ec7ea 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -20,6 +20,7 @@ import android.app.AppGlobals; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.graphics.Point; import android.os.RemoteException; import android.provider.Settings; import android.util.DisplayMetrics; @@ -277,15 +278,17 @@ public class ViewConfiguration { mDoubleTapSlop = (int) (sizeAndDensity * DOUBLE_TAP_SLOP + 0.5f); mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f); - final Display display = WindowManagerImpl.getDefault().getDefaultDisplay(); // Size of the screen in bytes, in ARGB_8888 format - mMaximumDrawingCacheSize = 4 * display.getRawWidth() * display.getRawHeight(); + final Display display = WindowManagerImpl.getDefault().getDefaultDisplay(); + final Point size = new Point(); + display.getRealSize(size); + mMaximumDrawingCacheSize = 4 * size.x * size.y; mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f); mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f); if (!sHasPermanentMenuKeySet) { - IWindowManager wm = Display.getWindowManager(); + IWindowManager wm = WindowManagerImpl.getWindowManagerService(); try { sHasPermanentMenuKey = !wm.hasSystemNavBar() && !wm.hasNavigationBar(); sHasPermanentMenuKeySet = true; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index cd6c502ee519..e8bd61811f0e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -331,7 +331,7 @@ public final class ViewRootImpl implements ViewParent, if (!mInitialized) { try { InputMethodManager imm = InputMethodManager.getInstance(mainLooper); - IWindowManager windowManager = Display.getWindowManager(); + IWindowManager windowManager = WindowManagerImpl.getWindowManagerService(); sWindowSession = windowManager.openSession( imm.getClient(), imm.getInputContext()); float animatorScale = windowManager.getAnimationScale(2); diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index dedee97fa5b1..bd95cdb34ad6 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -21,6 +21,7 @@ import android.content.ComponentCallbacks2; import android.content.res.Configuration; import android.opengl.ManagedEGLContext; import android.os.IBinder; +import android.os.ServiceManager; import android.os.SystemProperties; import android.util.AndroidRuntimeException; import android.util.Log; @@ -111,6 +112,7 @@ public class WindowManagerImpl implements WindowManager { public static final int ADD_PERMISSION_DENIED = -8; private static WindowManagerImpl sDefaultWindowManager; + private static IWindowManager sWindowManagerService; private final WindowManagerState mState; private final Window mParentWindow; @@ -135,6 +137,16 @@ public class WindowManagerImpl implements WindowManager { } } + public static IWindowManager getWindowManagerService() { + synchronized (WindowManagerImpl.class) { + if (sWindowManagerService == null) { + sWindowManagerService = IWindowManager.Stub.asInterface( + ServiceManager.getService("window")); + } + return sWindowManagerService; + } + } + public WindowManagerImpl makeLocal(Window parentWindow) { return new WindowManagerImpl(mState, parentWindow, parentWindow.getCompatibilityInfo()); } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 25f01319ea54..5be9899f29bc 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -4837,18 +4837,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText); + final boolean isLayoutRtl = isLayoutRtl(); + final int layoutDirection = getResolvedLayoutDirection(); final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection); if (mEllipsize == TextUtils.TruncateAt.MARQUEE && mMarqueeFadeMode != MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) { if (!mSingleLine && getLineCount() == 1 && canMarquee() && (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) { - canvas.translate(mLayout.getLineRight(0) - (mRight - mLeft - - getCompoundPaddingLeft() - getCompoundPaddingRight()), 0.0f); + final int width = mRight - mLeft; + final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight(); + final float dx = mLayout.getLineRight(0) - (width - padding); + canvas.translate(isLayoutRtl ? -dx : +dx, 0.0f); } if (mMarquee != null && mMarquee.isRunning()) { - canvas.translate(-mMarquee.mScroll, 0.0f); + final float dx = -mMarquee.getScroll(); + canvas.translate(isLayoutRtl ? -dx : +dx, 0.0f); } } @@ -4862,7 +4867,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } if (mMarquee != null && mMarquee.shouldDrawGhost()) { - canvas.translate((int) mMarquee.getGhostOffset(), 0.0f); + final int dx = (int) mMarquee.getGhostOffset(); + canvas.translate(isLayoutRtl ? -dx : dx, 0.0f); layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical); } @@ -7455,7 +7461,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (mMarquee != null && !mMarquee.isStopped()) { final Marquee marquee = mMarquee; if (marquee.shouldDrawLeftFade()) { - return marquee.mScroll / getHorizontalFadingEdgeLength(); + final float scroll = marquee.getScroll(); + return scroll / getHorizontalFadingEdgeLength(); } else { return 0.0f; } @@ -7483,7 +7490,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mMarqueeFadeMode != MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS) { if (mMarquee != null && !mMarquee.isStopped()) { final Marquee marquee = mMarquee; - return (marquee.mMaxFadeScroll - marquee.mScroll) / getHorizontalFadingEdgeLength(); + final float maxFadeScroll = marquee.getMaxFadeScroll(); + final float scroll = marquee.getScroll(); + return (maxFadeScroll - scroll) / getHorizontalFadingEdgeLength(); } else if (getLineCount() == 1) { final int layoutDirection = getResolvedLayoutDirection(); final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection); @@ -8577,13 +8586,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private byte mStatus = MARQUEE_STOPPED; private final float mScrollUnit; private float mMaxScroll; - float mMaxFadeScroll; + private float mMaxFadeScroll; private float mGhostStart; private float mGhostOffset; private float mFadeStop; private int mRepeatLimit; - float mScroll; + private float mScroll; Marquee(TextView v) { final float density = v.getContext().getResources().getDisplayMetrics().density; @@ -8675,6 +8684,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return mGhostOffset; } + float getScroll() { + return mScroll; + } + + float getMaxFadeScroll() { + return mMaxFadeScroll; + } + boolean shouldDrawLeftFade() { return mScroll <= mFadeStop; } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index e429ffcc623d..b1423ca7f7f2 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -44,7 +44,6 @@ LOCAL_SRC_FILES:= \ android_database_SQLiteGlobal.cpp \ android_database_SQLiteDebug.cpp \ android_emoji_EmojiFactory.cpp \ - android_view_Display.cpp \ android_view_DisplayEventReceiver.cpp \ android_view_Surface.cpp \ android_view_TextureView.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index f0dd32165d24..c936b0bb68b8 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -116,7 +116,6 @@ extern int register_android_graphics_Region(JNIEnv* env); extern int register_android_graphics_SurfaceTexture(JNIEnv* env); extern int register_android_graphics_Xfermode(JNIEnv* env); extern int register_android_graphics_PixelFormat(JNIEnv* env); -extern int register_android_view_Display(JNIEnv* env); extern int register_android_view_DisplayEventReceiver(JNIEnv* env); extern int register_android_view_GLES20DisplayList(JNIEnv* env); extern int register_android_view_GLES20Canvas(JNIEnv* env); @@ -1088,7 +1087,6 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_SystemProperties), REG_JNI(register_android_os_Binder), REG_JNI(register_android_os_Parcel), - REG_JNI(register_android_view_Display), REG_JNI(register_android_view_DisplayEventReceiver), REG_JNI(register_android_nio_utils), REG_JNI(register_android_graphics_PixelFormat), diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp deleted file mode 100644 index aedf1e42cf73..000000000000 --- a/core/jni/android_view_Display.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2007 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 <stdio.h> -#include <assert.h> - -#include <cutils/properties.h> - -#include <gui/SurfaceComposerClient.h> -#include <ui/PixelFormat.h> -#include <ui/DisplayInfo.h> - -#include "jni.h" -#include "JNIHelp.h" -#include <android_runtime/AndroidRuntime.h> -#include <utils/misc.h> -#include <utils/Log.h> -#include <cutils/properties.h> - -// ---------------------------------------------------------------------------- - -namespace android { - -// ---------------------------------------------------------------------------- - -struct offsets_t { - jfieldID display; - jfieldID pixelFormat; - jfieldID fps; - jfieldID density; - jfieldID xdpi; - jfieldID ydpi; -}; -static offsets_t offsets; -static bool headless = false; - -// ---------------------------------------------------------------------------- - -static void android_view_Display_init( - JNIEnv* env, jobject clazz, jint dpy) -{ - DisplayInfo info; - if (headless) { - // initialize dummy display with reasonable values - info.pixelFormatInfo.format = 1; // RGB_8888 - info.fps = 60; - info.density = 160; - info.xdpi = 160; - info.ydpi = 160; - } else { - status_t err = SurfaceComposerClient::getDisplayInfo(DisplayID(dpy), &info); - if (err < 0) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return; - } - } - env->SetIntField(clazz, offsets.pixelFormat,info.pixelFormatInfo.format); - env->SetFloatField(clazz, offsets.fps, info.fps); - env->SetFloatField(clazz, offsets.density, info.density); - env->SetFloatField(clazz, offsets.xdpi, info.xdpi); - env->SetFloatField(clazz, offsets.ydpi, info.ydpi); -} - -static jint android_view_Display_getRawWidthNative( - JNIEnv* env, jobject clazz) -{ - if (headless) return 640; - DisplayID dpy = env->GetIntField(clazz, offsets.display); - return SurfaceComposerClient::getDisplayWidth(dpy); -} - -static jint android_view_Display_getRawHeightNative( - JNIEnv* env, jobject clazz) -{ - if (headless) return 480; - DisplayID dpy = env->GetIntField(clazz, offsets.display); - return SurfaceComposerClient::getDisplayHeight(dpy); -} - -static jint android_view_Display_getOrientation( - JNIEnv* env, jobject clazz) -{ - if (headless) return 0; // Surface.ROTATION_0 - DisplayID dpy = env->GetIntField(clazz, offsets.display); - return SurfaceComposerClient::getDisplayOrientation(dpy); -} - -static jint android_view_Display_getDisplayCount( - JNIEnv* env, jclass clazz) -{ - if (headless) return 1; - return SurfaceComposerClient::getNumberOfDisplays(); -} - -// ---------------------------------------------------------------------------- - -const char* const kClassPathName = "android/view/Display"; - -static void nativeClassInit(JNIEnv* env, jclass clazz); - -static JNINativeMethod gMethods[] = { - { "nativeClassInit", "()V", - (void*)nativeClassInit }, - { "getDisplayCount", "()I", - (void*)android_view_Display_getDisplayCount }, - { "init", "(I)V", - (void*)android_view_Display_init }, - { "getRawWidthNative", "()I", - (void*)android_view_Display_getRawWidthNative }, - { "getRawHeightNative", "()I", - (void*)android_view_Display_getRawHeightNative }, - { "getOrientation", "()I", - (void*)android_view_Display_getOrientation } -}; - -void nativeClassInit(JNIEnv* env, jclass clazz) -{ - char value[PROPERTY_VALUE_MAX]; - - property_get("ro.config.headless", value, "0"); - if (strcmp(value, "1") == 0) - headless = true; - - offsets.display = env->GetFieldID(clazz, "mDisplay", "I"); - offsets.pixelFormat = env->GetFieldID(clazz, "mPixelFormat", "I"); - offsets.fps = env->GetFieldID(clazz, "mRefreshRate", "F"); - offsets.density = env->GetFieldID(clazz, "mDensity", "F"); - offsets.xdpi = env->GetFieldID(clazz, "mDpiX", "F"); - offsets.ydpi = env->GetFieldID(clazz, "mDpiY", "F"); -} - -int register_android_view_Display(JNIEnv* env) -{ - return AndroidRuntime::registerNativeMethods(env, - kClassPathName, gMethods, NELEM(gMethods)); -} - -}; diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 60f8c48a64d4..3cd28b113a72 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -473,9 +473,9 @@ static void Surface_closeTransaction( } static void Surface_setOrientation( - JNIEnv* env, jobject clazz, jint display, jint orientation, jint flags) + JNIEnv* env, jobject clazz, jint display, jint orientation) { - int err = SurfaceComposerClient::setOrientation(display, orientation, flags); + int err = SurfaceComposerClient::setOrientation(display, orientation, 0); if (err < 0) { doThrowIAE(env); } @@ -839,7 +839,7 @@ static JNINativeMethod gSurfaceMethods[] = { {"unlockCanvas", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas }, {"openTransaction", "()V", (void*)Surface_openTransaction }, {"closeTransaction", "()V", (void*)Surface_closeTransaction }, - {"setOrientation", "(III)V", (void*)Surface_setOrientation }, + {"setOrientation", "(II)V", (void*)Surface_setOrientation }, {"screenshot", "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll }, {"screenshot", "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot }, {"setLayer", "(I)V", (void*)Surface_setLayer }, diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index c6c4d5f09265..04765cf948f4 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -824,7 +824,7 @@ <string name="searchview_description_query" msgid="5911778593125355124">"Zoekopdracht"</string> <string name="searchview_description_clear" msgid="1330281990951833033">"Zoekopdracht wissen"</string> <string name="searchview_description_submit" msgid="2688450133297983542">"Zoekopdracht verzenden"</string> - <string name="searchview_description_voice" msgid="2453203695674994440">"Spraakgestuurd zoeken"</string> + <string name="searchview_description_voice" msgid="2453203695674994440">"Gesproken zoekopdrachten"</string> <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\'Verkennen via aanraking\' aan?"</string> <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de tablet."</string> <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wil \'Verkennen via aanraking\' inschakelen. Wanneer \'Verkennen via aanraking\' is ingeschakeld, kunt u beschrijvingen beluisteren of bekijken van wat er onder uw vinger staat of aanraakbewerkingen uitvoeren op de telefoon."</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 59cdab140c1b..7c9a500abe96 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -245,7 +245,7 @@ <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Ivumela insiza ukuthi ithole okuqukethe kwi-Window. Izinsiza ezinobungozi zingathola kabush iwindi eliphelele bese ibheka konke okuqukethwe ngaphandle kwaaaphasiwedi."</string> <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"buyisa ulwazi lewindi"</string> <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Ivumela uhlelo lokusebenza ukubuyisa ulwazi mayelana namawindi avela kumphathi wewindi. Izinhlelo zokusebenza zingabuyisa ulwazi olubhekiswe ukusetshenziselwa kohlelo lwangaphakathi."</string> - <string name="permlab_filter_events" msgid="8675535648807427389">"hlunga izehlakalo"</string> + <string name="permlab_filter_events" msgid="8675535648807427389">"hlunga imicimbi"</string> <string name="permdesc_filter_events" msgid="8006236315888347680">"Ivumela uhlelo lokusebenza ukubhalisa isihlungi sokufaka ukusakaza kwazo zonke izehlakalo zomsebenzisi ngaphambi kokuthunyelwa. Izinhlelo zokusebenza zingalawula i-UI yohlelo ngaphandle kokungena komsebenzisi."</string> <string name="permlab_shutdown" msgid="7185747824038909016">"ukuvala shaqa kwengxenye"</string> <string name="permdesc_shutdown" msgid="7046500838746291775">"Ibeka imeneja yomsebenzi kwisimo sokuvala shaqa. Ayenzi ukuvala shaqa okuphelele."</string> diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java index f01562cf8911..6630601ee35b 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java @@ -94,7 +94,6 @@ public class ConnectivityManagerTestActivity extends Activity { * Control Wifi States */ public WifiManager mWifiManager; - public WifiManager.Channel mChannel; /* * Verify connectivity state @@ -242,7 +241,6 @@ public class ConnectivityManagerTestActivity extends Activity { // Get an instance of WifiManager mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE); mContext = this; - mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null); if (mWifiManager.isWifiApEnabled()) { // if soft AP is enabled, disable it @@ -599,7 +597,7 @@ public class ConnectivityManagerTestActivity extends Activity { log("found " + ssid + " in the scan result list"); log("retry: " + retry); foundApInScanResults = true; - mWifiManager.connect(mChannel, config, + mWifiManager.connect(config, new WifiManager.ActionListener() { public void onSuccess() { } @@ -658,7 +656,7 @@ public class ConnectivityManagerTestActivity extends Activity { for (WifiConfiguration wifiConfig: wifiConfigList) { log("remove wifi configuration: " + wifiConfig.networkId); int netId = wifiConfig.networkId; - mWifiManager.forget(mChannel, netId, new WifiManager.ActionListener() { + mWifiManager.forget(netId, new WifiManager.ActionListener() { public void onSuccess() { } public void onFailure(int reason) { diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java index 8d73bc025359..81075efbdb47 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java @@ -63,7 +63,6 @@ public class WifiConnectionTest private ConnectivityManagerTestActivity mAct; private ConnectivityManagerTestRunner mRunner; private WifiManager mWifiManager = null; - private WifiManager.Channel mChannel; private Set<WifiConfiguration> enabledNetworks = null; public WifiConnectionTest() { @@ -77,7 +76,6 @@ public class WifiConnectionTest mWifiManager = (WifiManager) mRunner.getContext().getSystemService(Context.WIFI_SERVICE); mAct = getActivity(); - mChannel = mWifiManager.initialize(mAct, mAct.getMainLooper(), null); networks = mAct.loadNetworkConfigurations(); if (DEBUG) { @@ -93,24 +91,6 @@ public class WifiConnectionTest assertTrue("wpa_supplicant is not started ", mAct.mWifiManager.pingSupplicant()); } - private class WifiServiceHandler extends Handler { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: - if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { - //AsyncChannel in msg.obj - } else { - log("Failed to establish AsyncChannel connection"); - } - break; - default: - //Ignore - break; - } - } - } - private void printNetworkConfigurations() { log("==== print network configurations parsed from XML file ===="); log("number of access points: " + networks.size()); diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java index c3cc7c5d60fb..d5fcc1cd4f27 100644 --- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java +++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java @@ -74,7 +74,6 @@ public class ConnectionUtil { private int mWifiState; private NetworkInfo mWifiNetworkInfo; private WifiManager mWifiManager; - private WifiManager.Channel mChannel; private Context mContext; // Verify connectivity state private static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1; @@ -115,7 +114,6 @@ public class ConnectionUtil { // Get an instance of WifiManager mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); - mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null); mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE); @@ -574,7 +572,7 @@ public class ConnectionUtil { Log.v(LOG_TAG, "Found " + ssid + " in the scan result list."); Log.v(LOG_TAG, "Retry: " + retry); foundApInScanResults = true; - mWifiManager.connect(mChannel, config, new WifiManager.ActionListener() { + mWifiManager.connect(config, new WifiManager.ActionListener() { public void onSuccess() { } public void onFailure(int reason) { @@ -628,7 +626,7 @@ public class ConnectionUtil { for (WifiConfiguration wifiConfig: wifiConfigList) { Log.v(LOG_TAG, "Remove wifi configuration: " + wifiConfig.networkId); int netId = wifiConfig.networkId; - mWifiManager.forget(mChannel, netId, new WifiManager.ActionListener() { + mWifiManager.forget(netId, new WifiManager.ActionListener() { public void onSuccess() { } public void onFailure(int reason) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 00d6d6f28c18..63c9b79d05cb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -22,6 +22,7 @@ import android.animation.ObjectAnimator; import android.app.StatusBarManager; import android.content.Context; import android.content.res.Resources; +import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; @@ -431,13 +432,14 @@ public class NavigationBarView extends LinearLayout { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("NavigationBarView {"); final Rect r = new Rect(); + final Point size = new Point(); + mDisplay.getRealSize(size); pw.println(String.format(" this: " + PhoneStatusBar.viewInfo(this) + " " + visibilityToString(getVisibility()))); getWindowVisibleDisplayFrame(r); - final boolean offscreen = r.right > mDisplay.getRawWidth() - || r.bottom > mDisplay.getRawHeight(); + final boolean offscreen = r.right > size.x || r.bottom > size.y; pw.println(" window: " + r.toShortString() + " " + visibilityToString(getWindowVisibility()) diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index cca9cbb4656a..867f4f4ef7d1 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -340,8 +340,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mSystemReady; boolean mSystemBooted; boolean mHdmiPlugged; - int mExternalDisplayWidth; - int mExternalDisplayHeight; int mUiMode; int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED; int mLidOpenRotation; @@ -998,9 +996,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - mExternalDisplayWidth = mDisplay.getRawExternalWidth(); - mExternalDisplayHeight = mDisplay.getRawExternalHeight(); - mStatusBarHeight = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); @@ -3037,10 +3032,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { void setHdmiPlugged(boolean plugged) { if (mHdmiPlugged != plugged) { mHdmiPlugged = plugged; - if (plugged && mDisplay != null) { - mExternalDisplayWidth = mDisplay.getRawExternalWidth(); - mExternalDisplayHeight = mDisplay.getRawExternalHeight(); - } updateRotation(true, true); Intent intent = new Intent(ACTION_HDMI_PLUGGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index 77b3b5042cab..8836bac2e39d 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -36,6 +36,7 @@ import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; +import android.graphics.Point; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -49,6 +50,7 @@ import android.util.Pair; import android.util.Slog; import android.util.TypedValue; import android.util.Xml; +import android.view.Display; import android.view.WindowManager; import android.widget.RemoteViews; @@ -188,11 +190,12 @@ class AppWidgetServiceImpl { void computeMaximumWidgetBitmapMemory() { WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); - int height = wm.getDefaultDisplay().getRawHeight(); - int width = wm.getDefaultDisplay().getRawWidth(); + Display display = wm.getDefaultDisplay(); + Point size = new Point(); + display.getRealSize(size); // Cap memory usage at 1.5 times the size of the display // 1.5 * 4 bytes/pixel * w * h ==> 6 * w * h - mMaxWidgetBitmapMemory = 6 * width * height; + mMaxWidgetBitmapMemory = 6 * size.x * size.y; } public void systemReady(boolean safeMode) { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 218545638550..d766afd09037 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -49,6 +49,7 @@ import com.android.internal.os.SamplingProfilerIntegration; import com.android.internal.widget.LockSettingsService; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.am.ActivityManagerService; +import com.android.server.display.DisplayManagerService; import com.android.server.input.InputManagerService; import com.android.server.net.NetworkPolicyManagerService; import com.android.server.net.NetworkStatsService; @@ -115,6 +116,7 @@ class ServerThread extends Thread { LightsService lights = null; PowerManagerService power = null; + DisplayManagerService display = null; BatteryService battery = null; VibratorService vibrator = null; AlarmManagerService alarm = null; @@ -148,8 +150,13 @@ class ServerThread extends Thread { power = new PowerManagerService(); ServiceManager.addService(Context.POWER_SERVICE, power); + Slog.i(TAG, "Display Manager"); + display = new DisplayManagerService(); + ServiceManager.addService(Context.DISPLAY_SERVICE, display); + Slog.i(TAG, "Activity Manager"); context = ActivityManagerService.main(factoryTest); + display.setContext(context); Slog.i(TAG, "Telephony Registry"); ServiceManager.addService("telephony.registry", new TelephonyRegistry(context)); @@ -214,7 +221,7 @@ class ServerThread extends Thread { // only initialize the power service after we have started the // lights service, content providers and the battery service. - power.init(context, lights, ActivityManagerService.self(), battery); + power.init(context, lights, ActivityManagerService.self(), battery, display); Slog.i(TAG, "Alarm Manager"); alarm = new AlarmManagerService(context); @@ -225,7 +232,7 @@ class ServerThread extends Thread { ActivityManagerService.self()); Slog.i(TAG, "Window Manager"); - wm = WindowManagerService.main(context, power, + wm = WindowManagerService.main(context, power, display, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL, !firstBoot, onlyCore); ServiceManager.addService(Context.WINDOW_SERVICE, wm); diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java index c23a1d9c10ec..087e8db2deeb 100644 --- a/services/java/com/android/server/TelephonyRegistry.java +++ b/services/java/com/android/server/TelephonyRegistry.java @@ -35,6 +35,7 @@ import android.text.TextUtils; import android.util.Slog; import java.util.ArrayList; +import java.util.List; import java.io.FileDescriptor; import java.io.PrintWriter; import java.net.NetworkInterface; @@ -109,7 +110,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN; - private CellInfo mCellInfo = null; + private List<CellInfo> mCellInfo = null; static final int PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | @@ -242,7 +243,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { try { - r.callback.onCellInfoChanged(new CellInfo(mCellInfo)); + r.callback.onCellInfoChanged(mCellInfo); } catch (RemoteException ex) { remove(r.binder); } @@ -336,7 +337,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { broadcastSignalStrengthChanged(signalStrength); } - public void notifyCellInfo(CellInfo cellInfo) { + public void notifyCellInfo(List<CellInfo> cellInfo) { if (!checkNotifyPermission("notifyCellInfo()")) { return; } @@ -346,7 +347,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { try { - r.callback.onCellInfoChanged(new CellInfo(cellInfo)); + r.callback.onCellInfoChanged(cellInfo); } catch (RemoteException ex) { mRemoveList.add(r.binder); } diff --git a/services/java/com/android/server/display/DisplayAdapter.java b/services/java/com/android/server/display/DisplayAdapter.java new file mode 100644 index 000000000000..e150bf8adf02 --- /dev/null +++ b/services/java/com/android/server/display/DisplayAdapter.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012 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.server.display; + +/** + * A display adapter makes one or more display devices available to the system. + * <p> + * For now, all display adapters are registered in the system server but + * in principle it could be done from other processes. + * </p> + */ +public abstract class DisplayAdapter { + /** + * Gets the display adapter name. + * @return The display adapter name. + */ + public abstract String getName(); + + // TODO: dynamically register display devices + public abstract DisplayDevice[] getDisplayDevices(); +} diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java new file mode 100644 index 000000000000..6d723f24b78e --- /dev/null +++ b/services/java/com/android/server/display/DisplayDevice.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2012 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.server.display; + +/** + * Represents a physical display device such as the built-in display + * or an external monitor. + */ +public abstract class DisplayDevice { + public abstract void getInfo(DisplayDeviceInfo outInfo); +} diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java new file mode 100644 index 000000000000..c28b9bbea7cb --- /dev/null +++ b/services/java/com/android/server/display/DisplayDeviceInfo.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012 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.server.display; + +/** + * Describes the characteristics of a physical display device. + */ +public final class DisplayDeviceInfo { + /** + * The width of the display in its natural orientation, in pixels. + * This value is not affected by display rotation. + */ + public int width; + + /** + * The height of the display in its natural orientation, in pixels. + * This value is not affected by display rotation. + */ + public int height; + + public float refreshRate; + public float density; + public float xDpi; + public float yDpi; + + public void copyFrom(DisplayDeviceInfo other) { + width = other.width; + height = other.height; + refreshRate = other.refreshRate; + density = other.density; + xDpi = other.xDpi; + yDpi = other.yDpi; + } + + @Override + public String toString() { + return width + " x " + height + ", " + refreshRate + " fps, " + + "density " + density + ", " + xDpi + " x " + yDpi + " dpi"; + } +} diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java new file mode 100644 index 000000000000..082d28fec89c --- /dev/null +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2012 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.server.display; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.hardware.display.IDisplayManager; +import android.os.Binder; +import android.os.SystemProperties; +import android.view.Display; +import android.view.DisplayInfo; +import android.view.Surface; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; + +/** + * Manages the properties, media routing and power state of attached displays. + * <p> + * The display manager service does not own or directly control the displays. + * Instead, other components in the system register their display adapters with the + * display manager service which acts as a central controller. + * </p> + */ +public final class DisplayManagerService extends IDisplayManager.Stub { + private static final String TAG = "DisplayManagerService"; + + private static final String SYSTEM_HEADLESS = "ro.config.headless"; + + private final Object mLock = new Object(); + + private Context mContext; + private final boolean mHeadless; + private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); + + // TODO: represent this as a map between logical and physical devices + private DisplayInfo mDefaultDisplayInfo; + private DisplayDevice mDefaultDisplayDevice; + private DisplayDeviceInfo mDefaultDisplayDeviceInfo; + + public DisplayManagerService() { + mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1"); + registerDisplayAdapters(); + initializeDefaultDisplay(); + } + + public void setContext(Context context) { + mContext = context; + } + + // FIXME: this isn't the right API for the long term + public void setDefaultDisplayInfo(DisplayInfo info) { + synchronized (mLock) { + mDefaultDisplayInfo.copyFrom(info); + } + } + + // FIXME: this isn't the right API for the long term + public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) { + // hardcoded assuming 720p touch screen plugged into HDMI and USB + // need to redesign this + info.width = 1280; + info.height = 720; + } + + public boolean isHeadless() { + return mHeadless; + } + + @Override // Binder call + public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) { + synchronized (mLock) { + if (displayId == Display.DEFAULT_DISPLAY) { + outInfo.copyFrom(mDefaultDisplayInfo); + return true; + } + return false; + } + } + + @Override // Binder call + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (mContext == null + || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump DisplayManager from from pid=" + + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); + return; + } + + pw.println("DISPLAY MANAGER (dumpsys display)\n"); + + pw.println("Headless: " + mHeadless); + + DisplayDeviceInfo info = new DisplayDeviceInfo(); + for (DisplayAdapter adapter : mDisplayAdapters) { + pw.println("Displays for adapter " + adapter.getName()); + for (DisplayDevice device : adapter.getDisplayDevices()) { + device.getInfo(info); + pw.print(" "); + pw.println(info); + } + } + } + + private void registerDisplayAdapters() { + if (mHeadless) { + registerDisplayAdapter(new HeadlessDisplayAdapter()); + } else { + registerDisplayAdapter(new SurfaceFlingerDisplayAdapter()); + } + } + + private void registerDisplayAdapter(DisplayAdapter adapter) { + // TODO: do this dynamically + mDisplayAdapters.add(adapter); + mDefaultDisplayDevice = adapter.getDisplayDevices()[0]; + mDefaultDisplayDeviceInfo = new DisplayDeviceInfo(); + mDefaultDisplayDevice.getInfo(mDefaultDisplayDeviceInfo); + } + + private void initializeDefaultDisplay() { + // Bootstrap the default logical display using the default physical display. + mDefaultDisplayInfo = new DisplayInfo(); + mDefaultDisplayInfo.appWidth = mDefaultDisplayDeviceInfo.width; + mDefaultDisplayInfo.appHeight = mDefaultDisplayDeviceInfo.height; + mDefaultDisplayInfo.logicalWidth = mDefaultDisplayDeviceInfo.width; + mDefaultDisplayInfo.logicalHeight = mDefaultDisplayDeviceInfo.height; + mDefaultDisplayInfo.rotation = Surface.ROTATION_0; + mDefaultDisplayInfo.refreshRate = mDefaultDisplayDeviceInfo.refreshRate; + mDefaultDisplayInfo.logicalDensity = mDefaultDisplayDeviceInfo.density; + mDefaultDisplayInfo.physicalXDpi = mDefaultDisplayDeviceInfo.xDpi; + mDefaultDisplayInfo.physicalYDpi = mDefaultDisplayDeviceInfo.yDpi; + mDefaultDisplayInfo.smallestNominalAppWidth = mDefaultDisplayDeviceInfo.width; + mDefaultDisplayInfo.smallestNominalAppHeight = mDefaultDisplayDeviceInfo.height; + mDefaultDisplayInfo.largestNominalAppWidth = mDefaultDisplayDeviceInfo.width; + mDefaultDisplayInfo.largestNominalAppHeight = mDefaultDisplayDeviceInfo.height; + } +} diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java new file mode 100644 index 000000000000..d2a70d2acf12 --- /dev/null +++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 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.server.display; + +/** + * Provides a fake default display for headless systems. + */ +public final class HeadlessDisplayAdapter extends DisplayAdapter { + private final DisplayDevice mDefaultDisplay = new DisplayDevice() { + @Override + public void getInfo(DisplayDeviceInfo outInfo) { + outInfo.width = 640; + outInfo.height = 480; + outInfo.refreshRate = 60; + outInfo.density = 1.0f; + outInfo.xDpi = 160; + outInfo.yDpi = 160; + } + }; + + @Override + public String getName() { + return "HeadlessDisplayAdapter"; + } + + @Override + public DisplayDevice[] getDisplayDevices() { + return new DisplayDevice[] { mDefaultDisplay }; + } +} diff --git a/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java new file mode 100644 index 000000000000..89934d3251b0 --- /dev/null +++ b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 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.server.display; + +/** + * A display adapter for the displays managed by Surface Flinger. + */ +public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter { + private static native void nativeGetDefaultDisplayDeviceInfo(DisplayDeviceInfo outInfo); + + private final DisplayDevice mDefaultDisplay = new DisplayDevice() { + @Override + public void getInfo(DisplayDeviceInfo outInfo) { + nativeGetDefaultDisplayDeviceInfo(outInfo); + } + }; + + @Override + public String getName() { + return "SurfaceFlingerDisplayAdapter"; + } + + @Override + public DisplayDevice[] getDisplayDevices() { + return new DisplayDevice[] { mDefaultDisplay }; + } +} diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java index 2940b70fb564..b3cd0f2f03d0 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/java/com/android/server/power/PowerManagerService.java @@ -22,6 +22,7 @@ import com.android.server.EventLogTags; import com.android.server.LightsService; import com.android.server.Watchdog; import com.android.server.am.BatteryStatsService; +import com.android.server.display.DisplayManagerService; import android.app.ActivityManagerNative; import android.app.IActivityManager; @@ -254,6 +255,7 @@ public class PowerManagerService extends IPowerManager.Stub private IActivityManager mActivityService; private IBatteryStats mBatteryStats; private BatteryService mBatteryService; + private DisplayManagerService mDisplayManagerService; private SensorManager mSensorManager; private Sensor mProximitySensor; private Sensor mLightSensor; @@ -543,12 +545,13 @@ public class PowerManagerService extends IPowerManager.Stub private ContentQueryMap mSettings; public void init(Context context, LightsService lights, IActivityManager activity, - BatteryService battery) { + BatteryService battery, DisplayManagerService displayManagerService) { mLightsService = lights; mContext = context; mActivityService = activity; mBatteryStats = BatteryStatsService.getService(); mBatteryService = battery; + mDisplayManagerService = displayManagerService; mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT); mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS); diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java index b2cf3e0c39fc..f0b0e1f68ae8 100644 --- a/services/java/com/android/server/wm/DragState.java +++ b/services/java/com/android/server/wm/DragState.java @@ -125,8 +125,8 @@ class DragState { // The drag window covers the entire display mDragWindowHandle.frameLeft = 0; mDragWindowHandle.frameTop = 0; - mDragWindowHandle.frameRight = mService.mCurDisplayWidth; - mDragWindowHandle.frameBottom = mService.mCurDisplayHeight; + mDragWindowHandle.frameRight = mService.mDisplayInfo.logicalWidth; + mDragWindowHandle.frameBottom = mService.mDisplayInfo.logicalHeight; // Pause rotations before a drag. if (WindowManagerService.DEBUG_ORIENTATION) { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index d0456ee403e9..ac0fa87d7e5f 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -45,6 +45,8 @@ import com.android.server.AttributeCache; import com.android.server.EventLogTags; import com.android.server.Watchdog; import com.android.server.am.BatteryStatsService; +import com.android.server.display.DisplayDeviceInfo; +import com.android.server.display.DisplayManagerService; import com.android.server.input.InputManagerService; import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; @@ -104,6 +106,7 @@ import android.util.SparseIntArray; import android.util.TypedValue; import android.view.Choreographer; import android.view.Display; +import android.view.DisplayInfo; import android.view.Gravity; import android.view.IApplicationToken; import android.view.IInputFilter; @@ -271,7 +274,6 @@ public class WindowManagerService extends IWindowManager.Stub private static final String SYSTEM_SECURE = "ro.secure"; private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; - private static final String SYSTEM_HEADLESS = "ro.config.headless"; /** * Condition waited on by {@link #reenableKeyguard} to know the call to @@ -482,14 +484,7 @@ public class WindowManagerService extends IWindowManager.Stub int mInitialDisplayHeight = 0; int mBaseDisplayWidth = 0; int mBaseDisplayHeight = 0; - int mCurDisplayWidth = 0; - int mCurDisplayHeight = 0; - int mAppDisplayWidth = 0; - int mAppDisplayHeight = 0; - int mSmallestDisplayWidth = 0; - int mSmallestDisplayHeight = 0; - int mLargestDisplayWidth = 0; - int mLargestDisplayHeight = 0; + final DisplayInfo mDisplayInfo = new DisplayInfo(); int mRotation = 0; int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -616,6 +611,7 @@ public class WindowManagerService extends IWindowManager.Stub float mAnimatorDurationScale = 1.0f; final InputManagerService mInputManager; + final DisplayManagerService mDisplayManager; // Who is holding the screen on. Session mHoldingScreenOn; @@ -785,9 +781,10 @@ public class WindowManagerService extends IWindowManager.Stub final boolean mOnlyCore; public static WindowManagerService main(Context context, - PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs, + PowerManagerService pm, DisplayManagerService dm, + boolean haveInputMethods, boolean allowBootMsgs, boolean onlyCore) { - WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs, onlyCore); + WMThread thr = new WMThread(context, pm, dm, haveInputMethods, allowBootMsgs, onlyCore); thr.start(); synchronized (thr) { @@ -806,15 +803,18 @@ public class WindowManagerService extends IWindowManager.Stub private final Context mContext; private final PowerManagerService mPM; + private final DisplayManagerService mDisplayManager; private final boolean mHaveInputMethods; private final boolean mAllowBootMessages; private final boolean mOnlyCore; public WMThread(Context context, PowerManagerService pm, + DisplayManagerService dm, boolean haveInputMethods, boolean allowBootMsgs, boolean onlyCore) { super("WindowManager"); mContext = context; mPM = pm; + mDisplayManager = dm; mHaveInputMethods = haveInputMethods; mAllowBootMessages = allowBootMsgs; mOnlyCore = onlyCore; @@ -825,7 +825,7 @@ public class WindowManagerService extends IWindowManager.Stub Looper.prepare(); //Looper.myLooper().setMessageLogging(new LogPrinter( // android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM)); - WindowManagerService s = new WindowManagerService(mContext, mPM, + WindowManagerService s = new WindowManagerService(mContext, mPM, mDisplayManager, mHaveInputMethods, mAllowBootMessages, mOnlyCore); android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_DISPLAY); @@ -892,6 +892,7 @@ public class WindowManagerService extends IWindowManager.Stub } private WindowManagerService(Context context, PowerManagerService pm, + DisplayManagerService displayManager, boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) { mContext = context; mHaveInputMethods = haveInputMethods; @@ -899,7 +900,8 @@ public class WindowManagerService extends IWindowManager.Stub mOnlyCore = onlyCore; mLimitedAlphaCompositing = context.getResources().getBoolean( com.android.internal.R.bool.config_sf_limitedAlpha); - mHeadless = "1".equals(SystemProperties.get(SYSTEM_HEADLESS, "0")); + mDisplayManager = displayManager; + mHeadless = displayManager.isHeadless(); mPowerManager = pm; mPowerManager.setPolicy(mPolicy); @@ -1650,8 +1652,8 @@ public class WindowManagerService extends IWindowManager.Stub mInnerFields.mWallpaperMayChange = false; int changed = 0; - final int dw = mAppDisplayWidth; - final int dh = mAppDisplayHeight; + final int dw = mDisplayInfo.appWidth; + final int dh = mDisplayInfo.appHeight; // First find top-most window that has asked to be on top of the // wallpaper; all wallpapers go behind it. @@ -2060,8 +2062,8 @@ public class WindowManagerService extends IWindowManager.Stub } void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) { - final int dw = mAppDisplayWidth; - final int dh = mAppDisplayHeight; + final int dw = mDisplayInfo.appWidth; + final int dh = mDisplayInfo.appHeight; WindowState target = mWallpaperTarget; if (target != null) { @@ -2123,8 +2125,8 @@ public class WindowManagerService extends IWindowManager.Stub void updateWallpaperVisibilityLocked() { final boolean visible = isWallpaperVisible(mWallpaperTarget); - final int dw = mAppDisplayWidth; - final int dh = mAppDisplayHeight; + final int dw = mDisplayInfo.appWidth; + final int dh = mDisplayInfo.appHeight; int curTokenIndex = mWallpaperTokens.size(); while (curTokenIndex > 0) { @@ -2699,9 +2701,11 @@ public class WindowManagerService extends IWindowManager.Stub mTmpFloats[Matrix.MSKEW_X] = dsdy; mTmpFloats[Matrix.MSCALE_Y] = dtdy; matrix.setValues(mTmpFloats); - final RectF dispRect = new RectF(0, 0, mCurDisplayWidth, mCurDisplayHeight); + final RectF dispRect = new RectF(0, 0, + mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); matrix.mapRect(dispRect); - window.mGivenTouchableRegion.set(0, 0, mCurDisplayWidth, mCurDisplayHeight); + window.mGivenTouchableRegion.set(0, 0, + mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top, (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE); window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; @@ -2981,7 +2985,8 @@ public class WindowManagerService extends IWindowManager.Stub configChanged = updateOrientationFromAppTokensLocked(false); performLayoutAndPlaceSurfacesLocked(); if (toBeDisplayed && win.mIsWallpaper) { - updateWallpaperOffsetLocked(win, mAppDisplayWidth, mAppDisplayHeight, false); + updateWallpaperOffsetLocked(win, + mDisplayInfo.appWidth, mDisplayInfo.appHeight, false); } if (win.mAppToken != null) { win.mAppToken.updateReportedVisibilityLocked(); @@ -3201,8 +3206,8 @@ public class WindowManagerService extends IWindowManager.Stub } if (enter) { // Entering app zooms out from the center of the initial rect. - float scaleW = mNextAppTransitionStartWidth / (float) mAppDisplayWidth; - float scaleH = mNextAppTransitionStartHeight / (float) mAppDisplayHeight; + float scaleW = mNextAppTransitionStartWidth / (float) mDisplayInfo.appWidth; + float scaleH = mNextAppTransitionStartHeight / (float) mDisplayInfo.appHeight; Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1, computePivot(mNextAppTransitionStartX, scaleW), computePivot(mNextAppTransitionStartY, scaleH)); @@ -3222,8 +3227,8 @@ public class WindowManagerService extends IWindowManager.Stub final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext, com.android.internal.R.interpolator.decelerate_cubic); a.setInterpolator(interpolator); - a.initialize(mAppDisplayWidth, mAppDisplayHeight, - mAppDisplayWidth, mAppDisplayHeight); + a.initialize(mDisplayInfo.appWidth, mDisplayInfo.appHeight, + mDisplayInfo.appWidth, mDisplayInfo.appHeight); return a; } @@ -3252,8 +3257,8 @@ public class WindowManagerService extends IWindowManager.Stub if (thumb) { // Animation for zooming thumbnail from its initial size to // filling the screen. - float scaleW = mAppDisplayWidth/thumbWidth; - float scaleH = mAppDisplayHeight/thumbHeight; + float scaleW = mDisplayInfo.appWidth/thumbWidth; + float scaleH = mDisplayInfo.appHeight/thumbHeight; Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH, computePivot(mNextAppTransitionStartX, 1/scaleW), @@ -3273,8 +3278,8 @@ public class WindowManagerService extends IWindowManager.Stub a = set; } else if (enter) { // Entering app zooms out from the center of the thumbnail. - float scaleW = thumbWidth / mAppDisplayWidth; - float scaleH = thumbHeight / mAppDisplayHeight; + float scaleW = thumbWidth / mDisplayInfo.appWidth; + float scaleH = thumbHeight / mDisplayInfo.appHeight; Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1, computePivot(mNextAppTransitionStartX, scaleW), computePivot(mNextAppTransitionStartY, scaleH)); @@ -3300,8 +3305,8 @@ public class WindowManagerService extends IWindowManager.Stub final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext, com.android.internal.R.interpolator.decelerate_quad); a.setInterpolator(interpolator); - a.initialize(mAppDisplayWidth, mAppDisplayHeight, - mAppDisplayWidth, mAppDisplayHeight); + a.initialize(mDisplayInfo.appWidth, mDisplayInfo.appHeight, + mDisplayInfo.appWidth, mDisplayInfo.appHeight); return a; } @@ -5498,8 +5503,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mWindowMap) { long ident = Binder.clearCallingIdentity(); - dw = mCurDisplayWidth; - dh = mCurDisplayHeight; + dw = mDisplayInfo.logicalWidth; + dh = mDisplayInfo.logicalHeight; int aboveAppLayer = mPolicy.windowTypeToLayerLw( WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER @@ -5793,8 +5798,7 @@ public class WindowManagerService extends IWindowManager.Stub mWaitingForConfig = true; mLayoutNeeded = true; startFreezingDisplayLocked(inTransaction); - mInputManager.setDisplayOrientation(0, rotation, - mDisplay != null ? mDisplay.getExternalRotation() : Surface.ROTATION_0); + mInputManager.setDisplayOrientation(0, rotation, Surface.ROTATION_0); // We need to update our screen size information to match the new // rotation. Note that this is redundant with the later call to @@ -5816,7 +5820,7 @@ public class WindowManagerService extends IWindowManager.Stub && mAnimator.mScreenRotationAnimation.hasScreenshot()) { if (mAnimator.mScreenRotationAnimation.setRotation(rotation, mFxSession, MAX_ANIMATION_DURATION, mTransitionAnimationScale, - mCurDisplayWidth, mCurDisplayHeight)) { + mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight)) { updateLayoutToAnimationLocked(); } } @@ -6315,18 +6319,18 @@ public class WindowManagerService extends IWindowManager.Stub private void adjustDisplaySizeRanges(int rotation, int dw, int dh) { final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation); - if (width < mSmallestDisplayWidth) { - mSmallestDisplayWidth = width; + if (width < mDisplayInfo.smallestNominalAppWidth) { + mDisplayInfo.smallestNominalAppWidth = width; } - if (width > mLargestDisplayWidth) { - mLargestDisplayWidth = width; + if (width > mDisplayInfo.largestNominalAppWidth) { + mDisplayInfo.largestNominalAppWidth = width; } final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation); - if (height < mSmallestDisplayHeight) { - mSmallestDisplayHeight = height; + if (height < mDisplayInfo.smallestNominalAppHeight) { + mDisplayInfo.smallestNominalAppHeight = height; } - if (height > mLargestDisplayHeight) { - mLargestDisplayHeight = height; + if (height > mDisplayInfo.largestNominalAppHeight) { + mDisplayInfo.largestNominalAppHeight = height; } } @@ -6423,10 +6427,10 @@ public class WindowManagerService extends IWindowManager.Stub unrotDw = dw; unrotDh = dh; } - mSmallestDisplayWidth = 1<<30; - mSmallestDisplayHeight = 1<<30; - mLargestDisplayWidth = 0; - mLargestDisplayHeight = 0; + mDisplayInfo.smallestNominalAppWidth = 1<<30; + mDisplayInfo.smallestNominalAppHeight = 1<<30; + mDisplayInfo.largestNominalAppWidth = 0; + mDisplayInfo.largestNominalAppHeight = 0; adjustDisplaySizeRanges(Surface.ROTATION_0, unrotDw, unrotDh); adjustDisplaySizeRanges(Surface.ROTATION_90, unrotDh, unrotDw); adjustDisplaySizeRanges(Surface.ROTATION_180, unrotDw, unrotDh); @@ -6437,7 +6441,7 @@ public class WindowManagerService extends IWindowManager.Stub sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw); sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh); sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw); - outConfig.smallestScreenWidthDp = (int)(mSmallestDisplayWidth / density); + outConfig.smallestScreenWidthDp = (int)(mDisplayInfo.smallestNominalAppWidth / density); outConfig.screenLayout = sl; } @@ -6481,33 +6485,25 @@ public class WindowManagerService extends IWindowManager.Stub || mRotation == Surface.ROTATION_270); final int realdw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth; final int realdh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight; + int dw = realdw; + int dh = realdh; - synchronized(mDisplaySizeLock) { - if (mAltOrientation) { - mCurDisplayWidth = realdw; - mCurDisplayHeight = realdh; - if (realdw > realdh) { - // Turn landscape into portrait. - int maxw = (int)(realdh/1.3f); - if (maxw < realdw) { - mCurDisplayWidth = maxw; - } - } else { - // Turn portrait into landscape. - int maxh = (int)(realdw/1.3f); - if (maxh < realdh) { - mCurDisplayHeight = maxh; - } + if (mAltOrientation) { + if (realdw > realdh) { + // Turn landscape into portrait. + int maxw = (int)(realdh/1.3f); + if (maxw < realdw) { + dw = maxw; } } else { - mCurDisplayWidth = realdw; - mCurDisplayHeight = realdh; + // Turn portrait into landscape. + int maxh = (int)(realdw/1.3f); + if (maxh < realdh) { + dh = maxh; + } } } - final int dw = mCurDisplayWidth; - final int dh = mCurDisplayHeight; - if (config != null) { int orientation = Configuration.ORIENTATION_SQUARE; if (dw < dh) { @@ -6518,25 +6514,26 @@ public class WindowManagerService extends IWindowManager.Stub config.orientation = orientation; } - // Update real display metrics. - mDisplay.getMetricsWithSize(mRealDisplayMetrics, mCurDisplayWidth, mCurDisplayHeight); - // Update application display metrics. - final DisplayMetrics dm = mDisplayMetrics; final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation); final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation); synchronized(mDisplaySizeLock) { - mAppDisplayWidth = appWidth; - mAppDisplayHeight = appHeight; - mAnimator.setDisplayDimensions(mCurDisplayWidth, mCurDisplayHeight, - mAppDisplayWidth, mAppDisplayHeight); + mDisplayInfo.rotation = mRotation; + mDisplayInfo.logicalWidth = dw; + mDisplayInfo.logicalHeight = dh; + mDisplayInfo.appWidth = appWidth; + mDisplayInfo.appHeight = appHeight; + mDisplayInfo.getLogicalMetrics(mRealDisplayMetrics, null); + mDisplayInfo.getAppMetrics(mDisplayMetrics, null); + mDisplayManager.setDefaultDisplayInfo(mDisplayInfo); + + mAnimator.setDisplayDimensions(dw, dh, appWidth, appHeight); } if (false) { - Slog.i(TAG, "Set app display size: " + mAppDisplayWidth - + " x " + mAppDisplayHeight); + Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight); } - mDisplay.getMetricsWithSize(dm, mAppDisplayWidth, mAppDisplayHeight); + final DisplayMetrics dm = mDisplayMetrics; mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm, mCompatDisplayMetrics); @@ -6843,27 +6840,26 @@ public class WindowManagerService extends IWindowManager.Stub mDisplay = wm.getDefaultDisplay(); mIsTouchDevice = mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TOUCHSCREEN); + synchronized(mDisplaySizeLock) { - mInitialDisplayWidth = mDisplay.getRawWidth(); - mInitialDisplayHeight = mDisplay.getRawHeight(); - int rot = mDisplay.getRotation(); - if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) { - // If the screen is currently rotated, we need to swap the - // initial width and height to get the true natural values. - int tmp = mInitialDisplayWidth; - mInitialDisplayWidth = mInitialDisplayHeight; - mInitialDisplayHeight = tmp; - } - mBaseDisplayWidth = mCurDisplayWidth = mAppDisplayWidth = mInitialDisplayWidth; - mBaseDisplayHeight = mCurDisplayHeight = mAppDisplayHeight = mInitialDisplayHeight; - mAnimator.setDisplayDimensions(mCurDisplayWidth, mCurDisplayHeight, - mAppDisplayWidth, mAppDisplayHeight); + // Bootstrap the default logical display from the display manager. + mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY, mDisplayInfo); + mInitialDisplayWidth = mDisplayInfo.logicalWidth; + mInitialDisplayHeight = mDisplayInfo.logicalHeight; + mBaseDisplayWidth = mInitialDisplayWidth; + mBaseDisplayHeight = mInitialDisplayHeight; + + mAnimator.setDisplayDimensions(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight, + mDisplayInfo.appWidth, mDisplayInfo.appHeight); } + + DisplayDeviceInfo info = new DisplayDeviceInfo(); + mDisplayManager.getDefaultExternalDisplayDeviceInfo(info); mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY, - mDisplay.getRawWidth(), mDisplay.getRawHeight(), - mDisplay.getRawExternalWidth(), mDisplay.getRawExternalHeight()); + mInitialDisplayWidth, mInitialDisplayHeight, + info.width, info.height); mInputManager.setDisplayOrientation(Display.DEFAULT_DISPLAY, - mDisplay.getRotation(), mDisplay.getExternalRotation()); + mDisplay.getRotation(), Surface.ROTATION_0); mPolicy.setInitialDisplaySize(mDisplay, mInitialDisplayWidth, mInitialDisplayHeight); } @@ -7471,20 +7467,6 @@ public class WindowManagerService extends IWindowManager.Stub return false; } - public void getDisplaySize(Point size) { - synchronized(mDisplaySizeLock) { - size.x = mAppDisplayWidth; - size.y = mAppDisplayHeight; - } - } - - public void getRealDisplaySize(Point size) { - synchronized(mDisplaySizeLock) { - size.x = mCurDisplayWidth; - size.y = mCurDisplayHeight; - } - } - public void getInitialDisplaySize(Point size) { synchronized(mDisplaySizeLock) { size.x = mInitialDisplayWidth; @@ -7492,23 +7474,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - public int getMaximumSizeDimension() { - synchronized(mDisplaySizeLock) { - // Do this based on the raw screen size, until we are smarter. - return mBaseDisplayWidth > mBaseDisplayHeight - ? mBaseDisplayWidth : mBaseDisplayHeight; - } - } - - public void getCurrentSizeRange(Point smallestSize, Point largestSize) { - synchronized(mDisplaySizeLock) { - smallestSize.x = mSmallestDisplayWidth; - smallestSize.y = mSmallestDisplayHeight; - largestSize.x = mLargestDisplayWidth; - largestSize.y = mLargestDisplayHeight; - } - } - public void setForcedDisplaySize(int longDimen, int shortDimen) { synchronized(mWindowMap) { int width, height; @@ -7899,8 +7864,8 @@ public class WindowManagerService extends IWindowManager.Stub mLayoutNeeded = false; - final int dw = mCurDisplayWidth; - final int dh = mCurDisplayHeight; + final int dw = mDisplayInfo.logicalWidth; + final int dh = mDisplayInfo.logicalHeight; final int NFW = mFakeWindows.size(); for (int i=0; i<NFW; i++) { @@ -8492,8 +8457,8 @@ public class WindowManagerService extends IWindowManager.Stub if (!mAnimator.isDimming(winAnimator)) { final int width, height; if (attrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) { - width = mCurDisplayWidth; - height = mCurDisplayHeight; + width = mDisplayInfo.logicalWidth; + height = mDisplayInfo.logicalHeight; } else { width = innerDw; height = innerDh; @@ -8537,10 +8502,10 @@ public class WindowManagerService extends IWindowManager.Stub } final long currentTime = SystemClock.uptimeMillis(); - final int dw = mCurDisplayWidth; - final int dh = mCurDisplayHeight; - final int innerDw = mAppDisplayWidth; - final int innerDh = mAppDisplayHeight; + final int dw = mDisplayInfo.logicalWidth; + final int dh = mDisplayInfo.logicalHeight; + final int innerDw = mDisplayInfo.appWidth; + final int innerDh = mDisplayInfo.appHeight; int i; @@ -9456,7 +9421,7 @@ public class WindowManagerService extends IWindowManager.Stub } mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext, - mFxSession, inTransaction, mCurDisplayWidth, mCurDisplayHeight, + mFxSession, inTransaction, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight, mDisplay.getRotation()); } } @@ -9486,7 +9451,7 @@ public class WindowManagerService extends IWindowManager.Stub && mAnimator.mScreenRotationAnimation.hasScreenshot()) { if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation"); if (mAnimator.mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION, - mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) { + mTransitionAnimationScale, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight)) { updateLayoutToAnimationLocked(); } else { mAnimator.mScreenRotationAnimation.kill(); @@ -9935,19 +9900,21 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" base="); pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight); } - final int rawWidth = mDisplay.getRawWidth(); - final int rawHeight = mDisplay.getRawHeight(); - if (rawWidth != mCurDisplayWidth || rawHeight != mCurDisplayHeight) { - pw.print(" raw="); pw.print(rawWidth); pw.print("x"); pw.print(rawHeight); + if (mInitialDisplayWidth != mDisplayInfo.logicalWidth + || mInitialDisplayHeight != mDisplayInfo.logicalHeight) { + pw.print(" init="); pw.print(mInitialDisplayWidth); + pw.print("x"); pw.print(mInitialDisplayHeight); } pw.print(" cur="); - pw.print(mCurDisplayWidth); pw.print("x"); pw.print(mCurDisplayHeight); + pw.print(mDisplayInfo.logicalWidth); + pw.print("x"); pw.print(mDisplayInfo.logicalHeight); pw.print(" app="); - pw.print(mAppDisplayWidth); pw.print("x"); pw.print(mAppDisplayHeight); - pw.print(" rng="); pw.print(mSmallestDisplayWidth); - pw.print("x"); pw.print(mSmallestDisplayHeight); - pw.print("-"); pw.print(mLargestDisplayWidth); - pw.print("x"); pw.println(mLargestDisplayHeight); + pw.print(mDisplayInfo.appWidth); + pw.print("x"); pw.print(mDisplayInfo.appHeight); + pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth); + pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight); + pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth); + pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight); } else { pw.println(" NO DISPLAY"); } diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index 94fd19944f1d..d37182878eae 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -480,7 +480,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) { mService.updateWallpaperOffsetLocked(this, - mService.mAppDisplayWidth, mService.mAppDisplayHeight, false); + mService.mDisplayInfo.appWidth, mService.mDisplayInfo.appHeight, false); } if (WindowManagerService.localLOGV) { diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index f08204fe5065..ce87f4c72323 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -151,8 +151,8 @@ class WindowStateAnimator { mAnimator = service.mAnimator; mPolicy = service.mPolicy; mContext = service.mContext; - mAnimDw = service.mAppDisplayWidth; - mAnimDh = service.mAppDisplayHeight; + mAnimDw = service.mDisplayInfo.appWidth; + mAnimDh = service.mDisplayInfo.appHeight; mWin = win; mAttachedWinAnimator = win.mAttachedWindow == null @@ -248,8 +248,8 @@ class WindowStateAnimator { " scale=" + mService.mWindowAnimationScale); mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDw, mAnimDh); - mAnimDw = mService.mAppDisplayWidth; - mAnimDh = mService.mAppDisplayHeight; + mAnimDw = mService.mDisplayInfo.appWidth; + mAnimDh = mService.mDisplayInfo.appHeight; mAnimation.setStartTime(currentTime); mLocalAnimating = true; mAnimating = true; @@ -1102,7 +1102,7 @@ class WindowStateAnimator { WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) { mService.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount, - mService.mAppDisplayWidth, mService.mAppDisplayHeight); + mService.mDisplayInfo.appWidth, mService.mDisplayInfo.appHeight); } } catch (RuntimeException e) { // If something goes wrong with the surface (such diff --git a/services/jni/Android.mk b/services/jni/Android.mk index d097a9338a76..43e59b2f7735 100644 --- a/services/jni/Android.mk +++ b/services/jni/Android.mk @@ -4,6 +4,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ com_android_server_AlarmManagerService.cpp \ com_android_server_BatteryService.cpp \ + com_android_server_display_SurfaceFlingerDisplayAdapter.cpp \ com_android_server_input_InputApplicationHandle.cpp \ com_android_server_input_InputManagerService.cpp \ com_android_server_input_InputWindowHandle.cpp \ diff --git a/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp b/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp new file mode 100644 index 000000000000..e636eed8072a --- /dev/null +++ b/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 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. + */ + +#define LOG_TAG "SurfaceFlingerDisplayAdapter" + +#include "JNIHelp.h" +#include "jni.h" +#include <android_runtime/AndroidRuntime.h> + +#include <gui/SurfaceComposerClient.h> +#include <ui/DisplayInfo.h> + +#include <utils/Log.h> + +namespace android { + +static struct { + jfieldID width; + jfieldID height; + jfieldID refreshRate; + jfieldID density; + jfieldID xDpi; + jfieldID yDpi; +} gDisplayDeviceInfoClassInfo; + + +static void nativeGetDefaultDisplayDeviceInfo(JNIEnv* env, jclass clazz, jobject infoObj) { + DisplayInfo info; + status_t err = SurfaceComposerClient::getDisplayInfo(0, &info); + if (err < 0) { + jniThrowExceptionFmt(env, "java/lang/RuntimeException", + "Could not get display info. err=%d", err); + return; + } + + env->SetIntField(infoObj, gDisplayDeviceInfoClassInfo.width, info.w); + env->SetIntField(infoObj, gDisplayDeviceInfoClassInfo.height, info.h); + env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.refreshRate, info.fps); + env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.density, info.density); + env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.xDpi, info.xdpi); + env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.yDpi, info.ydpi); +} + + +static JNINativeMethod gSurfaceFlingerDisplayAdapterMethods[] = { + /* name, signature, funcPtr */ + { "nativeGetDefaultDisplayDeviceInfo", + "(Lcom/android/server/display/DisplayDeviceInfo;)V", + (void*) nativeGetDefaultDisplayDeviceInfo }, +}; + +#define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(! var, "Unable to find class " className); + +#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ + var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find field " fieldName); + +int register_android_server_display_SurfaceFlingerDisplayAdapter(JNIEnv* env) { + int res = jniRegisterNativeMethods(env, + "com/android/server/display/SurfaceFlingerDisplayAdapter", + gSurfaceFlingerDisplayAdapterMethods, NELEM(gSurfaceFlingerDisplayAdapterMethods)); + LOG_FATAL_IF(res < 0, "Unable to register native methods."); + + jclass clazz; + FIND_CLASS(clazz, "com/android/server/display/DisplayDeviceInfo"); + GET_FIELD_ID(gDisplayDeviceInfoClassInfo.width, clazz, "width", "I"); + GET_FIELD_ID(gDisplayDeviceInfoClassInfo.height, clazz, "height", "I"); + GET_FIELD_ID(gDisplayDeviceInfoClassInfo.refreshRate, clazz, "refreshRate", "F"); + GET_FIELD_ID(gDisplayDeviceInfoClassInfo.density, clazz, "density", "F"); + GET_FIELD_ID(gDisplayDeviceInfoClassInfo.xDpi, clazz, "xDpi", "F"); + GET_FIELD_ID(gDisplayDeviceInfoClassInfo.yDpi, clazz, "yDpi", "F"); + return 0; +} + +} /* namespace android */ diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp index 423ebd135027..50873fccf82a 100644 --- a/services/jni/onload.cpp +++ b/services/jni/onload.cpp @@ -22,6 +22,7 @@ namespace android { int register_android_server_AlarmManagerService(JNIEnv* env); int register_android_server_BatteryService(JNIEnv* env); +int register_android_server_display_SurfaceFlingerDisplayAdapter(JNIEnv* env); int register_android_server_InputApplicationHandle(JNIEnv* env); int register_android_server_InputWindowHandle(JNIEnv* env); int register_android_server_InputManager(JNIEnv* env); @@ -51,6 +52,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) register_android_server_PowerManagerService(env); register_android_server_SerialService(env); + register_android_server_display_SurfaceFlingerDisplayAdapter(env); register_android_server_InputApplicationHandle(env); register_android_server_InputWindowHandle(env); register_android_server_InputManager(env); diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index 65c220f135c5..1f4f78e9d99d 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2012 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. @@ -20,70 +20,79 @@ import android.os.Parcel; import android.os.Parcelable; /** - * CellIdentity is to represent ONE unique cell in the world + * CellIdentity is immutable and represents ONE unique cell in the world * it contains all levels of info to identity country, carrier, etc. * - * @hide pending API review + * @hide */ public abstract class CellIdentity implements Parcelable { - // Cell is a GSM Cell {@link GsmCellIdentity} - public static final int CELLID_TYPE_GSM = 1; - // Cell is a CMDA Cell {@link CdmaCellIdentity} - public static final int CELLID_TYPE_CDMA = 2; - // Cell is a LTE Cell {@link LteCellIdentity} - public static final int CELLID_TYPE_LTE = 3; + // Type fields for parceling + protected static final int TYPE_GSM = 1; + protected static final int TYPE_CDMA = 2; + protected static final int TYPE_LTE = 3; - private int mCellIdType; - private String mCellIdAttributes; - - protected CellIdentity(int type, String attr) { - this.mCellIdType = type; - this.mCellIdAttributes = new String(attr); + protected CellIdentity() { } protected CellIdentity(Parcel in) { - this.mCellIdType = in.readInt(); - this.mCellIdAttributes = new String(in.readString()); } protected CellIdentity(CellIdentity cid) { - this.mCellIdType = cid.mCellIdType; - this.mCellIdAttributes = new String(cid.mCellIdAttributes); } /** - * @return Cell Identity type as one of CELLID_TYPE_XXXX + * @return a copy of this object with package visibility. */ - public int getCellIdType() { - return mCellIdType; - } + abstract CellIdentity copy(); + @Override + public abstract int hashCode(); - /** - * @return Cell identity attribute pairs - * Comma separated “key=value” pairs. - * key := must must an single alpha-numeric word - * value := “quoted value string” - * - * Current list of keys and values: - * type = fixed | mobile - */ - public String getCellIdAttributes() { - return mCellIdAttributes; + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (this == other) { + return true; + } + return (other instanceof CellIdentity); } + @Override + public String toString() { + return ""; + } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ @Override public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mCellIdType); - dest.writeString(mCellIdAttributes); } + + /** Implement the Parcelable interface */ + public static final Creator<CellIdentity> CREATOR = + new Creator<CellIdentity>() { + @Override + public CellIdentity createFromParcel(Parcel in) { + int type = in.readInt(); + switch (type) { + case TYPE_GSM: return CellIdentityGsm.createFromParcelBody(in); + case TYPE_CDMA: return CellIdentityCdma.createFromParcelBody(in); + case TYPE_LTE: return CellIdentityLte.createFromParcelBody(in); + default: throw new RuntimeException("Bad CellIdentity Parcel"); + } + } + + @Override + public CellIdentity[] newArray(int size) { + return new CellIdentity[size]; + } + }; } diff --git a/telephony/java/android/telephony/CdmaCellIdentity.java b/telephony/java/android/telephony/CellIdentityCdma.java index 5b8454ff7288..0169d89e06bd 100644 --- a/telephony/java/android/telephony/CdmaCellIdentity.java +++ b/telephony/java/android/telephony/CellIdentityCdma.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2012 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. @@ -18,13 +18,18 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; /** * CellIdentity is to represent a unique CDMA cell * - * @hide pending API review + * @hide */ -public final class CdmaCellIdentity extends CellIdentity implements Parcelable { +public final class CellIdentityCdma extends CellIdentity implements Parcelable { + + private static final String LOG_TAG = "CellSignalStrengthCdma"; + private static final boolean DBG = false; + // Network Id 0..65535 private final int mNetworkId; // CDMA System Id 0..32767 @@ -47,6 +52,17 @@ public final class CdmaCellIdentity extends CellIdentity implements Parcelable { private final int mLatitude; /** + * @hide + */ + public CellIdentityCdma() { + mNetworkId = Integer.MAX_VALUE; + mSystemId = Integer.MAX_VALUE; + mBasestationId = Integer.MAX_VALUE; + mLongitude = Integer.MAX_VALUE; + mLatitude = Integer.MAX_VALUE; + } + + /** * public constructor * @param nid Network Id 0..65535 * @param sid CDMA System Id 0..32767 @@ -55,11 +71,10 @@ public final class CdmaCellIdentity extends CellIdentity implements Parcelable { * to 2592000 * @param lat Latitude is a decimal number ranges from -1296000 * to 1296000 - * @param attr is comma separated “key=value” attribute pairs. + * + * @hide */ - public CdmaCellIdentity (int nid, int sid, - int bid, int lon, int lat, String attr) { - super(CELLID_TYPE_CDMA, attr); + public CellIdentityCdma (int nid, int sid, int bid, int lon, int lat) { mNetworkId = nid; mSystemId = sid; mBasestationId = bid; @@ -67,16 +82,7 @@ public final class CdmaCellIdentity extends CellIdentity implements Parcelable { mLatitude = lat; } - private CdmaCellIdentity(Parcel in) { - super(in); - mNetworkId = in.readInt(); - mSystemId = in.readInt(); - mBasestationId = in.readInt(); - mLongitude = in.readInt(); - mLatitude = in.readInt(); - } - - CdmaCellIdentity(CdmaCellIdentity cid) { + private CellIdentityCdma(CellIdentityCdma cid) { super(cid); mNetworkId = cid.mNetworkId; mSystemId = cid.mSystemId; @@ -85,6 +91,11 @@ public final class CdmaCellIdentity extends CellIdentity implements Parcelable { mLatitude = cid.mLatitude; } + @Override + CellIdentityCdma copy() { + return new CellIdentityCdma(this); + } + /** * @return Network Id 0..65535 */ @@ -118,9 +129,6 @@ public final class CdmaCellIdentity extends CellIdentity implements Parcelable { } /** - * @return Base station - */ - /** * @return Base station latitude, which is a decimal number as * specified in 3GPP2 C.S0005-A v6.0. It is represented in units * of 0.25 seconds and ranges from -1296000 to 1296000, both @@ -131,15 +139,55 @@ public final class CdmaCellIdentity extends CellIdentity implements Parcelable { return mLatitude; } - /** Implement the Parcelable interface {@hide} */ + @Override + public int hashCode() { + int primeNum = 31; + return (mNetworkId * primeNum) + (mSystemId * primeNum) + (mBasestationId * primeNum) + + (mLatitude * primeNum) + (mLongitude * primeNum); + } + + @Override + public boolean equals(Object other) { + if (super.equals(other)) { + try { + CellIdentityCdma o = (CellIdentityCdma)other; + return mNetworkId == o.mNetworkId && + mSystemId == o.mSystemId && + mBasestationId == o.mBasestationId && + mLatitude == o.mLatitude && + mLongitude == o.mLongitude; + } catch (ClassCastException e) { + return false; + } + } else { + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CdmaCellIdentitiy:"); + sb.append(super.toString()); + sb.append(" mNetworkId="); sb.append(mNetworkId); + sb.append(" mSystemId="); sb.append(mSystemId); + sb.append(" mBasestationId="); sb.append(mBasestationId); + sb.append(" mLongitude="); sb.append(mLongitude); + sb.append(" mLatitude="); sb.append(mLatitude); + + return sb.toString(); + } + + /** Implement the Parcelable interface */ @Override public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(TYPE_CDMA); super.writeToParcel(dest, flags); dest.writeInt(mNetworkId); dest.writeInt(mSystemId); @@ -148,17 +196,42 @@ public final class CdmaCellIdentity extends CellIdentity implements Parcelable { dest.writeInt(mLatitude); } - /** Implement the Parcelable interface {@hide} */ - public static final Creator<CdmaCellIdentity> CREATOR = - new Creator<CdmaCellIdentity>() { + /** Construct from Parcel, type has already been processed */ + private CellIdentityCdma(Parcel in) { + super(in); + mNetworkId = in.readInt(); + mSystemId = in.readInt(); + mBasestationId = in.readInt(); + mLongitude = in.readInt(); + mLatitude = in.readInt(); + if (DBG) log("CellIdentityCdma(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + @SuppressWarnings("hiding") + public static final Creator<CellIdentityCdma> CREATOR = + new Creator<CellIdentityCdma>() { @Override - public CdmaCellIdentity createFromParcel(Parcel in) { - return new CdmaCellIdentity(in); + public CellIdentityCdma createFromParcel(Parcel in) { + in.readInt(); // Skip past token, we know what it is + return createFromParcelBody(in); } @Override - public CdmaCellIdentity[] newArray(int size) { - return new CdmaCellIdentity[size]; + public CellIdentityCdma[] newArray(int size) { + return new CellIdentityCdma[size]; } }; + + /** @hide */ + static CellIdentityCdma createFromParcelBody(Parcel in) { + return new CellIdentityCdma(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } } diff --git a/telephony/java/android/telephony/GsmCellIdentity.java b/telephony/java/android/telephony/CellIdentityGsm.java index 159cb52b379d..f46cd4714c29 100644 --- a/telephony/java/android/telephony/GsmCellIdentity.java +++ b/telephony/java/android/telephony/CellIdentityGsm.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2012 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. @@ -18,13 +18,17 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; /** * CellIdentity to represent a unique GSM or UMTS cell * - * @hide pending API review + * @hide */ -public final class GsmCellIdentity extends CellIdentity implements Parcelable { +public final class CellIdentityGsm extends CellIdentity implements Parcelable { + + private static final String LOG_TAG = "CellIdentityGsm"; + private static final boolean DBG = false; // 3-digit Mobile Country Code, 0..999 private final int mMcc; @@ -39,17 +43,26 @@ public final class GsmCellIdentity extends CellIdentity implements Parcelable { private final int mPsc; /** + * @hide + */ + public CellIdentityGsm() { + mMcc = Integer.MAX_VALUE; + mMnc = Integer.MAX_VALUE; + mLac = Integer.MAX_VALUE; + mCid = Integer.MAX_VALUE; + mPsc = Integer.MAX_VALUE; + } + /** * public constructor * @param mcc 3-digit Mobile Country Code, 0..999 * @param mnc 2 or 3-digit Mobile Network Code, 0..999 * @param lac 16-bit Location Area Code, 0..65535 * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity * @param psc 9-bit UMTS Primary Scrambling Code - * @param attr is comma separated “key=value” attribute pairs. + * + * @hide */ - public GsmCellIdentity (int mcc, int mnc, - int lac, int cid, int psc, String attr) { - super(CELLID_TYPE_GSM, attr); + public CellIdentityGsm (int mcc, int mnc, int lac, int cid, int psc) { mMcc = mcc; mMnc = mnc; mLac = lac; @@ -57,16 +70,7 @@ public final class GsmCellIdentity extends CellIdentity implements Parcelable { mPsc = psc; } - private GsmCellIdentity(Parcel in) { - super(in); - mMcc = in.readInt(); - mMnc = in.readInt(); - mLac = in.readInt(); - mCid = in.readInt(); - mPsc = in.readInt(); - } - - GsmCellIdentity(GsmCellIdentity cid) { + private CellIdentityGsm(CellIdentityGsm cid) { super(cid); mMcc = cid.mMcc; mMnc = cid.mMnc; @@ -75,6 +79,11 @@ public final class GsmCellIdentity extends CellIdentity implements Parcelable { mPsc = cid.mPsc; } + @Override + CellIdentityGsm copy() { + return new CellIdentityGsm(this); + } + /** * @return 3-digit Mobile Country Code, 0..999 */ @@ -115,15 +124,55 @@ public final class GsmCellIdentity extends CellIdentity implements Parcelable { return mPsc; } - /** Implement the Parcelable interface {@hide} */ + @Override + public int hashCode() { + int primeNum = 31; + return (mMcc * primeNum) + (mMnc * primeNum) + (mLac * primeNum) + (mCid * primeNum) + + (mPsc * primeNum); + } + + @Override + public boolean equals(Object other) { + if (super.equals(other)) { + try { + CellIdentityGsm o = (CellIdentityGsm)other; + return mMcc == o.mMcc && + mMnc == o.mMnc && + mLac == o.mLac && + mCid == o.mCid && + mPsc == o.mPsc; + } catch (ClassCastException e) { + return false; + } + } else { + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("GsmCellIdentitiy:"); + sb.append(super.toString()); + sb.append(" mMcc=").append(mMcc); + sb.append(" mMnc=").append(mMcc); + sb.append(" mLac=").append(mLac); + sb.append(" mCid=").append(mCid); + sb.append(" mPsc=").append(mPsc); + + return sb.toString(); + } + + /** Implement the Parcelable interface */ @Override public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(TYPE_GSM); super.writeToParcel(dest, flags); dest.writeInt(mMcc); dest.writeInt(mMnc); @@ -132,17 +181,42 @@ public final class GsmCellIdentity extends CellIdentity implements Parcelable { dest.writeInt(mPsc); } - /** Implement the Parcelable interface {@hide} */ - public static final Creator<GsmCellIdentity> CREATOR = - new Creator<GsmCellIdentity>() { + /** Construct from Parcel, type has already been processed */ + private CellIdentityGsm(Parcel in) { + super(in); + mMcc = in.readInt(); + mMnc = in.readInt(); + mLac = in.readInt(); + mCid = in.readInt(); + mPsc = in.readInt(); + if (DBG) log("CellIdentityGsm(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + @SuppressWarnings("hiding") + public static final Creator<CellIdentityGsm> CREATOR = + new Creator<CellIdentityGsm>() { @Override - public GsmCellIdentity createFromParcel(Parcel in) { - return new GsmCellIdentity(in); + public CellIdentityGsm createFromParcel(Parcel in) { + in.readInt(); // Skip past token, we know what it is + return createFromParcelBody(in); } @Override - public GsmCellIdentity[] newArray(int size) { - return new GsmCellIdentity[size]; + public CellIdentityGsm[] newArray(int size) { + return new CellIdentityGsm[size]; } }; + + /** @hide */ + static CellIdentityGsm createFromParcelBody(Parcel in) { + return new CellIdentityGsm(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } } diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java new file mode 100644 index 000000000000..3d8532d15b71 --- /dev/null +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2012 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.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * CellIdentity is to represent a unique LTE cell + * + * @hide + */ +public final class CellIdentityLte extends CellIdentity implements Parcelable { + + private static final String LOG_TAG = "CellIdentityLte"; + private static final boolean DBG = false; + + // 3-digit Mobile Country Code, 0..999 + private final int mMcc; + // 2 or 3-digit Mobile Network Code, 0..999 + private final int mMnc; + // 28-bit cell identity + private final int mCi; + // physical cell id 0..503 + private final int mPci; + // 16-bit tracking area code + private final int mTac; + + /** + * @hide + */ + public CellIdentityLte() { + mMcc = Integer.MAX_VALUE; + mMnc = Integer.MAX_VALUE; + mCi = Integer.MAX_VALUE; + mPci = Integer.MAX_VALUE; + mTac = Integer.MAX_VALUE; + } + + /** + * + * @param mcc 3-digit Mobile Country Code, 0..999 + * @param mnc 2 or 3-digit Mobile Network Code, 0..999 + * @param ci 28-bit Cell Identity + * @param pci Physical Cell Id 0..503 + * @param tac 16-bit Tracking Area Code + * + * @hide + */ + public CellIdentityLte (int mcc, int mnc, int ci, int pci, int tac) { + mMcc = mcc; + mMnc = mnc; + mCi = ci; + mPci = pci; + mTac = tac; + } + + private CellIdentityLte(CellIdentityLte cid) { + super(cid); + mMcc = cid.mMcc; + mMnc = cid.mMnc; + mCi = cid.mCi; + mPci = cid.mPci; + mTac = cid.mTac; + } + + @Override + CellIdentityLte copy() { + return new CellIdentityLte(this); + } + + /** + * @return 3-digit Mobile Country Code, 0..999 + */ + public int getMcc() { + return mMcc; + } + + /** + * @return 2 or 3-digit Mobile Network Code, 0..999 + */ + public int getMnc() { + return mMnc; + } + + /** + * @return 28-bit Cell Identity + */ + public int getCi() { + return mCi; + } + + /** + * @return Physical Cell Id 0..503 + */ + public int getPci() { + return mPci; + } + + /** + * @return 16-bit Tracking Area Code + */ + public int getTac() { + return mTac; + } + + @Override + public int hashCode() { + int primeNum = 31; + return (mMcc * primeNum) + (mMnc * primeNum) + (mCi * primeNum) + (mPci * primeNum) + + (mTac * primeNum); + } + + @Override + public boolean equals(Object other) { + if (super.equals(other)) { + try { + CellIdentityLte o = (CellIdentityLte)other; + return mMcc == o.mMcc && + mMnc == o.mMnc && + mCi == o.mCi && + mPci == o.mCi && + mTac == o.mTac; + } catch (ClassCastException e) { + return false; + } + } else { + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("LteCellIdentitiy:"); + sb.append(super.toString()); + sb.append(" mMcc="); sb.append(mMcc); + sb.append(" mMnc="); sb.append(mMnc); + sb.append(" mCi="); sb.append(mCi); + sb.append(" mPci="); sb.append(mPci); + sb.append(" mTac="); sb.append(mTac); + + return sb.toString(); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(TYPE_LTE); + super.writeToParcel(dest, flags); + dest.writeInt(mMcc); + dest.writeInt(mMnc); + dest.writeInt(mCi); + dest.writeInt(mPci); + dest.writeInt(mTac); + } + + /** Construct from Parcel, type has already been processed */ + private CellIdentityLte(Parcel in) { + super(in); + mMcc = in.readInt(); + mMnc = in.readInt(); + mCi = in.readInt(); + mPci = in.readInt(); + mTac = in.readInt(); + if (DBG) log("CellIdentityLte(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + @SuppressWarnings("hiding") + public static final Creator<CellIdentityLte> CREATOR = + new Creator<CellIdentityLte>() { + @Override + public CellIdentityLte createFromParcel(Parcel in) { + in.readInt(); // Skip past token, we know what it is + return createFromParcelBody(in); + } + + @Override + public CellIdentityLte[] newArray(int size) { + return new CellIdentityLte[size]; + } + }; + + /** @hide */ + static CellIdentityLte createFromParcelBody(Parcel in) { + return new CellIdentityLte(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index 9bea30c2d70d..5fdf7c0bb7c5 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2012 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. @@ -20,194 +20,171 @@ import android.os.Parcel; import android.os.Parcelable; /** - * Represent one snapshot observation of one cell info - * which contains the time of observation. + * Immutable cell information from a point in time. * - * @hide Pending API review + * @hide */ -public final class CellInfo implements Parcelable { - // Type to distinguish where time stamp gets recorded. - public static final int CELL_INFO_TIMESTAMP_TYPE_UNKNOWN = 0; - public static final int CELL_INFO_TIMESTAMP_TYPE_ANTENNA = 1; - public static final int CELL_INFO_TIMESTAMP_TYPE_MODEM = 2; - public static final int CELL_INFO_TIMESTAMP_TYPE_OEM_RIL = 3; - public static final int CELL_INFO_TIMESTAMP_TYPE_JAVA_RIL = 4; +public class CellInfo implements Parcelable { - // Observation time stamped as type in nanoseconds since boot - private final long mTimeStamp; - // Where time stamp gets recorded. - // Value of CELL_INFO_TIMESTAMP_TYPE_XXXX - private final int mTimeStampType; + // Type fields for parceling + protected static final int TYPE_GSM = 1; + protected static final int TYPE_CDMA = 2; + protected static final int TYPE_LTE = 3; - private final boolean mRegistered; + // Type to distinguish where time stamp gets recorded. - private final SignalStrength mStrength; - private final long mTimingAdvance; + /** @hide */ + public static final int TIMESTAMP_TYPE_UNKNOWN = 0; + /** @hide */ + public static final int TIMESTAMP_TYPE_ANTENNA = 1; + /** @hide */ + public static final int TIMESTAMP_TYPE_MODEM = 2; + /** @hide */ + public static final int TIMESTAMP_TYPE_OEM_RIL = 3; + /** @hide */ + public static final int TIMESTAMP_TYPE_JAVA_RIL = 4; - private final int mCellIdentityType; - private final CellIdentity mCellIdentity; + // True if device is mRegistered to the mobile network + private boolean mRegistered; - /** - * Public constructor - * @param timeStampType is one of CELL_INFO_TIMESTAMP_TYPE_XXXX - * @param timeStamp is observation time in nanoseconds since boot - * @param timingAdv is observed timing advance - * @param registered is true when register to this cellIdentity - * @param strength is observed signal strength - * @param cellIdentity is observed mobile cell - */ - public CellInfo(int timeStampType, long timeStamp, long timingAdv, - boolean registered, SignalStrength strength, - CellIdentity cellIdentity) { - - if (timeStampType < CELL_INFO_TIMESTAMP_TYPE_UNKNOWN || - timeStampType > CELL_INFO_TIMESTAMP_TYPE_JAVA_RIL) { - mTimeStampType = CELL_INFO_TIMESTAMP_TYPE_UNKNOWN; - } else { - mTimeStampType = timeStampType; - } + // Observation time stamped as type in nanoseconds since boot + private long mTimeStamp; - mRegistered = registered; - mTimeStamp = timeStamp; - mTimingAdvance = timingAdv; - mStrength = new SignalStrength(strength); + // Where time stamp gets recorded. + // Value of TIMESTAMP_TYPE_XXXX + private int mTimeStampType; - mCellIdentityType = cellIdentity.getCellIdType(); - // TODO: make defense copy - mCellIdentity = cellIdentity; + protected CellInfo() { + this.mRegistered = false; + this.mTimeStampType = TIMESTAMP_TYPE_UNKNOWN; + this.mTimeStamp = Long.MAX_VALUE; } - public CellInfo(CellInfo ci) { - this.mTimeStampType = ci.mTimeStampType; + protected CellInfo(CellInfo ci) { this.mRegistered = ci.mRegistered; + this.mTimeStampType = ci.mTimeStampType; this.mTimeStamp = ci.mTimeStamp; - this.mTimingAdvance = ci.mTimingAdvance; - this.mCellIdentityType = ci.mCellIdentityType; - this.mStrength = new SignalStrength(ci.mStrength); - switch(mCellIdentityType) { - case CellIdentity.CELLID_TYPE_GSM: - mCellIdentity = new GsmCellIdentity((GsmCellIdentity)ci.mCellIdentity); - break; - default: - mCellIdentity = null; - } } - private CellInfo(Parcel in) { - mTimeStampType = in.readInt(); - mRegistered = (in.readInt() == 1) ? true : false; - mTimeStamp = in.readLong(); - mTimingAdvance = in.readLong(); - mCellIdentityType = in.readInt(); - mStrength = SignalStrength.CREATOR.createFromParcel(in); - switch(mCellIdentityType) { - case CellIdentity.CELLID_TYPE_GSM: - mCellIdentity = GsmCellIdentity.CREATOR.createFromParcel(in); - break; - default: - mCellIdentity = null; - } + /** True if this cell is registered to the mobile network */ + public boolean isRegistered() { + return mRegistered; + } + /** @hide */ + public void setRegisterd(boolean registered) { + mRegistered = registered; } - /** - * @return the observation time in nanoseconds since boot - */ + /** Approximate time of this cell information in nanos since boot */ public long getTimeStamp() { return mTimeStamp; } + /** @hide */ + public void setTimeStamp(long timeStamp) { + mTimeStamp = timeStamp; + } /** - * @return Where time stamp gets recorded. - * one of CELL_INFO_TIMESTAMP_TYPE_XXXX + * Where time stamp gets recorded. + * @return one of TIMESTAMP_TYPE_XXXX + * + * @hide */ public int getTimeStampType() { return mTimeStampType; } - - /** - * @return true when register to this cellIdentity - */ - public boolean isRegistered() { - return mRegistered; - } - - /** - * @return observed timing advance - */ - public long getTimingAdvance() { - return mTimingAdvance; - } - - /** - * @return observed signal strength - */ - public SignalStrength getSignalStrength() { - // make a defense copy - return new SignalStrength(mStrength); + /** @hide */ + public void setTimeStampType(int timeStampType) { + if (timeStampType < TIMESTAMP_TYPE_UNKNOWN || timeStampType > TIMESTAMP_TYPE_JAVA_RIL) { + mTimeStampType = TIMESTAMP_TYPE_UNKNOWN; + } else { + mTimeStampType = timeStampType; + } } - /** - * @return observed cell identity - */ - public CellIdentity getCellIdentity() { - // TODO: make a defense copy - return mCellIdentity; + @Override + public int hashCode() { + int primeNum = 31; + return ((mRegistered ? 0 : 1) * primeNum) + ((int)(mTimeStamp / 1000) * primeNum) + + (mTimeStampType * primeNum); } @Override - public String toString() { - StringBuffer sb = new StringBuffer(); + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (this == other) { + return true; + } + try { + CellInfo o = (CellInfo) other; + return mRegistered == o.mRegistered + && mTimeStamp == o.mTimeStamp && mTimeStampType == o.mTimeStampType; + } catch (ClassCastException e) { + return false; + } + } - sb.append("TimeStampType: "); - switch(mTimeStampType) { + private static String timeStampTypeToString(int type) { + switch (type) { case 1: - sb.append("antenna"); - break; + return "antenna"; case 2: - sb.append("modem"); - break; + return "modem"; case 3: - sb.append("oem_ril"); - break; + return "oem_ril"; case 4: - sb.append("java_ril"); - break; + return "java_ril"; default: - sb.append("unknown"); + return "unknown"; } - sb.append(", TimeStamp: ").append(mTimeStamp).append(" ns"); - sb.append(", Registered: ").append(mRegistered ? "YES" : "NO"); - sb.append(", TimingAdvance: ").append(mTimingAdvance); - sb.append(", Strength : " + mStrength); - sb.append(", Cell Iden: " + mCellIdentity); + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + String timeStampType; + + sb.append(" mRegistered=").append(mRegistered ? "YES" : "NO"); + timeStampType = timeStampTypeToString(mTimeStampType); + sb.append(" mTimeStampType=").append(timeStampType); + sb.append(" mTimeStamp=").append(mTimeStamp).append("ns"); return sb.toString(); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ @Override public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mTimeStampType); dest.writeInt(mRegistered ? 1 : 0); + dest.writeInt(mTimeStampType); dest.writeLong(mTimeStamp); - dest.writeLong(mTimingAdvance); - dest.writeInt(mCellIdentityType); - mStrength.writeToParcel(dest, flags); - mCellIdentity.writeToParcel(dest, flags); } - /** Implement the Parcelable interface {@hide} */ - public static final Creator<CellInfo> CREATOR = - new Creator<CellInfo>() { + protected CellInfo(Parcel in) { + mRegistered = (in.readInt() == 1) ? true : false; + mTimeStampType = in.readInt(); + mTimeStamp = in.readLong(); + } + + /** Implement the Parcelable interface */ + public static final Creator<CellInfo> CREATOR = new Creator<CellInfo>() { @Override public CellInfo createFromParcel(Parcel in) { - return new CellInfo(in); + int type = in.readInt(); + switch (type) { + case TYPE_GSM: return CellInfoGsm.createFromParcelBody(in); + case TYPE_CDMA: return CellInfoCdma.createFromParcelBody(in); + case TYPE_LTE: return CellInfoLte.createFromParcelBody(in); + default: throw new RuntimeException("Bad CellInfo Parcel"); + } } @Override diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java new file mode 100644 index 000000000000..84c1560b769e --- /dev/null +++ b/telephony/java/android/telephony/CellInfoCdma.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2012 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.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * Immutable cell information from a point in time. + * + * @hide + */ +public final class CellInfoCdma extends CellInfo implements Parcelable { + + private static final String LOG_TAG = "CellInfoCdma"; + private static final boolean DBG = false; + + private CellIdentityCdma mCellIdentityCdma; + private CellSignalStrengthCdma mCellSignalStrengthCdma; + + /** @hide */ + public CellInfoCdma() { + super(); + mCellIdentityCdma = new CellIdentityCdma(); + mCellSignalStrengthCdma = new CellSignalStrengthCdma(); + } + + /** @hide */ + public CellInfoCdma(CellInfoCdma ci) { + super(ci); + this.mCellIdentityCdma = ci.mCellIdentityCdma.copy(); + this.mCellSignalStrengthCdma = ci.mCellSignalStrengthCdma.copy(); + } + + public CellIdentityCdma getCellIdentity() { + return mCellIdentityCdma; + } + /** @hide */ + public void setCellIdentity(CellIdentityCdma cid) { + mCellIdentityCdma = cid; + } + + public CellSignalStrengthCdma getCellSignalStrength() { + return mCellSignalStrengthCdma; + } + /** @hide */ + public void setCellSignalStrength(CellSignalStrengthCdma css) { + mCellSignalStrengthCdma = css; + } + + /** + * @return hash code + */ + @Override + public int hashCode() { + return super.hashCode() + mCellIdentityCdma.hashCode() + mCellSignalStrengthCdma.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (!super.equals(other)) { + return false; + } + try { + CellInfoCdma o = (CellInfoCdma) other; + return mCellIdentityCdma.equals(o.mCellIdentityCdma) + && mCellSignalStrengthCdma.equals(o.mCellSignalStrengthCdma); + } catch (ClassCastException e) { + return false; + } + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("CellInfoCdma:"); + sb.append(super.toString()); + sb.append(", ").append(mCellIdentityCdma); + sb.append(", ").append(mCellSignalStrengthCdma); + + return sb.toString(); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(TYPE_LTE); + super.writeToParcel(dest, flags); + mCellIdentityCdma.writeToParcel(dest, flags); + mCellSignalStrengthCdma.writeToParcel(dest, flags); + } + + /** + * Construct a CellInfoCdma object from the given parcel + * where the token is already been processed. + */ + private CellInfoCdma(Parcel in) { + super(in); + mCellIdentityCdma = CellIdentityCdma.CREATOR.createFromParcel(in); + mCellSignalStrengthCdma = CellSignalStrengthCdma.CREATOR.createFromParcel(in); + if (DBG) log("CellInfoCdma(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + public static final Creator<CellInfoCdma> CREATOR = new Creator<CellInfoCdma>() { + @Override + public CellInfoCdma createFromParcel(Parcel in) { + in.readInt(); // Skip past token, we know what it is + return createFromParcelBody(in); + } + + @Override + public CellInfoCdma[] newArray(int size) { + return new CellInfoCdma[size]; + } + }; + + /** @hide */ + protected static CellInfoCdma createFromParcelBody(Parcel in) { + return new CellInfoCdma(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java new file mode 100644 index 000000000000..f913569a159a --- /dev/null +++ b/telephony/java/android/telephony/CellInfoGsm.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2012 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.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * Immutable cell information from a point in time. + * + * @hide + */ +public final class CellInfoGsm extends CellInfo implements Parcelable { + + private static final String LOG_TAG = "CellInfoGsm"; + private static final boolean DBG = false; + + private CellIdentityGsm mCellIdentityGsm; + private CellSignalStrengthGsm mCellSignalStrengthGsm; + + /** @hide */ + public CellInfoGsm() { + super(); + mCellIdentityGsm = new CellIdentityGsm(); + mCellSignalStrengthGsm = new CellSignalStrengthGsm(); + } + + /** @hide */ + public CellInfoGsm(CellInfoGsm ci) { + super(ci); + this.mCellIdentityGsm = ci.mCellIdentityGsm.copy(); + this.mCellSignalStrengthGsm = ci.mCellSignalStrengthGsm.copy(); + } + + public CellIdentityGsm getCellIdentity() { + return mCellIdentityGsm; + } + /** @hide */ + public void setCellIdentity(CellIdentityGsm cid) { + mCellIdentityGsm = cid; + } + + public CellSignalStrengthGsm getCellSignalStrength() { + return mCellSignalStrengthGsm; + } + /** @hide */ + public void setCellSignalStrength(CellSignalStrengthGsm css) { + mCellSignalStrengthGsm = css; + } + + /** + * @return hash code + */ + @Override + public int hashCode() { + return super.hashCode() + mCellIdentityGsm.hashCode() + mCellSignalStrengthGsm.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (!super.equals(other)) { + return false; + } + try { + CellInfoGsm o = (CellInfoGsm) other; + return mCellIdentityGsm.equals(o.mCellIdentityGsm) + && mCellSignalStrengthGsm.equals(o.mCellSignalStrengthGsm); + } catch (ClassCastException e) { + return false; + } + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("CellInfoGsm:"); + sb.append(super.toString()); + sb.append(", ").append(mCellIdentityGsm); + sb.append(", ").append(mCellSignalStrengthGsm); + + return sb.toString(); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(TYPE_LTE); + super.writeToParcel(dest, flags); + mCellIdentityGsm.writeToParcel(dest, flags); + mCellSignalStrengthGsm.writeToParcel(dest, flags); + } + + /** + * Construct a CellInfoGsm object from the given parcel + * where the token is already been processed. + */ + private CellInfoGsm(Parcel in) { + super(in); + mCellIdentityGsm = CellIdentityGsm.CREATOR.createFromParcel(in); + mCellSignalStrengthGsm = CellSignalStrengthGsm.CREATOR.createFromParcel(in); + } + + /** Implement the Parcelable interface */ + public static final Creator<CellInfoGsm> CREATOR = new Creator<CellInfoGsm>() { + @Override + public CellInfoGsm createFromParcel(Parcel in) { + in.readInt(); // Skip past token, we know what it is + return createFromParcelBody(in); + } + + @Override + public CellInfoGsm[] newArray(int size) { + return new CellInfoGsm[size]; + } + }; + + /** @hide */ + protected static CellInfoGsm createFromParcelBody(Parcel in) { + return new CellInfoGsm(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java new file mode 100644 index 000000000000..57b040223a88 --- /dev/null +++ b/telephony/java/android/telephony/CellInfoLte.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2012 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.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * Immutable cell information from a point in time. + * + * @hide + */ +public final class CellInfoLte extends CellInfo implements Parcelable { + + private static final String LOG_TAG = "CellInfoLte"; + private static final boolean DBG = false; + + private CellIdentityLte mCellIdentityLte; + private CellSignalStrengthLte mCellSignalStrengthLte; + + /** @hide */ + public CellInfoLte() { + super(); + mCellIdentityLte = new CellIdentityLte(); + mCellSignalStrengthLte = new CellSignalStrengthLte(); + } + + /** @hide */ + public CellInfoLte(CellInfoLte ci) { + super(ci); + this.mCellIdentityLte = ci.mCellIdentityLte.copy(); + this.mCellSignalStrengthLte = ci.mCellSignalStrengthLte.copy(); + } + + public CellIdentityLte getCellIdentity() { + return mCellIdentityLte; + } + /** @hide */ + public void setCellIdentity(CellIdentityLte cid) { + mCellIdentityLte = cid; + } + + public CellSignalStrengthLte getCellSignalStrength() { + return mCellSignalStrengthLte; + } + /** @hide */ + public void setCellSignalStrength(CellSignalStrengthLte css) { + mCellSignalStrengthLte = css; + } + + /** + * @return hash code + */ + @Override + public int hashCode() { + return super.hashCode() + mCellIdentityLte.hashCode() + mCellSignalStrengthLte.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (!super.equals(other)) { + return false; + } + try { + CellInfoLte o = (CellInfoLte) other; + return mCellIdentityLte.equals(o.mCellIdentityLte) + && mCellSignalStrengthLte.equals(o.mCellSignalStrengthLte); + } catch (ClassCastException e) { + return false; + } + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("CellInfoLte:"); + sb.append(super.toString()); + sb.append(", ").append(mCellIdentityLte); + sb.append(", ").append(mCellSignalStrengthLte); + + return sb.toString(); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(TYPE_LTE); + super.writeToParcel(dest, flags); + mCellIdentityLte.writeToParcel(dest, flags); + mCellSignalStrengthLte.writeToParcel(dest, flags); + } + + /** + * Construct a CellInfoLte object from the given parcel + * where the TYPE_LTE token is already been processed. + */ + private CellInfoLte(Parcel in) { + super(in); + mCellIdentityLte = CellIdentityLte.CREATOR.createFromParcel(in); + mCellSignalStrengthLte = CellSignalStrengthLte.CREATOR.createFromParcel(in); + if (DBG) log("CellInfoLte(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + public static final Creator<CellInfoLte> CREATOR = new Creator<CellInfoLte>() { + @Override + public CellInfoLte createFromParcel(Parcel in) { + in.readInt(); // Skip past token, we know what it is + return createFromParcelBody(in); + } + + @Override + public CellInfoLte[] newArray(int size) { + return new CellInfoLte[size]; + } + }; + + /** @hide */ + protected static CellInfoLte createFromParcelBody(Parcel in) { + return new CellInfoLte(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java new file mode 100644 index 000000000000..4ed7dcfff08e --- /dev/null +++ b/telephony/java/android/telephony/CellSignalStrength.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2012 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.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.view.InputEvent; + +/** + * Abstract base class for cell phone signal strength related information. + * + * @hide + */ +public abstract class CellSignalStrength implements Parcelable { + + // Type fields for parceling + protected static final int TYPE_GSM = 1; + protected static final int TYPE_CDMA = 2; + protected static final int TYPE_LTE = 3; + + + /** @hide */ + public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; + /** @hide */ + public static final int SIGNAL_STRENGTH_POOR = 1; + /** @hide */ + public static final int SIGNAL_STRENGTH_MODERATE = 2; + /** @hide */ + public static final int SIGNAL_STRENGTH_GOOD = 3; + /** @hide */ + public static final int SIGNAL_STRENGTH_GREAT = 4; + /** @hide */ + public static final int NUM_SIGNAL_STRENGTH_BINS = 5; + /** @hide */ + public static final String[] SIGNAL_STRENGTH_NAMES = { + "none", "poor", "moderate", "good", "great" + }; + + /** @hide */ + public abstract void setDefaultValues(); + + /** + * Get signal level as an int from 0..4 + * + * @hide + */ + public abstract int getLevel(); + + /** + * Get the signal level as an asu value between 0..31, 99 is unknown + * + * @hide + */ + public abstract int getAsuLevel(); + + /** + * Get the signal strength as dBm + * + * @hide + */ + public abstract int getDbm(); + + /** + * Copies the CellSignalStrength. + * + * @return A deep copy of this class. + * @hide + */ + public abstract CellSignalStrength copy(); + + @Override + public abstract int hashCode(); + + @Override + public abstract boolean equals (Object o); + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public abstract void writeToParcel(Parcel dest, int flags); + + /** Implement the Parcelable interface */ + public static final Creator<CellSignalStrength> CREATOR = + new Creator<CellSignalStrength>() { + @Override + public CellSignalStrength createFromParcel(Parcel in) { + int type = in.readInt(); + switch (type) { + case TYPE_GSM: return CellSignalStrengthGsm.createFromParcelBody(in); + case TYPE_CDMA: return CellSignalStrengthCdma.createFromParcelBody(in); + case TYPE_LTE: return CellSignalStrengthLte.createFromParcelBody(in); + default: throw new RuntimeException("Bad CellSignalStrength Parcel"); + } + } + + @Override + public CellSignalStrength[] newArray(int size) { + return new CellSignalStrength[size]; + } + }; +} diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java new file mode 100644 index 000000000000..ee50fad02fba --- /dev/null +++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2012 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.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * LTE signal strength related information. + * + * @hide + */ +public class CellSignalStrengthCdma extends CellSignalStrength implements Parcelable { + + private static final String LOG_TAG = "CellSignalStrengthCdma"; + private static final boolean DBG = false; + + private int mCdmaDbm; // This value is the RSSI value + private int mCdmaEcio; // This value is the Ec/Io + private int mEvdoDbm; // This value is the EVDO RSSI value + private int mEvdoEcio; // This value is the EVDO Ec/Io + private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio + + /** + * Empty constructor + * + * @hide + */ + public CellSignalStrengthCdma() { + setDefaultValues(); + } + + /** + * Constructor + * + * @hide + */ + public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, + int evdoSnr) { + initialize(cdmaDbm, cdmaEcio, evdoDbm, evdoEcio, evdoSnr); + } + + /** + * Copy constructors + * + * @param s Source SignalStrength + * + * @hide + */ + public CellSignalStrengthCdma(CellSignalStrengthCdma s) { + copyFrom(s); + } + + /** + * Initialize all the values + * + * @param cdmaDbm + * @param cdmaEcio + * @param evdoDbm + * @param evdoEcio + * @param evdoSnr + * + * @hide + */ + public void initialize(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr) { + mCdmaDbm = cdmaDbm; + mCdmaEcio = cdmaEcio; + mEvdoDbm = evdoDbm; + mEvdoEcio = evdoEcio; + mEvdoSnr = evdoSnr; + } + + /** + * @hide + */ + protected void copyFrom(CellSignalStrengthCdma s) { + mCdmaDbm = s.mCdmaDbm; + mCdmaEcio = s.mCdmaEcio; + mEvdoDbm = s.mEvdoDbm; + mEvdoEcio = s.mEvdoEcio; + mEvdoSnr = s.mEvdoSnr; + } + + /** + * @hide + */ + @Override + public CellSignalStrengthCdma copy() { + return new CellSignalStrengthCdma(this); + } + + /** @hide */ + @Override + public void setDefaultValues() { + mCdmaDbm = Integer.MAX_VALUE; + mCdmaEcio = Integer.MAX_VALUE; + mEvdoDbm = Integer.MAX_VALUE; + mEvdoEcio = Integer.MAX_VALUE; + mEvdoSnr = Integer.MAX_VALUE; + } + + /** + * Get LTE as level 0..4 + * + * @hide + */ + @Override + public int getLevel() { + int level; + + int cdmaLevel = getCdmaLevel(); + int evdoLevel = getEvdoLevel(); + if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { + /* We don't know evdo, use cdma */ + level = getCdmaLevel(); + } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { + /* We don't know cdma, use evdo */ + level = getEvdoLevel(); + } else { + /* We know both, use the lowest level */ + level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; + } + if (DBG) log("getLevel=" + level); + return level; + } + + /** + * Get the LTE signal level as an asu value between 0..97, 99 is unknown + * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * + * @hide + */ + @Override + public int getAsuLevel() { + final int cdmaDbm = getCdmaDbm(); + final int cdmaEcio = getCdmaEcio(); + int cdmaAsuLevel; + int ecioAsuLevel; + + if (cdmaDbm >= -75) cdmaAsuLevel = 16; + else if (cdmaDbm >= -82) cdmaAsuLevel = 8; + else if (cdmaDbm >= -90) cdmaAsuLevel = 4; + else if (cdmaDbm >= -95) cdmaAsuLevel = 2; + else if (cdmaDbm >= -100) cdmaAsuLevel = 1; + else cdmaAsuLevel = 99; + + // Ec/Io are in dB*10 + if (cdmaEcio >= -90) ecioAsuLevel = 16; + else if (cdmaEcio >= -100) ecioAsuLevel = 8; + else if (cdmaEcio >= -115) ecioAsuLevel = 4; + else if (cdmaEcio >= -130) ecioAsuLevel = 2; + else if (cdmaEcio >= -150) ecioAsuLevel = 1; + else ecioAsuLevel = 99; + + int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel; + if (DBG) log("getAsuLevel=" + level); + return level; + } + + /** + * Get cdma as level 0..4 + * + * @hide + */ + public int getCdmaLevel() { + final int cdmaDbm = getCdmaDbm(); + final int cdmaEcio = getCdmaEcio(); + int levelDbm; + int levelEcio; + + if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT; + else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD; + else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE; + else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR; + else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + + // Ec/Io are in dB*10 + if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT; + else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD; + else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE; + else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR; + else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + + int level = (levelDbm < levelEcio) ? levelDbm : levelEcio; + if (DBG) log("getCdmaLevel=" + level); + return level; + } + + /** + * Get Evdo as level 0..4 + * + * @hide + */ + public int getEvdoLevel() { + int evdoDbm = getEvdoDbm(); + int evdoSnr = getEvdoSnr(); + int levelEvdoDbm; + int levelEvdoSnr; + + if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT; + else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD; + else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE; + else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR; + else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + + if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT; + else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD; + else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE; + else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR; + else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + + int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; + if (DBG) log("getEvdoLevel=" + level); + return level; + } + + /** + * Get as dBm + * + * @hide + */ + @Override + public int getDbm() { + int cdmaDbm = getCdmaDbm(); + int evdoDbm = getEvdoDbm(); + + // Use the lower value to be conservative + return (cdmaDbm < evdoDbm) ? cdmaDbm : evdoDbm; + } + + /** + * Get the CDMA RSSI value in dBm + */ + public int getCdmaDbm() { + return mCdmaDbm; + } + /** @hide */ + public void setCdmaDbm(int cdmaDbm) { + mCdmaDbm = cdmaDbm; + } + + /** + * Get the CDMA Ec/Io value in dB*10 + */ + public int getCdmaEcio() { + return mCdmaEcio; + } + /** @hide */ + public void setCdmaEcio(int cdmaEcio) { + mCdmaEcio = cdmaEcio; + } + + /** + * Get the EVDO RSSI value in dBm + */ + public int getEvdoDbm() { + return mEvdoDbm; + } + /** @hide */ + public void setEvdoDbm(int evdoDbm) { + mEvdoDbm = evdoDbm; + } + + /** + * Get the EVDO Ec/Io value in dB*10 + */ + public int getEvdoEcio() { + return mEvdoEcio; + } + /** @hide */ + public void setEvdoEcio(int evdoEcio) { + mEvdoEcio = evdoEcio; + } + + /** + * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest. + */ + public int getEvdoSnr() { + return mEvdoSnr; + } + /** @hide */ + public void setEvdoSnr(int evdoSnr) { + mEvdoSnr = evdoSnr; + } + + @Override + public int hashCode() { + int primeNum = 31; + return ((mCdmaDbm * primeNum) + (mCdmaEcio * primeNum) + + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)); + } + + @Override + public boolean equals (Object o) { + CellSignalStrengthCdma s; + + try { + s = (CellSignalStrengthCdma) o; + } catch (ClassCastException ex) { + return false; + } + + if (o == null) { + return false; + } + + return mCdmaDbm == s.mCdmaDbm + && mCdmaEcio == s.mCdmaEcio + && mEvdoDbm == s.mEvdoDbm + && mEvdoEcio == s.mEvdoEcio + && mEvdoSnr == s.mEvdoSnr; + } + + /** + * @return string representation. + */ + @Override + public String toString() { + return "CellSignalStrengthCdma:" + + " cdmaDbm=" + mCdmaDbm + + " cdmaEcio=" + mCdmaEcio + + " evdoDbm=" + mEvdoDbm + + " evdoEcio=" + mEvdoEcio + + " evdoSnr=" + mEvdoSnr; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(CellSignalStrength.TYPE_CDMA); + dest.writeInt(mCdmaDbm); + dest.writeInt(mCdmaEcio); + dest.writeInt(mEvdoDbm); + dest.writeInt(mEvdoEcio); + dest.writeInt(mEvdoSnr); + } + + /** + * Construct a SignalStrength object from the given parcel + * where the TYPE_LTE token is already been processed. + */ + private CellSignalStrengthCdma(Parcel in) { + mCdmaDbm = in.readInt(); + mCdmaEcio = in.readInt(); + mEvdoDbm = in.readInt(); + mEvdoEcio = in.readInt(); + mEvdoSnr = in.readInt(); + if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @SuppressWarnings("hiding") + public static final Parcelable.Creator<CellSignalStrengthCdma> CREATOR = + new Parcelable.Creator<CellSignalStrengthCdma>() { + @Override + public CellSignalStrengthCdma createFromParcel(Parcel in) { + if (in.readInt() != CellSignalStrength.TYPE_CDMA) { + throw new RuntimeException("Expecting TYPE_CDMA"); + } + return createFromParcelBody(in); + } + + @Override + public CellSignalStrengthCdma[] newArray(int size) { + return new CellSignalStrengthCdma[size]; + } + }; + + /** @hide */ + public static CellSignalStrengthCdma createFromParcelBody(Parcel in) { + return new CellSignalStrengthCdma(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java new file mode 100644 index 000000000000..70876fb44482 --- /dev/null +++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2012 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.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * LTE signal strength related information. + * + * @hide + */ +public class CellSignalStrengthGsm extends CellSignalStrength implements Parcelable { + + private static final String LOG_TAG = "CellSignalStrengthGsm"; + private static final boolean DBG = false; + + private static final int GSM_SIGNAL_STRENGTH_GREAT = 12; + private static final int GSM_SIGNAL_STRENGTH_GOOD = 8; + private static final int GSM_SIGNAL_STRENGTH_MODERATE = 8; + + private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 + private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 + + /** + * Empty constructor + * + * @hide + */ + public CellSignalStrengthGsm() { + setDefaultValues(); + } + + /** + * Constructor + * + * @hide + */ + public CellSignalStrengthGsm(int ss, int ber) { + initialize(ss, ber); + } + + /** + * Copy constructors + * + * @param s Source SignalStrength + * + * @hide + */ + public CellSignalStrengthGsm(CellSignalStrengthGsm s) { + copyFrom(s); + } + + /** + * Initialize all the values + * + * @param SignalStrength + * + * @hide + */ + public void initialize(int ss, int ber) { + mSignalStrength = ss; + mBitErrorRate = ber; + } + + /** + * @hide + */ + protected void copyFrom(CellSignalStrengthGsm s) { + mSignalStrength = s.mSignalStrength; + mBitErrorRate = s.mBitErrorRate; + } + + /** + * @hide + */ + @Override + public CellSignalStrengthGsm copy() { + return new CellSignalStrengthGsm(this); + } + + /** @hide */ + @Override + public void setDefaultValues() { + mSignalStrength = Integer.MAX_VALUE; + mBitErrorRate = Integer.MAX_VALUE; + } + + /** + * Get LTE as level 0..4 + * + * @hide + */ + @Override + public int getLevel() { + int level; + + // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 + // asu = 0 (-113dB or less) is very weak + // signal, its better to show 0 bars to the user in such cases. + // asu = 99 is a special case, where the signal strength is unknown. + int asu = mSignalStrength; + if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + else if (asu >= GSM_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT; + else if (asu >= GSM_SIGNAL_STRENGTH_GOOD) level = SIGNAL_STRENGTH_GOOD; + else if (asu >= GSM_SIGNAL_STRENGTH_MODERATE) level = SIGNAL_STRENGTH_MODERATE; + else level = SIGNAL_STRENGTH_POOR; + if (DBG) log("getLevel=" + level); + return level; + } + + /** + * Get LTE as dBm + * + * @hide + */ + @Override + public int getDbm() { + int dBm; + + int level = mSignalStrength; + int asu = (level == 99 ? Integer.MAX_VALUE : level); + if (asu != Integer.MAX_VALUE) { + dBm = -113 + (2 * asu); + } else { + dBm = Integer.MAX_VALUE; + } + if (DBG) log("getDbm=" + dBm); + return dBm; + } + + /** + * Get the LTE signal level as an asu value between 0..97, 99 is unknown + * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * + * @hide + */ + @Override + public int getAsuLevel() { + // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 + // asu = 0 (-113dB or less) is very weak + // signal, its better to show 0 bars to the user in such cases. + // asu = 99 is a special case, where the signal strength is unknown. + int level = mSignalStrength; + if (DBG) log("getAsuLevel=" + level); + return level; + } + + @Override + public int hashCode() { + int primeNum = 31; + return (mSignalStrength * primeNum) + (mBitErrorRate * primeNum); + } + + @Override + public boolean equals (Object o) { + CellSignalStrengthGsm s; + + try { + s = (CellSignalStrengthGsm) o; + } catch (ClassCastException ex) { + return false; + } + + if (o == null) { + return false; + } + + return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate; + } + + /** + * @return string representation. + */ + @Override + public String toString() { + return "CellSignalStrengthGsm:" + + " ss=" + mSignalStrength + + " ber=" + mBitErrorRate; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(CellSignalStrength.TYPE_GSM); + dest.writeInt(mSignalStrength); + dest.writeInt(mBitErrorRate); + } + + /** + * Construct a SignalStrength object from the given parcel + * where the token is already been processed. + */ + private CellSignalStrengthGsm(Parcel in) { + mSignalStrength = in.readInt(); + mBitErrorRate = in.readInt(); + if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @SuppressWarnings("hiding") + public static final Parcelable.Creator<CellSignalStrengthGsm> CREATOR = + new Parcelable.Creator<CellSignalStrengthGsm>() { + @Override + public CellSignalStrengthGsm createFromParcel(Parcel in) { + if (in.readInt() != CellSignalStrength.TYPE_GSM) { + throw new RuntimeException("Expecting TYPE_GSM"); + } + return createFromParcelBody(in); + } + + @Override + public CellSignalStrengthGsm[] newArray(int size) { + return new CellSignalStrengthGsm[size]; + } + }; + + /** @hide */ + public static CellSignalStrengthGsm createFromParcelBody(Parcel in) { + return new CellSignalStrengthGsm(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java new file mode 100644 index 000000000000..3caea3db9fbd --- /dev/null +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2012 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.telephony; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +/** + * LTE signal strength related information. + * + * @hide + */ +public class CellSignalStrengthLte extends CellSignalStrength implements Parcelable { + + private static final String LOG_TAG = "CellSignalStrengthLte"; + private static final boolean DBG = false; + + private int mSignalStrength; + private int mRsrp; + private int mRsrq; + private int mRssnr; + private int mCqi; + private int mTimingAdvance; + + /** + * Empty constructor + * + * @hide + */ + public CellSignalStrengthLte() { + setDefaultValues(); + } + + /** + * Constructor + * + * @hide + */ + public CellSignalStrengthLte(int signalStrength, int rsrp, int rsrq, int rssnr, int cqi, + int timingAdvance) { + initialize(signalStrength, rsrp, rsrq, rssnr, cqi, timingAdvance); + } + + /** + * Copy constructors + * + * @param s Source SignalStrength + * + * @hide + */ + public CellSignalStrengthLte(CellSignalStrengthLte s) { + copyFrom(s); + } + + /** + * Initialize all the values + * + * @param lteSignalStrength + * @param rsrp + * @param rsrq + * @param rssnr + * @param cqi + * + * @hide + */ + public void initialize(int lteSignalStrength, int rsrp, int rsrq, int rssnr, int cqi, + int timingAdvance) { + mSignalStrength = lteSignalStrength; + mRsrp = rsrp; + mRsrq = rsrq; + mRssnr = rssnr; + mCqi = cqi; + mTimingAdvance = timingAdvance; + } + + /** + * @hide + */ + protected void copyFrom(CellSignalStrengthLte s) { + mSignalStrength = s.mSignalStrength; + mRsrp = s.mRsrp; + mRsrq = s.mRsrq; + mRssnr = s.mRssnr; + mCqi = s.mCqi; + mTimingAdvance = s.mTimingAdvance; + } + + /** + * @hide + */ + @Override + public CellSignalStrengthLte copy() { + return new CellSignalStrengthLte(this); + } + + /** @hide */ + @Override + public void setDefaultValues() { + mSignalStrength = Integer.MAX_VALUE; + mRsrp = Integer.MAX_VALUE; + mRsrq = Integer.MAX_VALUE; + mRssnr = Integer.MAX_VALUE; + mCqi = Integer.MAX_VALUE; + mTimingAdvance = Integer.MAX_VALUE; + } + + /** + * Get LTE as level 0..4 + * + * @hide + */ + @Override + public int getLevel() { + int levelRsrp = 0; + int levelRssnr = 0; + + if (mRsrp == Integer.MAX_VALUE) levelRsrp = 0; + else if (mRsrp >= -95) levelRsrp = SIGNAL_STRENGTH_GREAT; + else if (mRsrp >= -105) levelRsrp = SIGNAL_STRENGTH_GOOD; + else if (mRsrp >= -115) levelRsrp = SIGNAL_STRENGTH_MODERATE; + else levelRsrp = SIGNAL_STRENGTH_POOR; + + // See RIL_LTE_SignalStrength in ril.h + if (mRssnr == Integer.MAX_VALUE) levelRssnr = 0; + else if (mRssnr >= 45) levelRssnr = SIGNAL_STRENGTH_GREAT; + else if (mRssnr >= 10) levelRssnr = SIGNAL_STRENGTH_GOOD; + else if (mRssnr >= -30) levelRssnr = SIGNAL_STRENGTH_MODERATE; + else levelRssnr = SIGNAL_STRENGTH_POOR; + + int level; + if (mRsrp == Integer.MAX_VALUE) + level = levelRssnr; + else if (mRssnr == Integer.MAX_VALUE) + level = levelRsrp; + else + level = (levelRssnr < levelRsrp) ? levelRssnr : levelRsrp; + + if (DBG) log("Lte rsrp level: " + levelRsrp + + " snr level: " + levelRssnr + " level: " + level); + return level; + } + + /** + * Get LTE as dBm + * + * @hide + */ + @Override + public int getDbm() { + return mRsrp; + } + + /** + * Get the LTE signal level as an asu value between 0..97, 99 is unknown + * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 + * + * @hide + */ + @Override + public int getAsuLevel() { + int lteAsuLevel = 99; + int lteDbm = getDbm(); + if (lteDbm <= -140) lteAsuLevel = 0; + else if (lteDbm >= -43) lteAsuLevel = 97; + else lteAsuLevel = lteDbm + 140; + if (DBG) log("Lte Asu level: "+lteAsuLevel); + return lteAsuLevel; + } + + /** + * Get the timing advance value for LTE. + * See 3GPP xxxx + */ + public int getTimingAdvance() { + return mTimingAdvance; + } + + @Override + public int hashCode() { + int primeNum = 31; + return (mSignalStrength * primeNum) + (mRsrp * primeNum) + + (mRsrq * primeNum) + (mRssnr * primeNum) + (mCqi * primeNum) + + (mTimingAdvance * primeNum); + } + + @Override + public boolean equals (Object o) { + CellSignalStrengthLte s; + + try { + s = (CellSignalStrengthLte) o; + } catch (ClassCastException ex) { + return false; + } + + if (o == null) { + return false; + } + + return mSignalStrength == s.mSignalStrength + && mRsrp == s.mRsrp + && mRsrq == s.mRsrq + && mRssnr == s.mRssnr + && mCqi == s.mCqi + && mTimingAdvance == s.mTimingAdvance; + } + + /** + * @return string representation. + */ + @Override + public String toString() { + return "CellSignalStrengthLte:" + + " ss=" + mSignalStrength + + " rsrp=" + mRsrp + + " rsrq=" + mRsrq + + " rssnr=" + mRssnr + + " cqi=" + mCqi + + " ta=" + mTimingAdvance; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + if (DBG) log("writeToParcel(Parcel, int): " + toString()); + dest.writeInt(CellSignalStrength.TYPE_LTE); + dest.writeInt(mSignalStrength); + dest.writeInt(mRsrp); + dest.writeInt(mRsrq); + dest.writeInt(mRssnr); + dest.writeInt(mCqi); + dest.writeInt(mTimingAdvance); + } + + /** + * Construct a SignalStrength object from the given parcel + * where the token is already been processed. + */ + private CellSignalStrengthLte(Parcel in) { + mSignalStrength = in.readInt(); + mRsrp = in.readInt(); + mRsrq = in.readInt(); + mRssnr = in.readInt(); + mCqi = in.readInt(); + mTimingAdvance = in.readInt(); + if (DBG) log("CellSignalStrengthLte(Parcel): " + toString()); + } + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @SuppressWarnings("hiding") + public static final Parcelable.Creator<CellSignalStrengthLte> CREATOR = + new Parcelable.Creator<CellSignalStrengthLte>() { + @Override + public CellSignalStrengthLte createFromParcel(Parcel in) { + if (in.readInt() != CellSignalStrength.TYPE_LTE) { + throw new RuntimeException("Expecting TYPE_LTE"); + } + return createFromParcelBody(in); + } + + @Override + public CellSignalStrengthLte[] newArray(int size) { + return new CellSignalStrengthLte[size]; + } + }; + + /** @hide */ + public static CellSignalStrengthLte createFromParcelBody(Parcel in) { + return new CellSignalStrengthLte(in); + } + + /** + * log + */ + private static void log(String s) { + Log.w(LOG_TAG, s); + } +} diff --git a/telephony/java/android/telephony/LteCellIdentity.java b/telephony/java/android/telephony/LteCellIdentity.java deleted file mode 100644 index 396922e74721..000000000000 --- a/telephony/java/android/telephony/LteCellIdentity.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 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 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.telephony; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * CellIdentity is to represent a unique LTE cell - * - * @hide pending API review - */ -public final class LteCellIdentity extends CellIdentity implements Parcelable { - - // 3-digit Mobile Country Code, 0..999 - private final int mMcc; - // 2 or 3-digit Mobile Network Code, 0..999 - private final int mMnc; - // 28-bit cell identity - private final int mCi; - // physical cell id 0..503 - private final int mPci; - // 16-bit tracking area code - private final int mTac; - - /** - * - * @param mcc 3-digit Mobile Country Code, 0..999 - * @param mnc 2 or 3-digit Mobile Network Code, 0..999 - * @param ci 28-bit Cell Identity - * @param pci Physical Cell Id 0..503 - * @param tac 16-bit Tracking Area Code - * @param attr is comma separated “key=value” attribute pairs. - */ - public LteCellIdentity (int mcc, int mnc, - int ci, int pci, int tac, String attr) { - super(CELLID_TYPE_CDMA, attr); - mMcc = mcc; - mMnc = mnc; - mCi = ci; - mPci = pci; - mTac = tac; - } - - private LteCellIdentity(Parcel in) { - super(in); - mMcc = in.readInt(); - mMnc = in.readInt(); - mCi = in.readInt(); - mPci = in.readInt(); - mTac = in.readInt(); - } - - LteCellIdentity(LteCellIdentity cid) { - super(cid); - mMcc = cid.mMcc; - mMnc = cid.mMnc; - mCi = cid.mCi; - mPci = cid.mPci; - mTac = cid.mTac; - } - - /** - * @return 3-digit Mobile Country Code, 0..999 - */ - public int getMcc() { - return mMcc; - } - - /** - * @return 2 or 3-digit Mobile Network Code, 0..999 - */ - public int getMnc() { - return mMnc; - } - - /** - * @return 28-bit Cell Identity - */ - public int getCi() { - return mCi; - } - - /** - * @return Physical Cell Id 0..503 - */ - public int getPci() { - return mPci; - } - - /** - * @return 16-bit Tracking Area Code - */ - public int getTac() { - return mTac; - } - - /** Implement the Parcelable interface {@hide} */ - @Override - public int describeContents() { - return 0; - } - - /** Implement the Parcelable interface {@hide} */ - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeInt(mMcc); - dest.writeInt(mMnc); - dest.writeInt(mCi); - dest.writeInt(mPci); - dest.writeInt(mTac); - } - - /** Implement the Parcelable interface {@hide} */ - public static final Creator<LteCellIdentity> CREATOR = - new Creator<LteCellIdentity>() { - @Override - public LteCellIdentity createFromParcel(Parcel in) { - return new LteCellIdentity(in); - } - - @Override - public LteCellIdentity[] newArray(int size) { - return new LteCellIdentity[size]; - } - }; -} diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index def6939aef28..63d81e9c1b3d 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -27,6 +27,8 @@ import android.util.Log; import com.android.internal.telephony.IPhoneStateListener; +import java.util.List; + /** * A listener class for monitoring changes in specific telephony states * on the device, including service state, signal strength, message @@ -160,7 +162,8 @@ public class PhoneStateListener { * Listen for changes to observed cell info. * * @see #onCellInfoChanged - * @hide pending API review + * + * @hide */ public static final int LISTEN_CELL_INFO = 0x00000400; @@ -284,17 +287,13 @@ public class PhoneStateListener { } /** - * Callback invoked when a observed cell info gets changed. + * Callback invoked when a observed cell info has changed, + * or new cells have been added or removed. + * @param cellInfo is the list of currently visible cells. * - * A notification should be sent when: - * 1. a cell is newly-observed. - * 2. a observed cell is not visible. - * 3. any of the cell info of a observed cell has changed. - * - * @hide pending API review + * @hide */ - public void onCellInfoChanged(CellInfo cellInfo) { - // default implementation empty + public void onCellInfoChanged(List<CellInfo> cellInfo) { } /** @@ -346,8 +345,8 @@ public class PhoneStateListener { Message.obtain(mHandler, LISTEN_OTASP_CHANGED, otaspMode, 0).sendToTarget(); } - public void onCellInfoChanged(CellInfo cellInfo) { - Message.obtain(mHandler, LISTEN_CELL_INFO, 0, 0).sendToTarget(); + public void onCellInfoChanged(List<CellInfo> cellInfo) { + Message.obtain(mHandler, LISTEN_CELL_INFO, 0, 0, cellInfo).sendToTarget(); } }; @@ -387,7 +386,7 @@ public class PhoneStateListener { PhoneStateListener.this.onOtaspChanged(msg.arg1); break; case LISTEN_CELL_INFO: - PhoneStateListener.this.onCellInfoChanged((CellInfo)msg.obj); + PhoneStateListener.this.onCellInfoChanged((List<CellInfo>)msg.obj); } } }; diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java index 104966932ebe..d80425c55417 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -1,6 +1,5 @@ /* - * Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved. - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2012 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. @@ -28,7 +27,7 @@ import android.util.Log; public class SignalStrength implements Parcelable { private static final String LOG_TAG = "SignalStrength"; - private static final boolean DBG = false; + private static final boolean DBG = true; /** @hide */ public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; @@ -114,19 +113,9 @@ public class SignalStrength implements Parcelable { int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, boolean gsm) { - mGsmSignalStrength = gsmSignalStrength; - mGsmBitErrorRate = gsmBitErrorRate; - mCdmaDbm = cdmaDbm; - mCdmaEcio = cdmaEcio; - mEvdoDbm = evdoDbm; - mEvdoEcio = evdoEcio; - mEvdoSnr = evdoSnr; - mLteSignalStrength = lteSignalStrength; - mLteRsrp = lteRsrp; - mLteRsrq = lteRsrq; - mLteRssnr = lteRssnr; - mLteCqi = lteCqi; - isGsm = gsm; + initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, + evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, + lteRsrq, lteRssnr, lteCqi, gsm); } /** @@ -138,7 +127,7 @@ public class SignalStrength implements Parcelable { int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, boolean gsm) { - this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, + initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, evdoDbm, evdoEcio, evdoSnr, -1, -1, -1, INVALID_SNR, -1, gsm); } @@ -155,6 +144,69 @@ public class SignalStrength implements Parcelable { } /** + * Initialize gsm/cdma values, sets lte values to defaults. + * + * @param gsmSignalStrength + * @param gsmBitErrorRate + * @param cdmaDbm + * @param cdmaEcio + * @param evdoDbm + * @param evdoEcio + * @param evdoSnr + * @param gsm + * + * @hide + */ + public void initialize(int gsmSignalStrength, int gsmBitErrorRate, + int cdmaDbm, int cdmaEcio, + int evdoDbm, int evdoEcio, int evdoSnr, + boolean gsm) { + initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, + evdoDbm, evdoEcio, evdoSnr, -1, -1, + -1, INVALID_SNR, -1, gsm); + } + + /** + * Initialize all the values + * + * @param gsmSignalStrength + * @param gsmBitErrorRate + * @param cdmaDbm + * @param cdmaEcio + * @param evdoDbm + * @param evdoEcio + * @param evdoSnr + * @param lteSignalStrength + * @param lteRsrp + * @param lteRsrq + * @param lteRssnr + * @param lteCqi + * @param gsm + * + * @hide + */ + public void initialize(int gsmSignalStrength, int gsmBitErrorRate, + int cdmaDbm, int cdmaEcio, + int evdoDbm, int evdoEcio, int evdoSnr, + int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, + boolean gsm) { + mGsmSignalStrength = gsmSignalStrength; + mGsmBitErrorRate = gsmBitErrorRate; + mCdmaDbm = cdmaDbm; + mCdmaEcio = cdmaEcio; + mEvdoDbm = evdoDbm; + mEvdoEcio = evdoEcio; + mEvdoSnr = evdoSnr; + mLteSignalStrength = lteSignalStrength; + mLteRsrp = lteRsrp; + mLteRsrq = lteRsrq; + mLteRssnr = lteRssnr; + mLteCqi = lteCqi; + isGsm = gsm; + if (DBG) log("initialize: " + toString()); + } + + /** * @hide */ protected void copyFrom(SignalStrength s) { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index fa4b7cdc16ab..2b0fcd8e336e 100755 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1272,7 +1272,7 @@ public class TelephonyManager { * <p>Requires Permission: * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES} * - * @hide pending API review + * @hide */ public List<CellInfo> getAllCellInfo() { try { diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index d6a1edd3d25f..3a04ceb9e65b 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -34,6 +34,6 @@ oneway interface IPhoneStateListener { void onDataActivity(int direction); void onSignalStrengthsChanged(in SignalStrength signalStrength); void onOtaspChanged(in int otaspMode); - void onCellInfoChanged(in CellInfo cellInfo); + void onCellInfoChanged(in List<CellInfo> cellInfo); } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 3c9a99b9bbb6..59c84724e233 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -40,5 +40,5 @@ interface ITelephonyRegistry { void notifyDataConnectionFailed(String reason, String apnType); void notifyCellLocation(in Bundle cellLocation); void notifyOtaspChanged(in int otaspMode); - void notifyCellInfo(in CellInfo cellInfo); + void notifyCellInfo(in List<CellInfo> cellInfo); } diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java index 36f13b17bc70..f0ce458b9195 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java @@ -67,6 +67,7 @@ public class RSTestCore { unitTests.add(new UT_primitives(this, mRes, mCtx)); unitTests.add(new UT_constant(this, mRes, mCtx)); unitTests.add(new UT_vector(this, mRes, mCtx)); + unitTests.add(new UT_unsigned(this, mRes, mCtx)); unitTests.add(new UT_array_init(this, mRes, mCtx)); unitTests.add(new UT_array_alloc(this, mRes, mCtx)); unitTests.add(new UT_clamp(this, mRes, mCtx)); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java index 9d94ba58d7ee..ca49344a6498 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math_agree.java @@ -299,14 +299,14 @@ public class UT_math_agree extends UnitTest { float[] rand_f2_1 = randvec_float(2); float[] rand_f3_1 = randvec_float(3); float[] rand_f4_1 = randvec_float(4); - byte rand_sc1_0 = (byte)rand.nextInt(0x1 << 8); - byte[] rand_sc2_0 = randvec_char(2); - byte[] rand_sc3_0 = randvec_char(3); - byte[] rand_sc4_0 = randvec_char(4); - byte rand_sc1_1 = (byte)rand.nextInt(0x1 << 8); - byte[] rand_sc2_1 = randvec_char(2); - byte[] rand_sc3_1 = randvec_char(3); - byte[] rand_sc4_1 = randvec_char(4); + short rand_uc1_0 = (short)rand.nextInt(0x1 << 8); + short[] rand_uc2_0 = randvec_uchar(2); + short[] rand_uc3_0 = randvec_uchar(3); + short[] rand_uc4_0 = randvec_uchar(4); + short rand_uc1_1 = (short)rand.nextInt(0x1 << 8); + short[] rand_uc2_1 = randvec_uchar(2); + short[] rand_uc3_1 = randvec_uchar(3); + short[] rand_uc4_1 = randvec_uchar(4); short rand_ss1_0 = (short)rand.nextInt(0x1 << 16); short[] rand_ss2_0 = randvec_short(2); short[] rand_ss3_0 = randvec_short(3); @@ -315,6 +315,14 @@ public class UT_math_agree extends UnitTest { short[] rand_ss2_1 = randvec_short(2); short[] rand_ss3_1 = randvec_short(3); short[] rand_ss4_1 = randvec_short(4); + int rand_us1_0 = rand.nextInt(0x1 << 16); + int[] rand_us2_0 = randvec_ushort(2); + int[] rand_us3_0 = randvec_ushort(3); + int[] rand_us4_0 = randvec_ushort(4); + int rand_us1_1 = rand.nextInt(0x1 << 16); + int[] rand_us2_1 = randvec_ushort(2); + int[] rand_us3_1 = randvec_ushort(3); + int[] rand_us4_1 = randvec_ushort(4); int rand_si1_0 = rand.nextInt(); int[] rand_si2_0 = randvec_int(2); int[] rand_si3_0 = randvec_int(3); @@ -323,6 +331,14 @@ public class UT_math_agree extends UnitTest { int[] rand_si2_1 = randvec_int(2); int[] rand_si3_1 = randvec_int(3); int[] rand_si4_1 = randvec_int(4); + long rand_ui1_0 = (long)rand.nextInt() - (long)Integer.MIN_VALUE; + long[] rand_ui2_0 = randvec_uint(2); + long[] rand_ui3_0 = randvec_uint(3); + long[] rand_ui4_0 = randvec_uint(4); + long rand_ui1_1 = (long)rand.nextInt() - (long)Integer.MIN_VALUE; + long[] rand_ui2_1 = randvec_uint(2); + long[] rand_ui3_1 = randvec_uint(3); + long[] rand_ui4_1 = randvec_uint(4); long rand_sl1_0 = rand.nextLong(); long[] rand_sl2_0 = randvec_long(2); long[] rand_sl3_0 = randvec_long(3); @@ -331,32 +347,16 @@ public class UT_math_agree extends UnitTest { long[] rand_sl2_1 = randvec_long(2); long[] rand_sl3_1 = randvec_long(3); long[] rand_sl4_1 = randvec_long(4); - // FIXME: generate unsigned input vectors once bug 6764163 is fixed + // FIXME: generate signed char vectors once bug 6865598 is fixed /* - short rand_uc1_0 = (short)rand.nextInt(0x1 << 8); - short[] rand_uc2_0 = randvec_uchar(2); - short[] rand_uc3_0 = randvec_uchar(3); - short[] rand_uc4_0 = randvec_uchar(4); - short rand_uc1_1 = (short)rand.nextInt(0x1 << 8); - short[] rand_uc2_1 = randvec_uchar(2); - short[] rand_uc3_1 = randvec_uchar(3); - short[] rand_uc4_1 = randvec_uchar(4); - int rand_us1_0 = rand.nextInt(0x1 << 16); - int[] rand_us2_0 = randvec_ushort(2); - int[] rand_us3_0 = randvec_ushort(3); - int[] rand_us4_0 = randvec_ushort(4); - int rand_us1_1 = rand.nextInt(0x1 << 16); - int[] rand_us2_1 = randvec_ushort(2); - int[] rand_us3_1 = randvec_ushort(3); - int[] rand_us4_1 = randvec_ushort(4); - long rand_ui1_0 = (long)rand.nextInt() - (long)Integer.MIN_VALUE; - long[] rand_ui2_0 = randvec_uint(2); - long[] rand_ui3_0 = randvec_uint(3); - long[] rand_ui4_0 = randvec_uint(4); - long rand_ui1_1 = (long)rand.nextInt() - (long)Integer.MIN_VALUE; - long[] rand_ui2_1 = randvec_uint(2); - long[] rand_ui3_1 = randvec_uint(3); - long[] rand_ui4_1 = randvec_uint(4); + byte rand_sc1_0 = (byte)rand.nextInt(0x1 << 8); + byte[] rand_sc2_0 = randvec_char(2); + byte[] rand_sc3_0 = randvec_char(3); + byte[] rand_sc4_0 = randvec_char(4); + byte rand_sc1_1 = (byte)rand.nextInt(0x1 << 8); + byte[] rand_sc2_1 = randvec_char(2); + byte[] rand_sc3_1 = randvec_char(3); + byte[] rand_sc4_1 = randvec_char(4); */ // TODO: generate unsigned long vectors @@ -369,10 +369,10 @@ public class UT_math_agree extends UnitTest { s.set_rand_f2_1(pack_f2(rand_f2_1)); s.set_rand_f3_1(pack_f3(rand_f3_1)); s.set_rand_f4_1(pack_f4(rand_f4_1)); - s.set_rand_sc1_1(rand_sc1_1); - s.set_rand_sc2_1(pack_b2(rand_sc2_1)); - s.set_rand_sc3_1(pack_b3(rand_sc3_1)); - s.set_rand_sc4_1(pack_b4(rand_sc4_1)); + s.set_rand_uc1_1(rand_uc1_1); + s.set_rand_uc2_1(pack_s2(rand_uc2_1)); + s.set_rand_uc3_1(pack_s3(rand_uc3_1)); + s.set_rand_uc4_1(pack_s4(rand_uc4_1)); s.set_rand_ss1_0(rand_ss1_0); s.set_rand_ss2_0(pack_s2(rand_ss2_0)); s.set_rand_ss3_0(pack_s3(rand_ss3_0)); @@ -381,6 +381,14 @@ public class UT_math_agree extends UnitTest { s.set_rand_ss2_1(pack_s2(rand_ss2_1)); s.set_rand_ss3_1(pack_s3(rand_ss3_1)); s.set_rand_ss4_1(pack_s4(rand_ss4_1)); + s.set_rand_us1_0(rand_us1_0); + s.set_rand_us2_0(pack_i2(rand_us2_0)); + s.set_rand_us3_0(pack_i3(rand_us3_0)); + s.set_rand_us4_0(pack_i4(rand_us4_0)); + s.set_rand_us1_1(rand_us1_1); + s.set_rand_us2_1(pack_i2(rand_us2_1)); + s.set_rand_us3_1(pack_i3(rand_us3_1)); + s.set_rand_us4_1(pack_i4(rand_us4_1)); s.set_rand_si1_0(rand_si1_0); s.set_rand_si2_0(pack_i2(rand_si2_0)); s.set_rand_si3_0(pack_i3(rand_si3_0)); @@ -389,6 +397,14 @@ public class UT_math_agree extends UnitTest { s.set_rand_si2_1(pack_i2(rand_si2_1)); s.set_rand_si3_1(pack_i3(rand_si3_1)); s.set_rand_si4_1(pack_i4(rand_si4_1)); + s.set_rand_ui1_0(rand_ui1_0); + s.set_rand_ui2_0(pack_l2(rand_ui2_0)); + s.set_rand_ui3_0(pack_l3(rand_ui3_0)); + s.set_rand_ui4_0(pack_l4(rand_ui4_0)); + s.set_rand_ui1_1(rand_ui1_1); + s.set_rand_ui2_1(pack_l2(rand_ui2_1)); + s.set_rand_ui3_1(pack_l3(rand_ui3_1)); + s.set_rand_ui4_1(pack_l4(rand_ui4_1)); s.set_rand_sl1_0(rand_sl1_0); s.set_rand_sl2_0(pack_l2(rand_sl2_0)); s.set_rand_sl3_0(pack_l3(rand_sl3_0)); @@ -397,39 +413,20 @@ public class UT_math_agree extends UnitTest { s.set_rand_sl2_1(pack_l2(rand_sl2_1)); s.set_rand_sl3_1(pack_l3(rand_sl3_1)); s.set_rand_sl4_1(pack_l4(rand_sl4_1)); - // FIXME: set signed char input vectors once bug is fixed + s.set_rand_uc1_0(rand_uc1_0); + s.set_rand_uc2_0(pack_s2(rand_uc2_0)); + s.set_rand_uc3_0(pack_s3(rand_uc3_0)); + s.set_rand_uc4_0(pack_s4(rand_uc4_0)); + // FIXME: set char input vectors once bug 6865598 is fixed /* s.set_rand_sc1_0(rand_sc1_0); s.set_rand_sc2_0(pack_b2(rand_sc2_0)); s.set_rand_sc3_0(pack_b3(rand_sc3_0)); s.set_rand_sc4_0(pack_b4(rand_sc4_0)); - */ - // FIXME: set unsigned input vectors once bug 6764163 is fixed - /* - s.set_rand_us1_0(rand_us1_0); - s.set_rand_us2_0(pack_i2(rand_us2_0)); - s.set_rand_us3_0(pack_i3(rand_us3_0)); - s.set_rand_us4_0(pack_i4(rand_us4_0)); - s.set_rand_us1_1(rand_us1_1); - s.set_rand_us2_1(pack_i2(rand_us2_1)); - s.set_rand_us3_1(pack_i3(rand_us3_1)); - s.set_rand_us4_1(pack_i4(rand_us4_1)); - s.set_rand_uc1_0(rand_uc1_0); - s.set_rand_uc2_0(pack_s2(rand_uc2_0)); - s.set_rand_uc3_0(pack_s3(rand_uc3_0)); - s.set_rand_uc4_0(pack_s4(rand_uc4_0)); - s.set_rand_uc1_1(rand_uc1_1); - s.set_rand_uc2_1(pack_s2(rand_uc2_1)); - s.set_rand_uc3_1(pack_s3(rand_uc3_1)); - s.set_rand_uc4_1(pack_s4(rand_uc4_1)); - s.set_rand_ui1_0(rand_ui1_0); - s.set_rand_ui2_0(pack_l2(rand_ui2_0)); - s.set_rand_ui3_0(pack_l3(rand_ui3_0)); - s.set_rand_ui4_0(pack_l4(rand_ui4_0)); - s.set_rand_ui1_1(rand_ui1_1); - s.set_rand_ui2_1(pack_l2(rand_ui2_1)); - s.set_rand_ui3_1(pack_l3(rand_ui3_1)); - s.set_rand_ui4_1(pack_l4(rand_ui4_1)); + s.set_rand_sc1_1(rand_sc1_1); + s.set_rand_sc2_1(pack_b2(rand_sc2_1)); + s.set_rand_sc3_1(pack_b3(rand_sc3_1)); + s.set_rand_sc4_1(pack_b4(rand_sc4_1)); */ // TODO: set unsigned long vectors @@ -438,40 +435,37 @@ public class UT_math_agree extends UnitTest { s.set_min_rand_f2_f2(pack_f2(min(rand_f2_0, rand_f2_1))); s.set_min_rand_f3_f3(pack_f3(min(rand_f3_0, rand_f3_1))); s.set_min_rand_f4_f4(pack_f4(min(rand_f4_0, rand_f4_1))); + s.set_min_rand_uc1_uc1(min(rand_uc1_0, rand_uc1_1)); + s.set_min_rand_uc2_uc2(pack_s2(min(rand_uc2_0, rand_uc2_1))); + s.set_min_rand_uc3_uc3(pack_s3(min(rand_uc3_0, rand_uc3_1))); + s.set_min_rand_uc4_uc4(pack_s4(min(rand_uc4_0, rand_uc4_1))); s.set_min_rand_ss1_ss1(min(rand_ss1_0, rand_ss1_1)); s.set_min_rand_ss2_ss2(pack_s2(min(rand_ss2_0, rand_ss2_1))); s.set_min_rand_ss3_ss3(pack_s3(min(rand_ss3_0, rand_ss3_1))); s.set_min_rand_ss4_ss4(pack_s4(min(rand_ss4_0, rand_ss4_1))); + s.set_min_rand_us1_us1(min(rand_us1_0, rand_us1_1)); + s.set_min_rand_us2_us2(pack_i2(min(rand_us2_0, rand_us2_1))); + s.set_min_rand_us3_us3(pack_i3(min(rand_us3_0, rand_us3_1))); + s.set_min_rand_us4_us4(pack_i4(min(rand_us4_0, rand_us4_1))); s.set_min_rand_si1_si1(min(rand_si1_0, rand_si1_1)); s.set_min_rand_si2_si2(pack_i2(min(rand_si2_0, rand_si2_1))); s.set_min_rand_si3_si3(pack_i3(min(rand_si3_0, rand_si3_1))); s.set_min_rand_si4_si4(pack_i4(min(rand_si4_0, rand_si4_1))); + s.set_min_rand_ui1_ui1(min(rand_ui1_0, rand_ui1_1)); + s.set_min_rand_ui2_ui2(pack_l2(min(rand_ui2_0, rand_ui2_1))); + s.set_min_rand_ui3_ui3(pack_l3(min(rand_ui3_0, rand_ui3_1))); + s.set_min_rand_ui4_ui4(pack_l4(min(rand_ui4_0, rand_ui4_1))); s.set_min_rand_sl1_sl1(min(rand_sl1_0, rand_sl1_1)); s.set_min_rand_sl2_sl2(pack_l2(min(rand_sl2_0, rand_sl2_1))); s.set_min_rand_sl3_sl3(pack_l3(min(rand_sl3_0, rand_sl3_1))); s.set_min_rand_sl4_sl4(pack_l4(min(rand_sl4_0, rand_sl4_1))); - // FIXME: set signed char min reference vectors once bug is fixed + // FIXME: set char min reference vectors once bug 6865598 is fixed /* s.set_min_rand_sc1_sc1(min(rand_sc1_0, rand_sc1_1)); s.set_min_rand_sc2_sc2(pack_b2(min(rand_sc2_0, rand_sc2_1))); s.set_min_rand_sc3_sc3(pack_b3(min(rand_sc3_0, rand_sc3_1))); s.set_min_rand_sc4_sc4(pack_b4(min(rand_sc4_0, rand_sc4_1))); */ - // FIXME: set unsigned min reference vectors once bug 6764163 is fixed - /* - s.set_min_rand_uc1_uc1(min(rand_uc1_0, rand_uc1_1)); - s.set_min_rand_uc2_uc2(pack_s3(min(rand_uc2_0, rand_uc2_1))); - s.set_min_rand_uc3_uc3(pack_s3(min(rand_uc3_0, rand_uc3_1))); - s.set_min_rand_uc4_uc4(pack_s4(min(rand_uc4_0, rand_uc4_1))); - s.set_min_rand_us1_us1(min(rand_us1_0, rand_us1_1)); - s.set_min_rand_us2_us2(pack_i2(min(rand_us2_0, rand_us2_1))); - s.set_min_rand_us3_us3(pack_i3(min(rand_us3_0, rand_us3_1))); - s.set_min_rand_us4_us4(pack_i4(min(rand_us4_0, rand_us4_1))); - s.set_min_rand_ui1_ui1(min(rand_ui1_0, rand_ui1_1)); - s.set_min_rand_ui2_ui2(pack_l2(min(rand_ui2_0, rand_ui2_1))); - s.set_min_rand_ui3_ui3(pack_l3(min(rand_ui3_0, rand_ui3_1))); - s.set_min_rand_ui4_ui4(pack_l4(min(rand_ui4_0, rand_ui4_1))); - */ // TODO: set results for unsigned long min // Set results for max @@ -479,40 +473,38 @@ public class UT_math_agree extends UnitTest { s.set_max_rand_f2_f2(pack_f2(max(rand_f2_0, rand_f2_1))); s.set_max_rand_f3_f3(pack_f3(max(rand_f3_0, rand_f3_1))); s.set_max_rand_f4_f4(pack_f4(max(rand_f4_0, rand_f4_1))); + s.set_max_rand_uc1_uc1(max(rand_uc1_0, rand_uc1_1)); + s.set_max_rand_uc2_uc2(pack_s2(max(rand_uc2_0, rand_uc2_1))); + s.set_max_rand_uc3_uc3(pack_s3(max(rand_uc3_0, rand_uc3_1))); + s.set_max_rand_uc4_uc4(pack_s4(max(rand_uc4_0, rand_uc4_1))); s.set_max_rand_ss1_ss1(max(rand_ss1_0, rand_ss1_1)); s.set_max_rand_ss2_ss2(pack_s2(max(rand_ss2_0, rand_ss2_1))); s.set_max_rand_ss3_ss3(pack_s3(max(rand_ss3_0, rand_ss3_1))); s.set_max_rand_ss4_ss4(pack_s4(max(rand_ss4_0, rand_ss4_1))); + s.set_max_rand_us1_us1(max(rand_us1_0, rand_us1_1)); + s.set_max_rand_us2_us2(pack_i2(max(rand_us2_0, rand_us2_1))); + s.set_max_rand_us3_us3(pack_i3(max(rand_us3_0, rand_us3_1))); + s.set_max_rand_us4_us4(pack_i4(max(rand_us4_0, rand_us4_1))); s.set_max_rand_si1_si1(max(rand_si1_0, rand_si1_1)); s.set_max_rand_si2_si2(pack_i2(max(rand_si2_0, rand_si2_1))); s.set_max_rand_si3_si3(pack_i3(max(rand_si3_0, rand_si3_1))); s.set_max_rand_si4_si4(pack_i4(max(rand_si4_0, rand_si4_1))); + s.set_max_rand_ui1_ui1(max(rand_ui1_0, rand_ui1_1)); + s.set_max_rand_ui2_ui2(pack_l2(max(rand_ui2_0, rand_ui2_1))); + s.set_max_rand_ui3_ui3(pack_l3(max(rand_ui3_0, rand_ui3_1))); + s.set_max_rand_ui4_ui4(pack_l4(max(rand_ui4_0, rand_ui4_1))); s.set_max_rand_sl1_sl1(max(rand_sl1_0, rand_sl1_1)); s.set_max_rand_sl2_sl2(pack_l2(max(rand_sl2_0, rand_sl2_1))); s.set_max_rand_sl3_sl3(pack_l3(max(rand_sl3_0, rand_sl3_1))); s.set_max_rand_sl4_sl4(pack_l4(max(rand_sl4_0, rand_sl4_1))); - // FIXME: set signed char max reference vectors once bug is fixed + // FIXME: set signed char max reference vectors once bug 6865598 is fixed /* s.set_max_rand_sc1_sc1(max(rand_sc1_0, rand_sc1_1)); s.set_max_rand_sc2_sc2(pack_b2(max(rand_sc2_0, rand_sc2_1))); s.set_max_rand_sc3_sc3(pack_b3(max(rand_sc3_0, rand_sc3_1))); s.set_max_rand_sc4_sc4(pack_b4(max(rand_sc4_0, rand_sc4_1))); */ - // FIXME: set unsigned max reference vectors once bug 6764163 is fixed - /* - s.set_max_rand_uc1_uc1(max(rand_uc1_0, rand_uc1_1)); - s.set_max_rand_uc2_uc2(pack_s3(max(rand_uc2_0, rand_uc2_1))); - s.set_max_rand_uc3_uc3(pack_s3(max(rand_uc3_0, rand_uc3_1))); - s.set_max_rand_uc4_uc4(pack_s4(max(rand_uc4_0, rand_uc4_1))); - s.set_max_rand_us1_us1(max(rand_us1_0, rand_us1_1)); - s.set_max_rand_us2_us2(pack_i2(max(rand_us2_0, rand_us2_1))); - s.set_max_rand_us3_us3(pack_i3(max(rand_us3_0, rand_us3_1))); - s.set_max_rand_us4_us4(pack_i4(max(rand_us4_0, rand_us4_1))); - s.set_max_rand_ui1_ui1(max(rand_ui1_0, rand_ui1_1)); - s.set_max_rand_ui2_ui2(pack_l2(max(rand_ui2_0, rand_ui2_1))); - s.set_max_rand_ui3_ui3(pack_l3(max(rand_ui3_0, rand_ui3_1))); - s.set_max_rand_ui4_ui4(pack_l4(max(rand_ui4_0, rand_ui4_1))); - */ + // TODO: set results for unsigned long max // Set results for fmin diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_unsigned.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_unsigned.java new file mode 100644 index 000000000000..2164766bec7d --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_unsigned.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012 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.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_unsigned extends UnitTest { + private Resources mRes; + + protected UT_unsigned(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Unsigned", ctx); + mRes = res; + } + + private boolean initializeGlobals(ScriptC_unsigned s) { + short pUC = s.get_uc(); + if (pUC != 5) { + return false; + } + s.set_uc((short)129); + + long pUI = s.get_ui(); + if (pUI != 37) { + return false; + } + s.set_ui(0x7fffffff); + + return true; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_unsigned s = new ScriptC_unsigned(pRS, mRes, R.raw.unsigned); + pRS.setMessageHandler(mRsMessage); + if (!initializeGlobals(s)) { + failTest(); + } else { + s.invoke_unsigned_test(); + pRS.finish(); + waitForMessage(); + } + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs index ac3a3fa9b617..1adb036fca26 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/math_agree.rs @@ -337,15 +337,16 @@ TEST_UL3_UL3(func) \ TEST_UL4_UL4(func) #define TEST_VEC_VEC_ALL(func) \ -TEST_FN_FN_ALL(func) \ +TEST_FN_FN_ALL(func) \ +TEST_UC_UC_ALL(func) \ TEST_SS_SS_ALL(func) \ -TEST_SI_SI_ALL(func) -// FIXME: Add tests back in once bug 6764163 is fixed -#if 0 -TEST_SC_SC_ALL(func) \ TEST_US_US_ALL(func) \ -TEST_UC_UC_ALL(func) \ +TEST_SI_SI_ALL(func) \ TEST_UI_UI_ALL(func) + +// FIXME: Add char tests back in once bug 6865598 is fixed +#if 0 +TEST_SC_SC_ALL(func) #endif // TODO: add long types to ALL macro #if 0 diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/unsigned.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/unsigned.rs new file mode 100644 index 000000000000..2c056f49c2c2 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/unsigned.rs @@ -0,0 +1,36 @@ +#include "shared.rsh" + +// Testing unsigned types for Bug 6764163 +unsigned int ui = 37; +unsigned char uc = 5; + +static bool test_unsigned() { + bool failed = false; + + rsDebug("ui", ui); + rsDebug("uc", uc); + _RS_ASSERT(ui == 0x7fffffff); + _RS_ASSERT(uc == 129); + + if (failed) { + rsDebug("test_unsigned FAILED", -1); + } + else { + rsDebug("test_unsigned PASSED", 0); + } + + return failed; +} + +void unsigned_test() { + bool failed = false; + failed |= test_unsigned(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java index 8868c65e59a8..6ccdcb6d2bf5 100644 --- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java +++ b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java @@ -31,57 +31,4 @@ import android.os.RemoteException; */ public class Display_Delegate { - // ---- Overridden methods ---- - - @LayoutlibDelegate - public static IWindowManager getWindowManager() { - return RenderAction.getCurrentContext().getIWindowManager(); - } - - // ---- Native methods ---- - - @LayoutlibDelegate - /*package*/ static int getDisplayCount() { - return 1; - } - - @LayoutlibDelegate - /** @hide special for when we are faking the screen size. */ - /*package*/ static int getRawWidthNative(Display theDisplay) { - // same as real since we're not faking compatibility mode. - return RenderAction.getCurrentContext().getIWindowManager().getMetrics().widthPixels; - } - - @LayoutlibDelegate - /** @hide special for when we are faking the screen size. */ - /*package*/ static int getRawHeightNative(Display theDisplay) { - // same as real since we're not faking compatibility mode. - return RenderAction.getCurrentContext().getIWindowManager().getMetrics().heightPixels; - } - - @LayoutlibDelegate - /*package*/ static int getOrientation(Display theDisplay) { - try { - // always dynamically query for the current window manager - return getWindowManager().getRotation(); - } catch (RemoteException e) { - // this will never been thrown since this is not a true RPC. - } - - return Surface.ROTATION_0; - } - - @LayoutlibDelegate - /*package*/ static void nativeClassInit() { - // not needed for now. - } - - @LayoutlibDelegate - /*package*/ static void init(Display theDisplay, int display) { - // always dynamically query for the current window manager - BridgeWindowManager wm = RenderAction.getCurrentContext().getIWindowManager(); - theDisplay.mDensity = wm.getMetrics().density; - theDisplay.mDpiX = wm.getMetrics().xdpi; - theDisplay.mDpiY = wm.getMetrics().ydpi; - } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java index 3e56b6057194..2619dd85ba22 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java @@ -29,6 +29,7 @@ import android.os.IRemoteCallback; import android.os.RemoteException; import android.util.DisplayMetrics; import android.view.Display; +import android.view.DisplayInfo; import android.view.Display_Delegate; import android.view.Gravity; import android.view.IApplicationToken; @@ -69,23 +70,6 @@ public class BridgeWindowManager implements IWindowManager { return mRotation; } - @Override - public int getMaximumSizeDimension() throws RemoteException { - return 0; - } - - @Override - public void getCurrentSizeRange(Point smallestSize, Point largestSize) { - } - - @Override - public void getDisplaySize(Point arg0) throws RemoteException { - } - - @Override - public void getRealDisplaySize(Point arg0) throws RemoteException { - } - // ---- unused implementation of IWindowManager ---- @Override diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 36f38f93ff1c..6e58a2d4b1aa 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -23,13 +23,17 @@ import android.net.DhcpInfo; import android.os.Binder; import android.os.IBinder; import android.os.Handler; +import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.WorkSource; import android.os.Messenger; +import android.util.Log; import android.util.SparseArray; +import java.util.concurrent.CountDownLatch; + import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; @@ -58,6 +62,7 @@ import java.util.List; */ public class WifiManager { + private static final String TAG = "WifiManager"; // Supplicant error codes: /** * The error code if there was a problem authenticating. @@ -481,9 +486,6 @@ public class WifiManager { /** @hide */ public static final int DATA_ACTIVITY_INOUT = 0x03; - IWifiManager mService; - Handler mHandler; - /* Maximum number of active locks we allow. * This limit was added to prevent apps from creating a ridiculous number * of locks and crashing the system by overflowing the global ref table. @@ -493,19 +495,33 @@ public class WifiManager { /* Number of currently active WifiLocks and MulticastLocks */ private int mActiveLockCount; + private Context mContext; + IWifiManager mService; + + private static final int INVALID_KEY = 0; + private int mListenerKey = 1; + private final SparseArray mListenerMap = new SparseArray(); + private final Object mListenerMapLock = new Object(); + + private AsyncChannel mAsyncChannel = new AsyncChannel(); + private ServiceHandler mHandler; + private Messenger mWifiServiceMessenger; + private final CountDownLatch mConnected = new CountDownLatch(1); + /** * Create a new WifiManager instance. * Applications will almost always want to use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. + * @param context the application context * @param service the Binder interface - * @param handler target for messages * @hide - hide this because it takes in a parameter of type IWifiManager, which * is a system private class. */ - public WifiManager(IWifiManager service, Handler handler) { + public WifiManager(Context context, IWifiManager service) { + mContext = context; mService = service; - mHandler = handler; + init(); } /** @@ -1168,15 +1184,6 @@ public class WifiManager { /** WPS timed out {@hide} */ public static final int WPS_TIMED_OUT = 7; - /** Interface for callback invocation when framework channel is lost {@hide} */ - public interface ChannelListener { - /** - * The channel to the framework has been disconnected. - * Application could try re-initializing using {@link #initialize} - */ - public void onChannelDisconnected(); - } - /** Interface for callback invocation on an application action {@hide} */ public interface ActionListener { /** The operation succeeded */ @@ -1205,134 +1212,122 @@ public class WifiManager { public void onFailure(int reason); } - /** - * A channel that connects the application to the Wifi framework. - * Most operations require a Channel as an argument. An instance of Channel is obtained - * by doing a call on {@link #initialize} - * @hide - */ - public static class Channel { - Channel(Looper looper, ChannelListener l) { - mAsyncChannel = new AsyncChannel(); - mHandler = new WifiHandler(looper); - mChannelListener = l; + private class ServiceHandler extends Handler { + ServiceHandler(Looper looper) { + super(looper); } - private ChannelListener mChannelListener; - private SparseArray<Object> mListenerMap = new SparseArray<Object>(); - private Object mListenerMapLock = new Object(); - private int mListenerKey = 0; - private static final int INVALID_KEY = -1; - - AsyncChannel mAsyncChannel; - WifiHandler mHandler; - class WifiHandler extends Handler { - WifiHandler(Looper looper) { - super(looper); - } - @Override - public void handleMessage(Message message) { - Object listener = removeListener(message.arg2); - switch (message.what) { - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: - if (mChannelListener != null) { - mChannelListener.onChannelDisconnected(); - mChannelListener = null; - } - break; - /* ActionListeners grouped together */ - case WifiManager.CONNECT_NETWORK_FAILED: - case WifiManager.FORGET_NETWORK_FAILED: - case WifiManager.SAVE_NETWORK_FAILED: - case WifiManager.CANCEL_WPS_FAILED: - case WifiManager.DISABLE_NETWORK_FAILED: - if (listener != null) { - ((ActionListener) listener).onFailure(message.arg1); - } - break; - /* ActionListeners grouped together */ - case WifiManager.CONNECT_NETWORK_SUCCEEDED: - case WifiManager.FORGET_NETWORK_SUCCEEDED: - case WifiManager.SAVE_NETWORK_SUCCEEDED: - case WifiManager.CANCEL_WPS_SUCCEDED: - case WifiManager.DISABLE_NETWORK_SUCCEEDED: - if (listener != null) { - ((ActionListener) listener).onSuccess(); - } - break; - case WifiManager.START_WPS_SUCCEEDED: - if (listener != null) { - WpsResult result = (WpsResult) message.obj; - ((WpsListener) listener).onStartSuccess(result.pin); - //Listener needs to stay until completion or failure - synchronized(mListenerMapLock) { - mListenerMap.put(message.arg2, listener); - } - } - break; - case WifiManager.WPS_COMPLETED: - if (listener != null) { - ((WpsListener) listener).onCompletion(); - } - break; - case WifiManager.WPS_FAILED: - if (listener != null) { - ((WpsListener) listener).onFailure(message.arg1); + @Override + public void handleMessage(Message message) { + Object listener = removeListener(message.arg2); + switch (message.what) { + case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: + if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { + mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); + } else { + Log.e(TAG, "Failed to set up channel connection"); + // This will cause all further async API calls on the WifiManager + // to fail and throw an exception + mAsyncChannel = null; + } + mConnected.countDown(); + break; + case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: + // Ignore + break; + case AsyncChannel.CMD_CHANNEL_DISCONNECTED: + Log.e(TAG, "Channel connection lost"); + // This will cause all further async API calls on the WifiManager + // to fail and throw an exception + mAsyncChannel = null; + break; + /* ActionListeners grouped together */ + case WifiManager.CONNECT_NETWORK_FAILED: + case WifiManager.FORGET_NETWORK_FAILED: + case WifiManager.SAVE_NETWORK_FAILED: + case WifiManager.CANCEL_WPS_FAILED: + case WifiManager.DISABLE_NETWORK_FAILED: + if (listener != null) { + ((ActionListener) listener).onFailure(message.arg1); + } + break; + /* ActionListeners grouped together */ + case WifiManager.CONNECT_NETWORK_SUCCEEDED: + case WifiManager.FORGET_NETWORK_SUCCEEDED: + case WifiManager.SAVE_NETWORK_SUCCEEDED: + case WifiManager.CANCEL_WPS_SUCCEDED: + case WifiManager.DISABLE_NETWORK_SUCCEEDED: + if (listener != null) { + ((ActionListener) listener).onSuccess(); + } + break; + case WifiManager.START_WPS_SUCCEEDED: + if (listener != null) { + WpsResult result = (WpsResult) message.obj; + ((WpsListener) listener).onStartSuccess(result.pin); + //Listener needs to stay until completion or failure + synchronized(mListenerMapLock) { + mListenerMap.put(message.arg2, listener); } - break; - default: - //ignore - break; - } + } + break; + case WifiManager.WPS_COMPLETED: + if (listener != null) { + ((WpsListener) listener).onCompletion(); + } + break; + case WifiManager.WPS_FAILED: + if (listener != null) { + ((WpsListener) listener).onFailure(message.arg1); + } + break; + default: + //ignore + break; } } + } - int putListener(Object listener) { - if (listener == null) return INVALID_KEY; - int key; - synchronized (mListenerMapLock) { - do { - key = mListenerKey++; - } while (key == INVALID_KEY); - mListenerMap.put(key, listener); - } - return key; + private int putListener(Object listener) { + if (listener == null) return INVALID_KEY; + int key; + synchronized (mListenerMapLock) { + do { + key = mListenerKey++; + } while (key == INVALID_KEY); + mListenerMap.put(key, listener); } + return key; + } - Object removeListener(int key) { - if (key == INVALID_KEY) return null; - synchronized (mListenerMapLock) { - Object listener = mListenerMap.get(key); - mListenerMap.remove(key); - return listener; - } + private Object removeListener(int key) { + if (key == INVALID_KEY) return null; + synchronized (mListenerMapLock) { + Object listener = mListenerMap.get(key); + mListenerMap.remove(key); + return listener; } } - /** - * Registers the application with the Wi-Fi framework. This function - * must be the first to be called before any Wi-Fi operations are performed. - * - * @param srcContext is the context of the source - * @param srcLooper is the Looper on which the callbacks are receivied - * @param listener for callback at loss of framework communication. Can be null. - * @return Channel instance that is necessary for performing any further Wi-Fi operations. - * A null is returned upon failure to initialize. - * @hide - */ - public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) { - Messenger messenger = getWifiServiceMessenger(); - if (messenger == null) return null; - - Channel c = new Channel(srcLooper, listener); - if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger) - == AsyncChannel.STATUS_SUCCESSFUL) { - return c; - } else { - return null; + private void init() { + mWifiServiceMessenger = getWifiServiceMessenger(); + if (mWifiServiceMessenger == null) throw new RuntimeException("Failed to initialize"); + HandlerThread t = new HandlerThread("WifiManager"); + t.start(); + mHandler = new ServiceHandler(t.getLooper()); + mAsyncChannel.connect(mContext, mHandler, mWifiServiceMessenger); + try { + mConnected.await(); + } catch (InterruptedException e) { + Log.e(TAG, "interrupted wait at init"); } } + private void validateChannel() { + if (mAsyncChannel == null) throw new IllegalStateException( + "Bad WifiManager instance state, re-initialize"); + } + /** * Connect to a network with the given configuration. The network also * gets added to the supplicant configuration. @@ -1341,20 +1336,21 @@ public class WifiManager { * sequence of addNetwork(), enableNetwork(), saveConfiguration() and * reconnect() * - * @param c is the channel created at {@link #initialize} * @param config the set of variables that describe the configuration, * contained in a {@link WifiConfiguration} object. * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again + * * @hide */ - public void connect(Channel c, WifiConfiguration config, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void connect(WifiConfiguration config, ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - + validateChannel(); // Use INVALID_NETWORK_ID for arg1 when passing a config object // arg1 is used to pass network id when the network already exists - c.mAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, - c.putListener(listener), config); + mAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, + putListener(listener), config); } /** @@ -1363,17 +1359,17 @@ public class WifiManager { * This function is used instead of a enableNetwork(), saveConfiguration() and * reconnect() * - * @param c is the channel created at {@link #initialize} * @param networkId the network id identifiying the network in the * supplicant configuration list * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void connect(Channel c, int networkId, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void connect(int networkId, ActionListener listener) { if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - - c.mAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, c.putListener(listener)); + validateChannel(); + mAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); } /** @@ -1387,17 +1383,17 @@ public class WifiManager { * For an existing network, it accomplishes the task of updateNetwork() * and saveConfiguration() * - * @param c is the channel created at {@link #initialize} * @param config the set of variables that describe the configuration, * contained in a {@link WifiConfiguration} object. * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void save(Channel c, WifiConfiguration config, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void save(WifiConfiguration config, ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - - c.mAsyncChannel.sendMessage(SAVE_NETWORK, 0, c.putListener(listener), config); + validateChannel(); + mAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config); } /** @@ -1406,64 +1402,62 @@ public class WifiManager { * This function is used instead of a sequence of removeNetwork() * and saveConfiguration(). * - * @param c is the channel created at {@link #initialize} * @param config the set of variables that describe the configuration, * contained in a {@link WifiConfiguration} object. * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void forget(Channel c, int netId, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void forget(int netId, ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - - c.mAsyncChannel.sendMessage(FORGET_NETWORK, netId, c.putListener(listener)); + validateChannel(); + mAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener)); } /** * Disable network * - * @param c is the channel created at {@link #initialize} * @param netId is the network Id * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void disable(Channel c, int netId, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void disable(int netId, ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - - c.mAsyncChannel.sendMessage(DISABLE_NETWORK, netId, c.putListener(listener)); + validateChannel(); + mAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener)); } /** * Start Wi-fi Protected Setup * - * @param c is the channel created at {@link #initialize} * @param config WPS configuration * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void startWps(Channel c, WpsInfo config, WpsListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void startWps(WpsInfo config, WpsListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - - c.mAsyncChannel.sendMessage(START_WPS, 0, c.putListener(listener), config); + validateChannel(); + mAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config); } /** * Cancel any ongoing Wi-fi Protected Setup * - * @param c is the channel created at {@link #initialize} * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void cancelWps(Channel c, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); - - c.mAsyncChannel.sendMessage(CANCEL_WPS, 0, c.putListener(listener)); + public void cancelWps(ActionListener listener) { + validateChannel(); + mAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener)); } - - /** * Get a reference to WifiService handler. This is used by a client to establish * an AsyncChannel communication with WifiService @@ -1492,8 +1486,6 @@ public class WifiManager { } } - - /** * Returns the file in which IP and proxy configuration data is stored * @hide |