diff options
Diffstat (limited to 'services/java')
9 files changed, 337 insertions, 196 deletions
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 4af6112..6e4aca7 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -514,7 +514,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { continue; } mCurrentLinkProperties[netType] = null; - if (mNetConfigs[netType].isDefault()) mNetTrackers[netType].reconnect(); + if (mNetTrackers[netType] != null && mNetConfigs[netType].isDefault()) { + mNetTrackers[netType].reconnect(); + } } IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); @@ -1595,6 +1597,7 @@ private NetworkStateTracker makeWimaxStateTracker() { if (checkType == prevNetType) continue; if (mNetConfigs[checkType] == null) continue; if (!mNetConfigs[checkType].isDefault()) continue; + if (mNetTrackers[checkType] == null) continue; // Enabling the isAvailable() optimization caused mobile to not get // selected if it was in the middle of error handling. Specifically diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 05d42ad..cd63090 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1669,7 +1669,7 @@ public final class ActivityManagerService extends ActivityManagerNative final void setFocusedActivityLocked(ActivityRecord r) { if (mFocusedActivity != r) { mFocusedActivity = r; - mWindowManager.setFocusedApp(r, true); + mWindowManager.setFocusedApp(r.appToken, true); } } @@ -2346,7 +2346,8 @@ public final class ActivityManagerService extends ActivityManagerNative // XXX we are not dealing with propagating grantedUriPermissions... // those are not yet exposed to user code, so there is no need. int res = mMainStack.startActivityLocked(r.app.thread, intent, - r.resolvedType, null, 0, aInfo, resultTo, resultWho, + r.resolvedType, null, 0, aInfo, + resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1, r.launchedFromUid, false, false, null); Binder.restoreCallingIdentity(origId); @@ -2429,10 +2430,10 @@ public final class ActivityManagerService extends ActivityManagerNative return; } final long origId = Binder.clearCallingIdentity(); - mWindowManager.setAppOrientation(r, requestedOrientation); + mWindowManager.setAppOrientation(r.appToken, requestedOrientation); Configuration config = mWindowManager.updateOrientationFromAppTokens( mConfiguration, - r.mayFreezeScreenLocked(r.app) ? r : null); + r.mayFreezeScreenLocked(r.app) ? r.appToken : null); if (config != null) { r.frozenBeforeDestroy = true; if (!updateConfigurationLocked(config, r, false)) { @@ -2449,7 +2450,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (r == null) { return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; } - return mWindowManager.getAppOrientation(r); + return mWindowManager.getAppOrientation(r.appToken); } } @@ -2515,7 +2516,7 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=0; i<activities.size(); i++) { ActivityRecord r = activities.get(i); if (!r.finishing) { - int index = mMainStack.indexOfTokenLocked(r); + int index = mMainStack.indexOfTokenLocked(r.appToken); if (index >= 0) { mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "finish-heavy"); @@ -2617,7 +2618,7 @@ public final class ActivityManagerService extends ActivityManagerNative int i; for (i=mMainStack.mHistory.size()-1; i>=0; i--) { ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); - if (r == token) { + if (r.appToken == token) { return true; } if (r.fullscreen && !r.finishing) { @@ -2705,9 +2706,9 @@ public final class ActivityManagerService extends ActivityManagerNative r.makeFinishing(); mMainStack.mHistory.remove(i); r.takeFromHistory(); - mWindowManager.removeAppToken(r); + mWindowManager.removeAppToken(r.appToken); if (VALIDATE_TOKENS) { - mWindowManager.validateAppTokens(mMainStack.mHistory); + mMainStack.validateAppTokensLocked(); } r.removeUriPermissionsLocked(); @@ -5173,10 +5174,10 @@ public final class ActivityManagerService extends ActivityManagerNative if (topThumbnail != null) { if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); try { - topThumbnail.requestThumbnail(topRecord); + topThumbnail.requestThumbnail(topRecord.appToken); } catch (Exception e) { Slog.w(TAG, "Exception thrown when requesting thumbnail", e); - sendPendingThumbnail(null, topRecord, null, null, true); + sendPendingThumbnail(null, topRecord.appToken, null, null, true); } } @@ -5547,7 +5548,7 @@ public final class ActivityManagerService extends ActivityManagerNative TaskRecord lastTask = null; for (int i=0; i<N; i++) { ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); - if (r == token) { + if (r.appToken == token) { if (!onlyRoot || lastTask != r.task) { return r.task.taskId; } @@ -5568,7 +5569,7 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=0; i<N; i++) { ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); if (r.realActivity.equals(className) - && r != token && lastTask != r.task) { + && r.appToken != token && lastTask != r.task) { if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "others")) { i--; @@ -7112,7 +7113,7 @@ public final class ActivityManagerService extends ActivityManagerNative // process, then terminate it to avoid getting in a loop. Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); - int index = mMainStack.indexOfTokenLocked(r); + int index = mMainStack.indexOfActivityLocked(r); r.stack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "crashed"); // Also terminate any activities below it that aren't yet @@ -8631,8 +8632,8 @@ public final class ActivityManagerService extends ActivityManagerNative try { TransferPipe tp = new TransferPipe(); try { - r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r, - innerPrefix, args); + r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), + r.appToken, innerPrefix, args); tp.go(fd); } finally { tp.kill(); @@ -9048,8 +9049,8 @@ public final class ActivityManagerService extends ActivityManagerNative try { TransferPipe tp = new TransferPipe(); try { - r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r, - innerPrefix, args); + r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), + r.appToken, innerPrefix, args); // Short timeout, since blocking here can // deadlock with the application. tp.go(fd, 2000); diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index 00e6cb2..951a946 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -29,6 +29,7 @@ import android.content.res.Configuration; import android.graphics.Bitmap; import android.os.Build; import android.os.Bundle; +import android.os.IBinder; import android.os.Message; import android.os.Process; import android.os.RemoteException; @@ -48,9 +49,10 @@ import java.util.HashSet; /** * An entry in the history stack, representing an activity. */ -final class ActivityRecord extends IApplicationToken.Stub { +final class ActivityRecord { final ActivityManagerService service; // owner final ActivityStack stack; // owner + final IApplicationToken.Stub appToken; // window manager token final ActivityInfo info; // all about me final int launchedFromUid; // always the uid who started the activity. final Intent intent; // the original intent that generated us @@ -200,6 +202,70 @@ final class ActivityRecord extends IApplicationToken.Stub { } } + static class Token extends IApplicationToken.Stub { + final WeakReference<ActivityRecord> weakActivity; + + Token(ActivityRecord activity) { + weakActivity = new WeakReference<ActivityRecord>(activity); + } + + @Override public void windowsDrawn() throws RemoteException { + ActivityRecord activity = weakActivity.get(); + if (activity != null) { + activity.windowsDrawn(); + } + } + + @Override public void windowsVisible() throws RemoteException { + ActivityRecord activity = weakActivity.get(); + if (activity != null) { + activity.windowsVisible(); + } + } + + @Override public void windowsGone() throws RemoteException { + ActivityRecord activity = weakActivity.get(); + if (activity != null) { + activity.windowsGone(); + } + } + + @Override public boolean keyDispatchingTimedOut() throws RemoteException { + ActivityRecord activity = weakActivity.get(); + if (activity != null) { + return activity.keyDispatchingTimedOut(); + } + return false; + } + + @Override public long getKeyDispatchingTimeout() throws RemoteException { + ActivityRecord activity = weakActivity.get(); + if (activity != null) { + return activity.getKeyDispatchingTimeout(); + } + return 0; + } + + public String toString() { + StringBuilder sb = new StringBuilder(128); + sb.append("Token{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(' '); + sb.append(weakActivity.get()); + sb.append('}'); + return sb.toString(); + } + } + + static ActivityRecord forToken(IBinder token) { + try { + return token != null ? ((Token)token).weakActivity.get() : null; + } catch (ClassCastException e) { + Slog.w(ActivityManagerService.TAG, "Bad activity token: " + token, e); + return null; + } + } + ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller, int _launchedFromUid, Intent _intent, String _resolvedType, ActivityInfo aInfo, Configuration _configuration, @@ -207,6 +273,7 @@ final class ActivityRecord extends IApplicationToken.Stub { boolean _componentSpecified) { service = _service; stack = _stack; + appToken = new Token(this); info = aInfo; launchedFromUid = _launchedFromUid; intent = _intent; @@ -445,7 +512,7 @@ final class ActivityRecord extends IApplicationToken.Stub { ar.add(intent); service.grantUriPermissionFromIntentLocked(callingUid, packageName, intent, getUriPermissionsLocked()); - app.thread.scheduleNewIntent(ar, this); + app.thread.scheduleNewIntent(ar, appToken); sent = true; } catch (RemoteException e) { Slog.w(ActivityManagerService.TAG, @@ -470,14 +537,14 @@ final class ActivityRecord extends IApplicationToken.Stub { void pauseKeyDispatchingLocked() { if (!keysPaused) { keysPaused = true; - service.mWindowManager.pauseKeyDispatching(this); + service.mWindowManager.pauseKeyDispatching(appToken); } } void resumeKeyDispatchingLocked() { if (keysPaused) { keysPaused = false; - service.mWindowManager.resumeKeyDispatching(this); + service.mWindowManager.resumeKeyDispatching(appToken); } } @@ -512,14 +579,14 @@ final class ActivityRecord extends IApplicationToken.Stub { public void startFreezingScreenLocked(ProcessRecord app, int configChanges) { if (mayFreezeScreenLocked(app)) { - service.mWindowManager.startAppFreezingScreen(this, configChanges); + service.mWindowManager.startAppFreezingScreen(appToken, configChanges); } } public void stopFreezingScreenLocked(boolean force) { if (force || frozenBeforeDestroy) { frozenBeforeDestroy = false; - service.mWindowManager.stopAppFreezingScreen(this, force); + service.mWindowManager.stopAppFreezingScreen(appToken, force); } } @@ -687,7 +754,7 @@ final class ActivityRecord extends IApplicationToken.Stub { } if (app != null && app.thread != null) { try { - app.thread.scheduleSleeping(this, _sleeping); + app.thread.scheduleSleeping(appToken, _sleeping); if (sleeping && !stack.mGoingToSleepActivities.contains(this)) { stack.mGoingToSleepActivities.add(this); } diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 8435eaa..c892cb1 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -145,7 +145,12 @@ final class ActivityStack { * running) activities. It contains HistoryRecord objects. */ final ArrayList<ActivityRecord> mHistory = new ArrayList<ActivityRecord>(); - + + /** + * Used for validating app tokens with window manager. + */ + final ArrayList<IBinder> mValidateAppTokens = new ArrayList<IBinder>(); + /** * List of running activities, sorted by recent usage. * The first entry in the list is the least recently used. @@ -294,11 +299,11 @@ final class ActivityStack { } } break; case PAUSE_TIMEOUT_MSG: { - IBinder token = (IBinder)msg.obj; + ActivityRecord r = (ActivityRecord)msg.obj; // We don't at this point know if the activity is fullscreen, // so we need to be conservative and assume it isn't. - Slog.w(TAG, "Activity pause timeout for " + token); - activityPaused(token, true); + Slog.w(TAG, "Activity pause timeout for " + r); + activityPaused(r != null ? r.appToken : null, true); } break; case IDLE_TIMEOUT_MSG: { if (mService.mDidDexOpt) { @@ -310,20 +315,20 @@ final class ActivityStack { } // We don't at this point know if the activity is fullscreen, // so we need to be conservative and assume it isn't. - IBinder token = (IBinder)msg.obj; - Slog.w(TAG, "Activity idle timeout for " + token); - activityIdleInternal(token, true, null); + ActivityRecord r = (ActivityRecord)msg.obj; + Slog.w(TAG, "Activity idle timeout for " + r); + activityIdleInternal(r != null ? r.appToken : null, true, null); } break; case DESTROY_TIMEOUT_MSG: { - IBinder token = (IBinder)msg.obj; + ActivityRecord r = (ActivityRecord)msg.obj; // We don't at this point know if the activity is fullscreen, // so we need to be conservative and assume it isn't. - Slog.w(TAG, "Activity destroy timeout for " + token); - activityDestroyed(token); + Slog.w(TAG, "Activity destroy timeout for " + r); + activityDestroyed(r != null ? r.appToken : null); } break; case IDLE_NOW_MSG: { - IBinder token = (IBinder)msg.obj; - activityIdleInternal(token, false, null); + ActivityRecord r = (ActivityRecord)msg.obj; + activityIdleInternal(r != null ? r.appToken : null, false, null); } break; case LAUNCH_TIMEOUT_MSG: { if (mService.mDidDexOpt) { @@ -397,7 +402,7 @@ final class ActivityStack { while (i >= 0) { ActivityRecord r = mHistory.get(i); // Note: the taskId check depends on real taskId fields being non-zero - if (!r.finishing && (token != r) && (taskId != r.task.taskId)) { + if (!r.finishing && (token != r.appToken) && (taskId != r.task.taskId)) { return r; } i--; @@ -406,23 +411,17 @@ final class ActivityStack { } final int indexOfTokenLocked(IBinder token) { - try { - ActivityRecord r = (ActivityRecord)token; - return mHistory.indexOf(r); - } catch (ClassCastException e) { - Slog.w(TAG, "Bad activity token: " + token, e); - return -1; - } + return mHistory.indexOf(ActivityRecord.forToken(token)); + } + + final int indexOfActivityLocked(ActivityRecord r) { + return mHistory.indexOf(r); } final ActivityRecord isInStackLocked(IBinder token) { - try { - ActivityRecord r = (ActivityRecord)token; - if (mHistory.contains(r)) { - return r; - } - } catch (ClassCastException e) { - Slog.w(TAG, "Bad activity token: " + token, e); + ActivityRecord r = ActivityRecord.forToken(token); + if (mHistory.contains(r)) { + return r; } return null; } @@ -517,7 +516,7 @@ final class ActivityStack { throws RemoteException { r.startFreezingScreenLocked(app, 0); - mService.mWindowManager.setAppVisibility(r, true); + mService.mWindowManager.setAppVisibility(r.appToken, true); // Have the window manager re-evaluate the orientation of // the screen based on the new activity order. Note that @@ -528,7 +527,7 @@ final class ActivityStack { if (checkConfig) { Configuration config = mService.mWindowManager.updateOrientationFromAppTokens( mService.mConfiguration, - r.mayFreezeScreenLocked(app) ? r : null); + r.mayFreezeScreenLocked(app) ? r.appToken : null); mService.updateConfigurationLocked(config, r, false); } @@ -590,7 +589,7 @@ final class ActivityStack { profileFd = null; } } - app.thread.scheduleLaunchActivity(new Intent(r.intent), r, + app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, mService.mConfiguration, r.compat, r.icicle, results, newIntents, !andResume, mService.isNextTransitionForward(), profileFile, profileFd, @@ -624,7 +623,7 @@ final class ActivityStack { + r.intent.getComponent().flattenToShortString() + ", giving up", e); mService.appDiedLocked(app, app.pid, app.thread); - requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, + requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash"); return false; } @@ -821,7 +820,7 @@ final class ActivityStack { } if (w > 0) { - return mService.mWindowManager.screenshotApplications(who, w, h); + return mService.mWindowManager.screenshotApplications(who.appToken, w, h); } return null; } @@ -856,8 +855,8 @@ final class ActivityStack { EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, System.identityHashCode(prev), prev.shortComponentName); - prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, - prev.configChangeFlags); + prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, + userLeaving, prev.configChangeFlags); if (mMainStack) { mService.updateUsageStats(prev, false); } @@ -1129,7 +1128,7 @@ final class ActivityStack { if (!r.visible) { if (DEBUG_VISBILITY) Slog.v( TAG, "Starting and making visible: " + r); - mService.mWindowManager.setAppVisibility(r, true); + mService.mWindowManager.setAppVisibility(r.appToken, true); } if (r != starting) { startSpecificActivityLocked(r, false, false); @@ -1153,10 +1152,10 @@ final class ActivityStack { if (DEBUG_VISBILITY) Slog.v( TAG, "Making visible and scheduling visibility: " + r); try { - mService.mWindowManager.setAppVisibility(r, true); + mService.mWindowManager.setAppVisibility(r.appToken, true); r.sleeping = false; r.app.pendingUiClean = true; - r.app.thread.scheduleWindowVisibility(r, true); + r.app.thread.scheduleWindowVisibility(r.appToken, true); r.stopFreezingScreenLocked(false); } catch (Exception e) { // Just skip on any failure; we'll make it @@ -1195,13 +1194,13 @@ final class ActivityStack { TAG, "Making invisible: " + r); r.visible = false; try { - mService.mWindowManager.setAppVisibility(r, false); + mService.mWindowManager.setAppVisibility(r.appToken, false); if ((r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED) && r.app != null && r.app.thread != null) { if (DEBUG_VISBILITY) Slog.v( TAG, "Scheduling invisibility: " + r); - r.app.thread.scheduleWindowVisibility(r, false); + r.app.thread.scheduleWindowVisibility(r.appToken, false); } } catch (Exception e) { // Just skip on any failure; we'll make it @@ -1351,7 +1350,7 @@ final class ActivityStack { // previous should actually be hidden depending on whether the // new one is found to be full-screen or not. if (prev.finishing) { - mService.mWindowManager.setAppVisibility(prev, false); + mService.mWindowManager.setAppVisibility(prev.appToken, false); if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: " + prev + ", waitingVisible=" + (prev != null ? prev.waitingVisible : null) @@ -1399,8 +1398,8 @@ final class ActivityStack { ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE : WindowManagerPolicy.TRANSIT_TASK_CLOSE, false); } - mService.mWindowManager.setAppWillBeHidden(prev); - mService.mWindowManager.setAppVisibility(prev, false); + mService.mWindowManager.setAppWillBeHidden(prev.appToken); + mService.mWindowManager.setAppVisibility(prev.appToken, false); } else { if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: prev=" + prev); @@ -1414,8 +1413,8 @@ final class ActivityStack { } } if (false) { - mService.mWindowManager.setAppWillBeHidden(prev); - mService.mWindowManager.setAppVisibility(prev, false); + mService.mWindowManager.setAppWillBeHidden(prev.appToken); + mService.mWindowManager.setAppVisibility(prev.appToken, false); } } else if (mHistory.size() > 1) { if (DEBUG_TRANSITION) Slog.v(TAG, @@ -1433,7 +1432,7 @@ final class ActivityStack { if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next); // This activity is now becoming visible. - mService.mWindowManager.setAppVisibility(next, true); + mService.mWindowManager.setAppVisibility(next.appToken, true); ActivityRecord lastResumedActivity = mResumedActivity; ActivityState lastState = next.state; @@ -1457,7 +1456,7 @@ final class ActivityStack { synchronized (mService) { Configuration config = mService.mWindowManager.updateOrientationFromAppTokens( mService.mConfiguration, - next.mayFreezeScreenLocked(next.app) ? next : null); + next.mayFreezeScreenLocked(next.app) ? next.appToken : null); if (config != null) { next.frozenBeforeDestroy = true; } @@ -1496,12 +1495,12 @@ final class ActivityStack { if (DEBUG_RESULTS) Slog.v( TAG, "Delivering results to " + next + ": " + a); - next.app.thread.scheduleSendResult(next, a); + next.app.thread.scheduleSendResult(next.appToken, a); } } if (next.newIntents != null) { - next.app.thread.scheduleNewIntent(next.newIntents, next); + next.app.thread.scheduleNewIntent(next.newIntents, next.appToken); } EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, @@ -1511,7 +1510,7 @@ final class ActivityStack { next.sleeping = false; showAskCompatModeDialogLocked(next); next.app.pendingUiClean = true; - next.app.thread.scheduleResumeActivity(next, + next.app.thread.scheduleResumeActivity(next.appToken, mService.isNextTransitionForward()); checkReadyForSleepLocked(); @@ -1528,7 +1527,7 @@ final class ActivityStack { } else { if (SHOW_APP_STARTING_PREVIEW && mMainStack) { mService.mWindowManager.setAppStartingWindow( - next, next.packageName, next.theme, + next.appToken, next.packageName, next.theme, mService.compatibilityInfoForPackageLocked( next.info.applicationInfo), next.nonLocalizedLabel, @@ -1549,7 +1548,7 @@ final class ActivityStack { // If any exception gets thrown, toss away this // activity and try the next one. Slog.w(TAG, "Exception thrown during resume of " + next, e); - requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null, + requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null, "resume-exception"); return true; } @@ -1567,7 +1566,7 @@ final class ActivityStack { } else { if (SHOW_APP_STARTING_PREVIEW) { mService.mWindowManager.setAppStartingWindow( - next, next.packageName, next.theme, + next.appToken, next.packageName, next.theme, mService.compatibilityInfoForPackageLocked( next.info.applicationInfo), next.nonLocalizedLabel, @@ -1610,10 +1609,10 @@ final class ActivityStack { } mHistory.add(addPos, r); r.putInHistory(); - mService.mWindowManager.addAppToken(addPos, r, r.task.taskId, + mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen); if (VALIDATE_TOKENS) { - mService.mWindowManager.validateAppTokens(mHistory); + validateAppTokensLocked(); } return; } @@ -1677,7 +1676,7 @@ final class ActivityStack { mNoAnimActivities.remove(r); } mService.mWindowManager.addAppToken( - addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); + addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen); boolean doShow = true; if (newTask) { // Even though this activity is starting fresh, we still need @@ -1705,19 +1704,20 @@ final class ActivityStack { else if (prev.nowVisible) prev = null; } mService.mWindowManager.setAppStartingWindow( - r, r.packageName, r.theme, + r.appToken, r.packageName, r.theme, mService.compatibilityInfoForPackageLocked( r.info.applicationInfo), r.nonLocalizedLabel, - r.labelRes, r.icon, r.windowFlags, prev, showStartingIcon); + r.labelRes, r.icon, r.windowFlags, + prev != null ? prev.appToken : null, showStartingIcon); } } else { // If this is the first activity, don't do any fancy animations, // because there is nothing for it to animate on top of. - mService.mWindowManager.addAppToken(addPos, r, r.task.taskId, + mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen); } if (VALIDATE_TOKENS) { - mService.mWindowManager.validateAppTokens(mHistory); + validateAppTokensLocked(); } if (doResume) { @@ -1725,6 +1725,15 @@ final class ActivityStack { } } + final void validateAppTokensLocked() { + mValidateAppTokens.clear(); + mValidateAppTokens.ensureCapacity(mHistory.size()); + for (int i=0; i<mHistory.size(); i++) { + mValidateAppTokens.add(mHistory.get(i).appToken); + } + mService.mWindowManager.validateAppTokens(mValidateAppTokens); + } + /** * Perform a reset of the given task, if needed as part of launching it. * Returns the new HistoryRecord at the top of the task. @@ -1826,7 +1835,7 @@ final class ActivityStack { if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target + " out to new task " + target.task); } - mService.mWindowManager.setAppGroupId(target, task.taskId); + mService.mWindowManager.setAppGroupId(target.appToken, task.taskId); if (replyChainEnd < 0) { replyChainEnd = targetI; } @@ -1849,11 +1858,11 @@ final class ActivityStack { } mHistory.remove(srcPos); mHistory.add(dstPos, p); - mService.mWindowManager.moveAppToken(dstPos, p); - mService.mWindowManager.setAppGroupId(p, p.task.taskId); + mService.mWindowManager.moveAppToken(dstPos, p.appToken); + mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId); dstPos++; if (VALIDATE_TOKENS) { - mService.mWindowManager.validateAppTokens(mHistory); + validateAppTokensLocked(); } i++; } @@ -1985,10 +1994,10 @@ final class ActivityStack { mHistory.add(lastReparentPos, p); if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p + " in to resetting task " + task); - mService.mWindowManager.moveAppToken(lastReparentPos, p); - mService.mWindowManager.setAppGroupId(p, p.task.taskId); + mService.mWindowManager.moveAppToken(lastReparentPos, p.appToken); + mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId); if (VALIDATE_TOKENS) { - mService.mWindowManager.validateAppTokens(mHistory); + validateAppTokensLocked(); } } replyChainEnd = -1; @@ -2081,7 +2090,7 @@ final class ActivityStack { if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { if (!ret.finishing) { - int index = indexOfTokenLocked(ret); + int index = indexOfTokenLocked(ret.appToken); if (index >= 0) { finishActivityLocked(ret, index, Activity.RESULT_CANCELED, null, "clear"); @@ -3007,7 +3016,7 @@ final class ActivityStack { return res; } - resultTo = outActivity[0]; + resultTo = outActivity[0] != null ? outActivity[0].appToken : null; } } } finally { @@ -3065,7 +3074,7 @@ final class ActivityStack { ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); list.add(new ResultInfo(resultWho, requestCode, resultCode, data)); - r.app.thread.scheduleSendResult(r, list); + r.app.thread.scheduleSendResult(r.appToken, list); return; } catch (Exception e) { Slog.w(TAG, "Exception thrown sending result to " + r, e); @@ -3080,7 +3089,7 @@ final class ActivityStack { if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { if (!r.finishing) { - requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, + requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "no-history"); } } else if (r.app != null && r.app.thread != null) { @@ -3098,9 +3107,9 @@ final class ActivityStack { if (DEBUG_VISBILITY) Slog.v( TAG, "Stopping visible=" + r.visible + " for " + r); if (!r.visible) { - mService.mWindowManager.setAppVisibility(r, false); + mService.mWindowManager.setAppVisibility(r.appToken, false); } - r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags); + r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags); if (mService.isSleeping()) { r.setSleeping(true); } @@ -3145,7 +3154,7 @@ final class ActivityStack { // normal flow and hide it once we determine that it is // hidden by the activities in front of it. if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); - mService.mWindowManager.setAppVisibility(s, false); + mService.mWindowManager.setAppVisibility(s.appToken, false); } } if ((!s.waitingVisible || mService.isSleeping()) && remove) { @@ -3186,14 +3195,14 @@ final class ActivityStack { boolean enableScreen = false; synchronized (mService) { - if (token != null) { - mHandler.removeMessages(IDLE_TIMEOUT_MSG, token); + ActivityRecord r = ActivityRecord.forToken(token); + if (r != null) { + mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); } // Get the activity record. - int index = indexOfTokenLocked(token); + int index = indexOfActivityLocked(r); if (index >= 0) { - ActivityRecord r = mHistory.get(index); res = r; if (fromTimeout) { @@ -3413,7 +3422,7 @@ final class ActivityStack { : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE, false); // Tell window manager to prepare for this one to be removed. - mService.mWindowManager.setAppVisibility(r, false); + mService.mWindowManager.setAppVisibility(r.appToken, false); if (mPausingActivity == null) { if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r); @@ -3440,7 +3449,7 @@ final class ActivityStack { private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode) { - final int index = indexOfTokenLocked(r); + final int index = indexOfActivityLocked(r); if (index < 0) { return null; } @@ -3570,9 +3579,9 @@ final class ActivityStack { if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (removed from history)"); r.state = ActivityState.DESTROYED; - mService.mWindowManager.removeAppToken(r); + mService.mWindowManager.removeAppToken(r.appToken); if (VALIDATE_TOKENS) { - mService.mWindowManager.validateAppTokens(mHistory); + validateAppTokensLocked(); } cleanUpActivityServicesLocked(r); r.removeUriPermissionsLocked(); @@ -3653,7 +3662,7 @@ final class ActivityStack { try { if (DEBUG_SWITCH) Slog.i(TAG, "Destroying: " + r); - r.app.thread.scheduleDestroyActivity(r, r.finishing, + r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing, r.configChangeFlags); } catch (Exception e) { // We can just ignore exceptions here... if the process @@ -3712,11 +3721,13 @@ final class ActivityStack { final void activityDestroyed(IBinder token) { synchronized (mService) { - mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token); + ActivityRecord r = ActivityRecord.forToken(token); + if (r != null) { + mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r); + } - int index = indexOfTokenLocked(token); + int index = indexOfActivityLocked(r); if (index >= 0) { - ActivityRecord r = mHistory.get(index); if (r.state == ActivityState.DESTROYING) { final long origId = Binder.clearCallingIdentity(); removeActivityFromHistoryLocked(r); @@ -3781,7 +3792,7 @@ final class ActivityStack { return; } - ArrayList moved = new ArrayList(); + ArrayList<IBinder> moved = new ArrayList<IBinder>(); // Applying the affinities may have removed entries from the history, // so get the size again. @@ -3803,7 +3814,7 @@ final class ActivityStack { } mHistory.remove(pos); mHistory.add(top, r); - moved.add(0, r); + moved.add(0, r.appToken); top--; } pos--; @@ -3826,7 +3837,7 @@ final class ActivityStack { mService.mWindowManager.moveAppTokensToTop(moved); if (VALIDATE_TOKENS) { - mService.mWindowManager.validateAppTokens(mHistory); + validateAppTokensLocked(); } finishTaskMoveLocked(task); @@ -3873,7 +3884,7 @@ final class ActivityStack { } } - ArrayList moved = new ArrayList(); + ArrayList<IBinder> moved = new ArrayList<IBinder>(); if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to back transition: task=" + task); @@ -3898,7 +3909,7 @@ final class ActivityStack { } mHistory.remove(pos); mHistory.add(bottom, r); - moved.add(r); + moved.add(r.appToken); bottom++; } pos++; @@ -3918,7 +3929,7 @@ final class ActivityStack { } mService.mWindowManager.moveAppTokensToBottom(moved); if (VALIDATE_TOKENS) { - mService.mWindowManager.validateAppTokens(mHistory); + validateAppTokensLocked(); } finishTaskMoveLocked(task); @@ -4148,7 +4159,7 @@ final class ActivityStack { if (r.app != null && r.app.thread != null) { try { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + r); - r.app.thread.scheduleActivityConfigurationChanged(r); + r.app.thread.scheduleActivityConfigurationChanged(r.appToken); } catch (RemoteException e) { // If process died, whatever. } @@ -4178,7 +4189,7 @@ final class ActivityStack { try { if (DEBUG_SWITCH) Slog.i(TAG, "Switch is restarting resumed " + r); r.forceNewConfig = false; - r.app.thread.scheduleRelaunchActivity(r, results, newIntents, + r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes, !andResume, mService.mConfiguration); // Note: don't need to call pauseIfSleepingLocked() here, because // the caller will only pass in 'andResume' if this activity is diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 423a78f..c344bc6 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -73,7 +73,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { private Context mContext; private final static String TAG = "Tethering"; private final static boolean DBG = true; - private final static boolean VDBG = true; + private final static boolean VDBG = false; // TODO - remove both of these - should be part of interface inspection/selection stuff private String[] mTetherableUsbRegexs; @@ -228,7 +228,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { if (isUsb(iface)) { // ignore usb0 down after enabling RNDIS // we will handle disconnect in interfaceRemoved instead - if (VDBG) Log.d(TAG, "ignoring interface down for " + iface); + if (VDBG) Log.d(TAG, "ignore interface down for " + iface); } else if (sm != null) { sm.sendMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN); mIfaces.remove(iface); @@ -298,7 +298,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mIfaces.put(iface, sm); sm.start(); } - if (VDBG) Log.d(TAG, "interfaceAdded :" + iface); } public void interfaceRemoved(String iface) { @@ -415,7 +414,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER, erroredList); mContext.sendStickyBroadcast(broadcast); - if (VDBG) { + if (DBG) { Log.d(TAG, "sendTetherStateChangedBroadcast " + availableList.size() + ", " + activeList.size() + ", " + erroredList.size()); } @@ -865,7 +864,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { @Override public boolean processMessage(Message message) { - if (VDBG) Log.d(TAG, "InitialState.processMessage what=" + message.what); + if (DBG) Log.d(TAG, "InitialState.processMessage what=" + message.what); boolean retValue = true; switch (message.what) { case CMD_TETHER_REQUESTED: @@ -906,7 +905,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } @Override public boolean processMessage(Message message) { - if (VDBG) Log.d(TAG, "StartingState.processMessage what=" + message.what); + if (DBG) Log.d(TAG, "StartingState.processMessage what=" + message.what); boolean retValue = true; switch (message.what) { // maybe a parent class? @@ -985,7 +984,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { @Override public boolean processMessage(Message message) { - if (VDBG) Log.d(TAG, "TetheredState.processMessage what=" + message.what); + if (DBG) Log.d(TAG, "TetheredState.processMessage what=" + message.what); boolean retValue = true; boolean error = false; switch (message.what) { @@ -1061,7 +1060,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { ConnectivityManager.TETHER_ERROR_MASTER_ERROR); break; } - if (VDBG) Log.d(TAG, "Tether lost upstream connection " + mIfaceName); + if (DBG) Log.d(TAG, "Tether lost upstream connection " + mIfaceName); sendTetherStateChangedBroadcast(); if (mUsb) { if (!Tethering.this.configureUsbIface(false)) { @@ -1296,7 +1295,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } } - if (VDBG) { + if (DBG) { Log.d(TAG, "chooseUpstreamType(" + tryCell + "), preferredApn =" + mPreferredUpstreamMobileApn + ", got type=" + upType); } @@ -1328,7 +1327,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } protected void notifyTetheredOfNewUpstreamIface(String ifaceName) { - if (VDBG) Log.d(TAG, "notifying tethered with iface =" + ifaceName); + if (DBG) Log.d(TAG, "notifying tethered with iface =" + ifaceName); mUpstreamIfaceName = ifaceName; for (Object o : mNotifyList) { TetherInterfaceSM sm = (TetherInterfaceSM)o; @@ -1344,7 +1343,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } @Override public boolean processMessage(Message message) { - if (VDBG) Log.d(TAG, "MasterInitialState.processMessage what=" + message.what); + if (DBG) Log.d(TAG, "MasterInitialState.processMessage what=" + message.what); boolean retValue = true; switch (message.what) { case CMD_TETHER_MODE_REQUESTED: @@ -1386,7 +1385,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } @Override public boolean processMessage(Message message) { - if (VDBG) Log.d(TAG, "TetherModeAliveState.processMessage what=" + message.what); + if (DBG) Log.d(TAG, "TetherModeAliveState.processMessage what=" + message.what); boolean retValue = true; switch (message.what) { case CMD_TETHER_MODE_REQUESTED: diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index 77b0d96..6365525 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -806,9 +806,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final NetworkStats networkDevSnapshot; try { // collect any tethering stats - final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs(); - final NetworkStats tetherSnapshot = mNetworkManager.getNetworkStatsTethering( - tetheredIfacePairs); + final NetworkStats tetherSnapshot = getNetworkStatsTethering(); // record uid stats, folding in tethering stats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL); @@ -1505,7 +1503,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { NetworkStats before, NetworkStats current, boolean collectStale, String type) { if (before != null) { try { - return current.subtract(before); + return current.subtract(before, false); } catch (NonMonotonicException e) { Log.w(TAG, "found non-monotonic values; saving to dropbox"); @@ -1517,8 +1515,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { builder.append("right=").append(e.right).append('\n'); mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString()); - // return empty delta to avoid recording broken stats - return new NetworkStats(0L, 10); + try { + // return clamped delta to help recover + return current.subtract(before, true); + } catch (NonMonotonicException e1) { + Log.wtf(TAG, "found non-monotonic values; returning empty delta", e1); + return new NetworkStats(0L, 10); + } } } else if (collectStale) { // caller is okay collecting stale stats for first call. @@ -1530,6 +1533,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } + /** + * Return snapshot of current tethering statistics. Will return empty + * {@link NetworkStats} if any problems are encountered. + */ + private NetworkStats getNetworkStatsTethering() throws RemoteException { + try { + final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs(); + return mNetworkManager.getNetworkStatsTethering(tetheredIfacePairs); + } catch (IllegalStateException e) { + Log.wtf(TAG, "problem reading network stats", e); + return new NetworkStats(0L, 10); + } + } + private static NetworkStats computeNetworkXtSnapshotFromUid(NetworkStats uidSnapshot) { return uidSnapshot.groupedByIface(); } diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java index bfe6613..36442a0 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/java/com/android/server/pm/Settings.java @@ -63,6 +63,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import libcore.io.IoUtils; + /** * Holds information about dynamic settings. */ @@ -998,8 +1000,8 @@ final class Settings { FileUtils.sync(fstr); str.close(); journal.commit(); - } - catch (Exception e) { + } catch (Exception e) { + IoUtils.closeQuietly(str); journal.rollback(); } diff --git a/services/java/com/android/server/wm/InputManager.java b/services/java/com/android/server/wm/InputManager.java index df7e0e1..a4f0a0c 100644 --- a/services/java/com/android/server/wm/InputManager.java +++ b/services/java/com/android/server/wm/InputManager.java @@ -675,7 +675,13 @@ public class InputManager implements Watchdog.Monitor { } catch (NumberFormatException e) { } if (result < 1) { - result = 55; + // This number equates to the refresh rate * 1.5. The rate should be at least + // equal to the screen refresh rate. We increase the rate by 50% to compensate for + // the discontinuity between the actual rate that events come in at (they do + // not necessarily come in constantly and are not handled synchronously). + // Ideally, we would use Display.getRefreshRate(), but as this does not necessarily + // return a sensible result, we use '60' as our default assumed refresh rate. + result = 90; } return result; } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 8ed7966..50321b3 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -3070,7 +3070,7 @@ public class WindowManagerService extends IWindowManager.Stub // Application Window Tokens // ------------------------------------------------------------- - public void validateAppTokens(List tokens) { + public void validateAppTokens(List<IBinder> tokens) { int v = tokens.size()-1; int m = mAppTokens.size()-1; while (v >= 0 && m >= 0) { @@ -5809,7 +5809,87 @@ public class WindowManagerService extends IWindowManager.Stub return curSize; } - private int computeSmallestWidth(boolean rotated, int dw, int dh, float density) { + private int reduceConfigLayout(int curLayout, int rotation, float density, + int dw, int dh) { + // Get the app screen size at this rotation. + int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation); + int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation); + + // Compute the screen layout size class for this rotation. + int screenLayoutSize; + boolean screenLayoutLong; + boolean screenLayoutCompatNeeded; + int longSize = w; + int shortSize = h; + if (longSize < shortSize) { + int tmp = longSize; + longSize = shortSize; + shortSize = tmp; + } + longSize = (int)(longSize/density); + shortSize = (int)(shortSize/density); + + // These semi-magic numbers define our compatibility modes for + // applications with different screens. These are guarantees to + // app developers about the space they can expect for a particular + // configuration. DO NOT CHANGE! + if (longSize < 470) { + // This is shorter than an HVGA normal density screen (which + // is 480 pixels on its long side). + screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_SMALL; + screenLayoutLong = false; + screenLayoutCompatNeeded = false; + } else { + // What size is this screen screen? + if (longSize >= 960 && shortSize >= 720) { + // 1.5xVGA or larger screens at medium density are the point + // at which we consider it to be an extra large screen. + screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_XLARGE; + } else if (longSize >= 640 && shortSize >= 480) { + // VGA or larger screens at medium density are the point + // at which we consider it to be a large screen. + screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_LARGE; + } else { + screenLayoutSize = Configuration.SCREENLAYOUT_SIZE_NORMAL; + } + + // If this screen is wider than normal HVGA, or taller + // than FWVGA, then for old apps we want to run in size + // compatibility mode. + if (shortSize > 321 || longSize > 570) { + screenLayoutCompatNeeded = true; + } else { + screenLayoutCompatNeeded = false; + } + + // Is this a long screen? + if (((longSize*3)/5) >= (shortSize-1)) { + // Anything wider than WVGA (5:3) is considering to be long. + screenLayoutLong = true; + } else { + screenLayoutLong = false; + } + } + + // Now reduce the last screenLayout to not be better than what we + // have found. + if (!screenLayoutLong) { + curLayout = (curLayout&~Configuration.SCREENLAYOUT_LONG_MASK) + | Configuration.SCREENLAYOUT_LONG_NO; + } + if (screenLayoutCompatNeeded) { + curLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED; + } + int curSize = curLayout&Configuration.SCREENLAYOUT_SIZE_MASK; + if (screenLayoutSize < curSize) { + curLayout = (curLayout&~Configuration.SCREENLAYOUT_SIZE_MASK) + | screenLayoutSize; + } + return curLayout; + } + + private void computeSmallestWidthAndScreenLayout(boolean rotated, int dw, int dh, + float density, Configuration outConfig) { // We need to determine the smallest width that will occur under normal // operation. To this, start with the base screen size and compute the // width under the different possible rotations. We need to un-rotate @@ -5826,7 +5906,14 @@ public class WindowManagerService extends IWindowManager.Stub sw = reduceConfigWidthSize(sw, Surface.ROTATION_90, density, unrotDh, unrotDw); sw = reduceConfigWidthSize(sw, Surface.ROTATION_180, density, unrotDw, unrotDh); sw = reduceConfigWidthSize(sw, Surface.ROTATION_270, density, unrotDh, unrotDw); - return sw; + int sl = Configuration.SCREENLAYOUT_SIZE_XLARGE + | Configuration.SCREENLAYOUT_LONG_YES; + sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh); + 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 = sw; + outConfig.screenLayout = sl; } private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm, @@ -5924,64 +6011,12 @@ public class WindowManagerService extends IWindowManager.Stub / dm.density); config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation) / dm.density); - config.smallestScreenWidthDp = computeSmallestWidth(rotated, dw, dh, dm.density); + computeSmallestWidthAndScreenLayout(rotated, dw, dh, dm.density, config); config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale); config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale); config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh); - // Compute the screen layout size class. - int screenLayout; - int longSize = mAppDisplayWidth; - int shortSize = mAppDisplayHeight; - if (longSize < shortSize) { - int tmp = longSize; - longSize = shortSize; - shortSize = tmp; - } - longSize = (int)(longSize/dm.density); - shortSize = (int)(shortSize/dm.density); - - // These semi-magic numbers define our compatibility modes for - // applications with different screens. These are guarantees to - // app developers about the space they can expect for a particular - // configuration. DO NOT CHANGE! - if (longSize < 470) { - // This is shorter than an HVGA normal density screen (which - // is 480 pixels on its long side). - screenLayout = Configuration.SCREENLAYOUT_SIZE_SMALL - | Configuration.SCREENLAYOUT_LONG_NO; - } else { - // What size is this screen screen? - if (longSize >= 960 && shortSize >= 720) { - // 1.5xVGA or larger screens at medium density are the point - // at which we consider it to be an extra large screen. - screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE; - } else if (longSize >= 640 && shortSize >= 480) { - // VGA or larger screens at medium density are the point - // at which we consider it to be a large screen. - screenLayout = Configuration.SCREENLAYOUT_SIZE_LARGE; - } else { - screenLayout = Configuration.SCREENLAYOUT_SIZE_NORMAL; - } - - // If this screen is wider than normal HVGA, or taller - // than FWVGA, then for old apps we want to run in size - // compatibility mode. - if (shortSize > 321 || longSize > 570) { - screenLayout |= Configuration.SCREENLAYOUT_COMPAT_NEEDED; - } - - // Is this a long screen? - if (((longSize*3)/5) >= (shortSize-1)) { - // Anything wider than WVGA (5:3) is considering to be long. - screenLayout |= Configuration.SCREENLAYOUT_LONG_YES; - } else { - screenLayout |= Configuration.SCREENLAYOUT_LONG_NO; - } - } - config.screenLayout = screenLayout; - // Determine whether a hard keyboard is available and enabled. boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS; if (hardKeyboardAvailable != mHardKeyboardAvailable) { |
