diff options
| -rw-r--r-- | Android.mk | 1 | ||||
| -rw-r--r-- | core/java/android/app/AppOpsManager.java | 46 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 8 | ||||
| -rw-r--r-- | core/java/android/view/WindowManagerPolicy.java | 6 | ||||
| -rw-r--r-- | core/java/com/android/internal/app/IAppOpsCallback.aidl | 21 | ||||
| -rw-r--r-- | core/java/com/android/internal/app/IAppOpsService.aidl | 5 | ||||
| -rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindowManager.java | 8 | ||||
| -rw-r--r-- | services/java/com/android/server/AppOpsService.java | 117 | ||||
| -rw-r--r-- | services/java/com/android/server/LocationManagerService.java | 21 | ||||
| -rw-r--r-- | services/java/com/android/server/VibratorService.java | 2 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/WindowManagerService.java | 15 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/WindowState.java | 25 |
12 files changed, 253 insertions, 22 deletions
diff --git a/Android.mk b/Android.mk index dd155be7003a..af3b37ef887f 100644 --- a/Android.mk +++ b/Android.mk @@ -166,6 +166,7 @@ LOCAL_SRC_FILES += \ core/java/android/speech/IRecognitionService.aidl \ core/java/android/speech/tts/ITextToSpeechCallback.aidl \ core/java/android/speech/tts/ITextToSpeechService.aidl \ + core/java/com/android/internal/app/IAppOpsCallback.aidl \ core/java/com/android/internal/app/IAppOpsService.aidl \ core/java/com/android/internal/app/IBatteryStats.aidl \ core/java/com/android/internal/app/IUsageStats.aidl \ diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index b92b9cea0341..241a9ae07666 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -16,10 +16,11 @@ package android.app; -import android.Manifest; import com.android.internal.app.IAppOpsService; +import com.android.internal.app.IAppOpsCallback; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import android.content.Context; @@ -32,6 +33,8 @@ import android.os.RemoteException; public class AppOpsManager { final Context mContext; final IAppOpsService mService; + final HashMap<Callback, IAppOpsCallback> mModeWatchers + = new HashMap<Callback, IAppOpsCallback>(); public static final int MODE_ALLOWED = 0; public static final int MODE_IGNORED = 1; @@ -62,8 +65,9 @@ public class AppOpsManager { public static final int OP_READ_ICC_SMS = 21; public static final int OP_WRITE_ICC_SMS = 22; public static final int OP_WRITE_SETTINGS = 23; + public static final int OP_SYSTEM_ALERT_WINDOW = 24; /** @hide */ - public static final int _NUM_OP = 24; + public static final int _NUM_OP = 25; /** * This maps each operation to the operation that serves as the @@ -98,6 +102,7 @@ public class AppOpsManager { OP_READ_SMS, OP_WRITE_SMS, OP_WRITE_SETTINGS, + OP_SYSTEM_ALERT_WINDOW, }; /** @@ -129,6 +134,7 @@ public class AppOpsManager { "READ_ICC_SMS", "WRITE_ICC_SMS", "WRITE_SETTINGS", + "SYSTEM_ALERT_WINDOW", }; /** @@ -160,6 +166,7 @@ public class AppOpsManager { android.Manifest.permission.READ_SMS, android.Manifest.permission.WRITE_SMS, android.Manifest.permission.WRITE_SETTINGS, + android.Manifest.permission.SYSTEM_ALERT_WINDOW, }; public static int opToSwitch(int op) { @@ -167,6 +174,7 @@ public class AppOpsManager { } public static String opToName(int op) { + if (op == OP_NONE) return "NONE"; return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")"); } @@ -305,6 +313,10 @@ public class AppOpsManager { }; } + public interface Callback { + public void opChanged(int op, String packageName); + } + public AppOpsManager(Context context, IAppOpsService service) { mContext = context; mService = service; @@ -333,6 +345,36 @@ public class AppOpsManager { } } + public void startWatchingMode(int op, String packageName, final Callback callback) { + synchronized (mModeWatchers) { + IAppOpsCallback cb = mModeWatchers.get(callback); + if (cb == null) { + cb = new IAppOpsCallback.Stub() { + public void opChanged(int op, String packageName) { + callback.opChanged(op, packageName); + } + }; + mModeWatchers.put(callback, cb); + } + try { + mService.startWatchingMode(op, packageName, cb); + } catch (RemoteException e) { + } + } + } + + public void stopWatchingMode(Callback callback) { + synchronized (mModeWatchers) { + IAppOpsCallback cb = mModeWatchers.get(callback); + if (cb != null) { + try { + mService.stopWatchingMode(cb); + } catch (RemoteException e) { + } + } + } + } + public int checkOp(int op, int uid, String packageName) { try { int mode = mService.checkOperation(op, uid, packageName); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index c3321eadd5b0..fa2f8c87c93b 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -139,6 +139,7 @@ public final class ViewRootImpl implements ViewParent, final IWindowSession mWindowSession; final Display mDisplay; + final String mBasePackageName; long mLastTrackballTime = 0; final TrackballAxis mTrackballAxisX = new TrackballAxis(); @@ -355,6 +356,7 @@ public final class ViewRootImpl implements ViewParent, // allow the spawning of threads. mWindowSession = WindowManagerGlobal.getWindowSession(context.getMainLooper()); mDisplay = display; + mBasePackageName = context.getBasePackageName(); CompatibilityInfoHolder cih = display.getCompatibilityInfo(); mCompatibilityInfo = cih != null ? cih : new CompatibilityInfoHolder(); @@ -477,6 +479,9 @@ public final class ViewRootImpl implements ViewParent, mViewLayoutDirectionInitial = mView.getRawLayoutDirection(); mFallbackEventHandler.setView(view); mWindowAttributes.copyFrom(attrs); + if (mWindowAttributes.packageName == null) { + mWindowAttributes.packageName = mBasePackageName; + } attrs = mWindowAttributes; // Keep track of the actual window flags supplied by the client. mClientWindowLayoutFlags = attrs.flags; @@ -774,6 +779,9 @@ public final class ViewRootImpl implements ViewParent, attrs.systemUiVisibility = mWindowAttributes.systemUiVisibility; attrs.subtreeSystemUiVisibility = mWindowAttributes.subtreeSystemUiVisibility; mWindowAttributesChangesFlag = mWindowAttributes.copyFrom(attrs); + if (mWindowAttributes.packageName == null) { + mWindowAttributes.packageName = mBasePackageName; + } mWindowAttributes.flags |= compatibleWindowFlag; applyKeepScreenOnFlag(mWindowAttributes); diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index bd28abc8fdc0..b5d216ab9c29 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -460,13 +460,15 @@ public interface WindowManagerPolicy { /** * Check permissions when adding a window. * - * @param attrs The window's LayoutParams. + * @param attrs The window's LayoutParams. + * @param outAppOp First element will be filled with the app op corresponding to + * this window, or OP_NONE. * * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed; * else an error code, usually * {@link WindowManagerGlobal#ADD_PERMISSION_DENIED}, to abort the add. */ - public int checkAddPermission(WindowManager.LayoutParams attrs); + public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp); /** * Check permissions when adding a window. diff --git a/core/java/com/android/internal/app/IAppOpsCallback.aidl b/core/java/com/android/internal/app/IAppOpsCallback.aidl new file mode 100644 index 000000000000..4e75a61bc03f --- /dev/null +++ b/core/java/com/android/internal/app/IAppOpsCallback.aidl @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.app; + +oneway interface IAppOpsCallback { + void opChanged(int op, String packageName); +} diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index c4f1bc4817c2..83967f60e5b1 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2013 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. @@ -17,6 +17,7 @@ package com.android.internal.app; import android.app.AppOpsManager; +import com.android.internal.app.IAppOpsCallback; interface IAppOpsService { List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops); @@ -26,4 +27,6 @@ interface IAppOpsService { int noteOperation(int code, int uid, String packageName); int startOperation(int code, int uid, String packageName); void finishOperation(int code, int uid, String packageName); + void startWatchingMode(int op, String packageName, IAppOpsCallback callback); + void stopWatchingMode(IAppOpsCallback callback); } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 8135d22d5984..9d0903cc0fd9 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -17,6 +17,7 @@ package com.android.internal.policy.impl; import android.app.ActivityManager; import android.app.ActivityManagerNative; +import android.app.AppOpsManager; import android.app.ProgressDialog; import android.app.SearchManager; import android.app.UiModeManager; @@ -1185,9 +1186,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ @Override - public int checkAddPermission(WindowManager.LayoutParams attrs) { + public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) { int type = attrs.type; - + + outAppOp[0] = AppOpsManager.OP_NONE; + if (type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW || type > WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) { return WindowManagerGlobal.ADD_OKAY; @@ -1210,6 +1213,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { case TYPE_SYSTEM_ERROR: case TYPE_SYSTEM_OVERLAY: permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW; + outAppOp[0] = AppOpsManager.OP_SYSTEM_ALERT_WINDOW; break; default: permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java index 748b3cbbac18..e94d03ccdc88 100644 --- a/services/java/com/android/server/AppOpsService.java +++ b/services/java/com/android/server/AppOpsService.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import android.app.AppOpsManager; @@ -34,7 +35,9 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.os.AsyncTask; import android.os.Binder; import android.os.Handler; +import android.os.IBinder; import android.os.Process; +import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.util.AtomicFile; @@ -45,6 +48,7 @@ import android.util.TimeUtils; import android.util.Xml; import com.android.internal.app.IAppOpsService; +import com.android.internal.app.IAppOpsCallback; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; @@ -82,7 +86,7 @@ public class AppOpsService extends IAppOpsService.Stub { final SparseArray<HashMap<String, Ops>> mUidOps = new SparseArray<HashMap<String, Ops>>(); - final static class Ops extends SparseArray<Op> { + public final static class Ops extends SparseArray<Op> { public final String packageName; public final int uid; @@ -92,7 +96,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } - final static class Op { + public final static class Op { public final int op; public int mode; public int duration; @@ -106,6 +110,34 @@ public class AppOpsService extends IAppOpsService.Stub { } } + final SparseArray<ArrayList<Callback>> mOpModeWatchers + = new SparseArray<ArrayList<Callback>>(); + final HashMap<String, ArrayList<Callback>> mPackageModeWatchers + = new HashMap<String, ArrayList<Callback>>(); + final HashMap<IBinder, Callback> mModeWatchers + = new HashMap<IBinder, Callback>(); + + public final class Callback implements DeathRecipient { + final IAppOpsCallback mCallback; + + public Callback(IAppOpsCallback callback) { + mCallback = callback; + try { + mCallback.asBinder().linkToDeath(this, 0); + } catch (RemoteException e) { + } + } + + public void unlinkToDeath() { + mCallback.asBinder().unlinkToDeath(this, 0); + } + + @Override + public void binderDied() { + stopWatchingMode(mCallback); + } + } + public AppOpsService(File storagePath) { mFile = new AtomicFile(storagePath); mHandler = new Handler(); @@ -205,15 +237,94 @@ public class AppOpsService extends IAppOpsService.Stub { public void setMode(int code, int uid, String packageName, int mode) { verifyIncomingUid(uid); verifyIncomingOp(code); + ArrayList<Callback> repCbs = null; + code = AppOpsManager.opToSwitch(code); synchronized (this) { - Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, true); + Op op = getOpLocked(code, uid, packageName, true); if (op != null) { if (op.mode != mode) { op.mode = mode; + ArrayList<Callback> cbs = mOpModeWatchers.get(code); + if (cbs != null) { + if (repCbs == null) { + repCbs = new ArrayList<Callback>(); + } + repCbs.addAll(cbs); + } + cbs = mPackageModeWatchers.get(packageName); + if (cbs != null) { + if (repCbs == null) { + repCbs = new ArrayList<Callback>(); + } + repCbs.addAll(cbs); + } scheduleWriteNowLocked(); } } } + if (repCbs != null) { + for (int i=0; i<repCbs.size(); i++) { + try { + repCbs.get(i).mCallback.opChanged(code, packageName); + } catch (RemoteException e) { + } + } + } + } + + @Override + public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) { + synchronized (this) { + op = AppOpsManager.opToSwitch(op); + Callback cb = mModeWatchers.get(callback.asBinder()); + if (cb == null) { + cb = new Callback(callback); + mModeWatchers.put(callback.asBinder(), cb); + } + if (op != AppOpsManager.OP_NONE) { + ArrayList<Callback> cbs = mOpModeWatchers.get(op); + if (cbs == null) { + cbs = new ArrayList<Callback>(); + mOpModeWatchers.put(op, cbs); + } + cbs.add(cb); + } + if (packageName != null) { + ArrayList<Callback> cbs = mPackageModeWatchers.get(packageName); + if (cbs == null) { + cbs = new ArrayList<Callback>(); + mPackageModeWatchers.put(packageName, cbs); + } + cbs.add(cb); + } + } + } + + @Override + public void stopWatchingMode(IAppOpsCallback callback) { + synchronized (this) { + Callback cb = mModeWatchers.remove(callback.asBinder()); + if (cb != null) { + cb.unlinkToDeath(); + for (int i=0; i<mOpModeWatchers.size(); i++) { + ArrayList<Callback> cbs = mOpModeWatchers.valueAt(i); + cbs.remove(cb); + if (cbs.size() <= 0) { + mOpModeWatchers.removeAt(i); + } + } + if (mPackageModeWatchers.size() > 0) { + Iterator<ArrayList<Callback>> it = mPackageModeWatchers.values().iterator(); + while (it.hasNext()) { + ArrayList<Callback> cbs = it.next(); + cbs.remove(cb); + if (cbs.size() <= 0) { + it.remove(); + } + } + } + } + } } @Override diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 62f996558bc1..78699fb10951 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -221,6 +221,16 @@ public class LocationManagerService extends ILocationManager.Stub { mBlacklist.init(); mGeofenceManager = new GeofenceManager(mContext, mBlacklist); + // Monitor for app ops mode changes. + AppOpsManager.Callback callback = new AppOpsManager.Callback() { + public void opChanged(int op, String packageName) { + synchronized (mLock) { + applyAllProviderRequirementsLocked(); + } + } + }; + mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback); + // prepare providers loadProvidersLocked(); updateProvidersLocked(); @@ -1335,6 +1345,17 @@ public class LocationManagerService extends ILocationManager.Stub { } } + private void applyAllProviderRequirementsLocked() { + for (LocationProviderInterface p : mProviders) { + // If provider is already disabled, don't need to do anything + if (!isAllowedBySettingsLocked(p.getName(), UserHandle.getUid(mCurrentUserId, 0))) { + continue; + } + + applyRequirementsLocked(p.getName()); + } + } + @Override public Location getLastLocation(LocationRequest request, String packageName) { if (D) Log.d(TAG, "getLastLocation: " + request); diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java index 9065525e74fa..21d31111c38d 100644 --- a/services/java/com/android/server/VibratorService.java +++ b/services/java/com/android/server/VibratorService.java @@ -466,7 +466,7 @@ public class VibratorService extends IVibratorService.Stub //synchronized (mInputDeviceVibrators) { // return !mInputDeviceVibrators.isEmpty() || vibratorExists(); //} - return true || vibratorExists(); + return vibratorExists(); } private void doVibratorOn(long millis, int uid) { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 1e5cd548c42b..440976213a27 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -42,6 +42,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; +import android.app.AppOpsManager; import com.android.internal.app.IBatteryStats; import com.android.internal.policy.PolicyManager; import com.android.internal.policy.impl.PhoneWindowManager; @@ -311,6 +312,8 @@ public class WindowManagerService extends IWindowManager.Stub final IBatteryStats mBatteryStats; + final AppOpsManager mAppOps; + /** * All currently active sessions with clients. */ @@ -765,6 +768,7 @@ public class WindowManagerService extends IWindowManager.Stub mActivityManager = ActivityManagerNative.getDefault(); mBatteryStats = BatteryStatsService.getService(); + mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); // Get persisted window scale setting mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(), @@ -2024,7 +2028,8 @@ public class WindowManagerService extends IWindowManager.Stub public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, InputChannel outInputChannel) { - int res = mPolicy.checkAddPermission(attrs); + int[] appOp = new int[1]; + int res = mPolicy.checkAddPermission(attrs, appOp); if (res != WindowManagerGlobal.ADD_OKAY) { return res; } @@ -2128,7 +2133,7 @@ public class WindowManagerService extends IWindowManager.Stub } win = new WindowState(this, session, client, token, - attachedWindow, seq, attrs, viewVisibility, displayContent); + attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent); if (win.mDeathRecipient == null) { // Client has apparently died, so there is no reason to // continue. @@ -2166,6 +2171,9 @@ public class WindowManagerService extends IWindowManager.Stub } win.attach(); mWindowMap.put(client.asBinder(), win); + if (win.mAppOp != AppOpsManager.OP_NONE) { + mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(), win.getOwningPackage()); + } if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) { token.appWindowToken.startingWindow = win; @@ -2376,6 +2384,9 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win); mWindowMap.remove(win.mClient.asBinder()); + if (win.mAppOp != AppOpsManager.OP_NONE) { + mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage()); + } final WindowList windows = win.getWindowList(); windows.remove(win); diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index a33595867797..6648e566d29b 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; +import android.app.AppOpsManager; import com.android.server.input.InputWindowHandle; import android.content.Context; @@ -69,6 +70,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { final Context mContext; final Session mSession; final IWindow mClient; + final int mAppOp; + // UserId and appId of the owner. Don't display windows of non-current user. + final int mOwnerUid; WindowToken mToken; WindowToken mRootToken; AppWindowToken mAppToken; @@ -270,18 +274,16 @@ final class WindowState implements WindowManagerPolicy.WindowState { DisplayContent mDisplayContent; - // UserId and appId of the owner. Don't display windows of non-current user. - int mOwnerUid; - /** When true this window can be displayed on screens owther than mOwnerUid's */ private boolean mShowToOwnerOnly; WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, - WindowState attachedWindow, int seq, WindowManager.LayoutParams a, + WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent) { mService = service; mSession = s; mClient = c; + mAppOp = appOp; mToken = token; mOwnerUid = s.mUid; mAttrs.copyFrom(a); @@ -383,7 +385,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { @Override public int getOwningUid() { - return mSession.mUid; + return mOwnerUid; } @Override @@ -1129,7 +1131,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { pw.print(" mSession="); pw.print(mSession); pw.print(" mClient="); pw.println(mClient.asBinder()); pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid); - pw.print(" mShowToOwnerOnly="); pw.println(mShowToOwnerOnly); + pw.print(" mShowToOwnerOnly="); pw.print(mShowToOwnerOnly); + pw.print(" package="); pw.print(mAttrs.packageName); + pw.print(" appop="); pw.println(AppOpsManager.opToName(mAppOp)); pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs); pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth); pw.print(" h="); pw.print(mRequestedHeight); @@ -1273,9 +1277,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { @Override public String toString() { - if (mStringNameCache == null || mLastTitle != mAttrs.getTitle() - || mWasExiting != mExiting) { - mLastTitle = mAttrs.getTitle(); + CharSequence title = mAttrs.getTitle(); + if (title == null || title.length() <= 0) { + title = mAttrs.packageName; + } + if (mStringNameCache == null || mLastTitle != title || mWasExiting != mExiting) { + mLastTitle = title; mWasExiting = mExiting; mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this)) + " u" + UserHandle.getUserId(mSession.mUid) |