diff --git a/README.md b/README.md new file mode 100644 index 0000000000000..d7627c7c0bc69 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +android_frameworks_base +======================= + +Android base frameworks (cyanogenmod) by Sarbyn diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 2d6e1d6c81f5d..3587f48d429b5 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -59,6 +59,10 @@ + + + + - + + + + diff --git a/packages/SystemUI/res/menu/recent_popup_menu.xml b/packages/SystemUI/res/menu/recent_popup_menu.xml index eecfb9ab7fbe9..c1a8ae4753c72 100644 --- a/packages/SystemUI/res/menu/recent_popup_menu.xml +++ b/packages/SystemUI/res/menu/recent_popup_menu.xml @@ -20,4 +20,7 @@ + + + diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 8cf53a8660b58..767d5ad24ac43 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -161,4 +161,6 @@ Tasto menu (nascondi autom.) Tasto menu (mostra sempre) Tasto menu + "Cancella dati applicazioni" + "Arresto forzato" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index b4ef23f55cf8a..61416d3d23223 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -425,4 +425,7 @@ Menu (autoHide) button Menu (alwaysShow) button Menu button + + "Wipe app data" + "Force stop" diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java index 5cbb75d19c477..06a78ad2e5b4f 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java @@ -21,8 +21,14 @@ import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.ActivityOptions; +import android.app.admin.DevicePolicyManager; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageDataObserver; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; @@ -38,6 +44,7 @@ import android.provider.Settings; import android.util.AttributeSet; import android.util.Log; +import android.util.Slog; import android.view.Display; import android.view.KeyEvent; import android.view.IWindowManager; @@ -882,6 +889,36 @@ public void handleLongPress( new PopupMenu(mContext, anchorView == null ? selectedView : anchorView); mPopup = popup; popup.getMenuInflater().inflate(R.menu.recent_popup_menu, popup.getMenu()); + + final ContentResolver cr = mContext.getContentResolver(); + if(Settings.Secure.getInt(cr, + Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 0) == 0) { + popup.getMenu().findItem(R.id.recent_force_stop).setVisible(false); + popup.getMenu().findItem(R.id.recent_wipe_app).setVisible(false); + } else { + ViewHolder viewHolder = (ViewHolder) selectedView.getTag(); + if (viewHolder != null) { + final TaskDescription ad = viewHolder.taskDescription; + try { + PackageManager pm = (PackageManager) mContext.getPackageManager(); + ApplicationInfo mAppInfo = pm.getApplicationInfo(ad.packageName, 0); + DevicePolicyManager mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); + + if ((mAppInfo.flags&(ApplicationInfo.FLAG_SYSTEM + | ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA)) + == ApplicationInfo.FLAG_SYSTEM + || mDpm.packageHasActiveAdmins(ad.packageName)) + popup.getMenu() + .findItem(R.id.notification_inspect_item_wipe_app).setEnabled(false); + else + Slog.d(TAG, "Not a 'special' application"); + } catch (NameNotFoundException ex) { + Slog.e(TAG, "Failed looking up ApplicationInfo for " + ad.packageName, ex); + } + } + } + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { if (item.getItemId() == R.id.recent_remove_item) { @@ -895,6 +932,28 @@ public boolean onMenuItemClick(MenuItem item) { } else { throw new IllegalStateException("Oops, no tag on view " + selectedView); } + } else if (item.getItemId() == R.id.recent_force_stop){ + ViewHolder viewHolder = (ViewHolder) selectedView.getTag(); + if (viewHolder != null) { + final TaskDescription ad = viewHolder.taskDescription; + ActivityManager am = (ActivityManager)mContext.getSystemService( + Context.ACTIVITY_SERVICE); + am.forceStopPackage(ad.packageName); + mRecentsContainer.removeViewInLayout(selectedView); + } else { + throw new IllegalStateException("Oops, no tag on view " + selectedView); + } + } else if (item.getItemId() == R.id.recent_wipe_app){ + ViewHolder viewHolder = (ViewHolder) selectedView.getTag(); + if (viewHolder != null) { + final TaskDescription ad = viewHolder.taskDescription; + ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + am.clearApplicationUserData(ad.packageName, new FakeClearUserDataObserver()); + mRecentsContainer.removeViewInLayout(selectedView); + } else { + throw new IllegalStateException("Oops, no tag on view " + selectedView); + } + } else { return false; } @@ -909,4 +968,9 @@ public void onDismiss(PopupMenu menu) { }); popup.show(); } + + class FakeClearUserDataObserver extends IPackageDataObserver.Stub { + public void onRemoveCompleted(final String packageName, final boolean succeeded) { + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 84b2322d6f112..b17a3537a8e76 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -16,15 +16,17 @@ package com.android.systemui.statusbar; -import java.util.ArrayList; - +import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.KeyguardManager; -import android.app.Notification; import android.app.PendingIntent; +import android.app.admin.DevicePolicyManager; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.content.pm.IPackageDataObserver; +import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.database.ContentObserver; import android.graphics.Rect; @@ -52,28 +54,28 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.RemoteViews; import android.widget.PopupMenu; +import android.widget.RemoteViews; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIconList; import com.android.internal.statusbar.StatusBarNotification; import com.android.internal.widget.SizeAdaptiveLayout; +import com.android.settings.applications.ApplicationsState; +import com.android.systemui.R; import com.android.systemui.SearchPanelView; import com.android.systemui.SystemUI; -import com.android.systemui.recent.RecentsPanelView; import com.android.systemui.recent.RecentTasksLoader; +import com.android.systemui.recent.RecentsPanelView; import com.android.systemui.recent.TaskDescription; -import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.policy.NotificationRowLayout; import com.android.systemui.statusbar.tablet.StatusBarPanel; -import com.android.systemui.R; +import java.util.ArrayList; public abstract class BaseStatusBar extends SystemUI implements - CommandQueue.Callbacks, RecentsPanelView.OnRecentsPanelVisibilityChangedListener { + CommandQueue.Callbacks, RecentsPanelView.OnRecentsPanelVisibilityChangedListener { static final String TAG = "StatusBar"; private static final boolean DEBUG = false; @@ -121,8 +123,8 @@ public abstract class BaseStatusBar extends SystemUI implements // UI-specific methods /** - * Create all windows necessary for the status bar (including navigation, overlay panels, etc) - * and add them to the window manager. + * Create all windows necessary for the status bar (including navigation, + * overlay panels, etc) and add them to the window manager. */ protected abstract void createAndAddWindows(); @@ -165,9 +167,12 @@ public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fil if (isActivity) { try { // The intent we are sending is for the application, which - // won't have permission to immediately start an activity after - // the user switches to home. We know it is safe to do at this - // point, so make sure new activity switches are now allowed. + // won't have permission to immediately start an activity + // after + // the user switches to home. We know it is safe to do at + // this + // point, so make sure new activity switches are now + // allowed. ActivityManagerNative.getDefault().resumeAppSwitches(); // Also, notifications can be launched from the lock screen, // so dismiss the lock screen when the activity starts. @@ -190,7 +195,7 @@ public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fil private boolean mShowNotificationCounts; public void start() { - mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)) + mDisplay = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); mProvisioningObserver.onChange(false); // set up @@ -229,14 +234,15 @@ public void start() { disable(switches[0]); setSystemUiVisibility(switches[1], 0xffffffff); topAppWindowChanged(switches[2] != 0); - // StatusBarManagerService has a back up of IME token and it's restored here. + // StatusBarManagerService has a back up of IME token and it's restored + // here. setImeWindowStatus(binders.get(0), switches[3], switches[4]); setHardKeyboardStatus(switches[5] != 0, switches[6] != 0); // Set up the initial icon state int N = iconList.size(); int viewIndex = 0; - for (int i=0; i " + notification + ")"); + if (DEBUG) + Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")"); final NotificationData.Entry oldEntry = mNotificationData.findByKey(key); if (oldEntry == null) { @@ -834,7 +905,8 @@ public void updateNotification(IBinder key, StatusBarNotification notification) final StatusBarNotification oldNotification = oldEntry.notification; - // XXX: modify when we do something more intelligent with the two content views + // XXX: modify when we do something more intelligent with the two + // content views final RemoteViews oldContentView = oldNotification.notification.contentView; final RemoteViews contentView = notification.notification.contentView; final RemoteViews oldBigContentView = oldNotification.notification.bigContentView; @@ -853,7 +925,8 @@ public void updateNotification(IBinder key, StatusBarNotification notification) + " bigContentView=" + bigContentView); } - // Can we just reapply the RemoteViews in place? If when didn't change, the order + // Can we just reapply the RemoteViews in place? If when didn't change, + // the order // didn't change. // 1U is never null @@ -865,22 +938,24 @@ public void updateNotification(IBinder key, StatusBarNotification notification) // large view may be null boolean bigContentsUnchanged = (oldEntry.getLargeView() == null && bigContentView == null) - || ((oldEntry.getLargeView() != null && bigContentView != null) - && bigContentView.getPackage() != null - && oldBigContentView.getPackage() != null - && oldBigContentView.getPackage().equals(bigContentView.getPackage()) - && oldBigContentView.getLayoutId() == bigContentView.getLayoutId()); + || ((oldEntry.getLargeView() != null && bigContentView != null) + && bigContentView.getPackage() != null + && oldBigContentView.getPackage() != null + && oldBigContentView.getPackage().equals( + bigContentView.getPackage()) + && oldBigContentView.getLayoutId() == bigContentView.getLayoutId()); ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent(); - boolean orderUnchanged = notification.notification.when==oldNotification.notification.when + boolean orderUnchanged = notification.notification.when == oldNotification.notification.when && notification.score == oldNotification.score; - // score now encompasses/supersedes isOngoing() + // score now encompasses/supersedes isOngoing() boolean updateTicker = notification.notification.tickerText != null && !TextUtils.equals(notification.notification.tickerText, oldEntry.notification.notification.tickerText); boolean isTopAnyway = isTopNotification(rowParent, oldEntry); if (contentsUnchanged && bigContentsUnchanged && (orderUnchanged || isTopAnyway)) { - if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key); + if (DEBUG) + Slog.d(TAG, "reusing notification for key: " + key); oldEntry.notification = notification; try { // Reapply the RemoteViews @@ -907,18 +982,22 @@ public void updateNotification(IBinder key, StatusBarNotification notification) return; } updateExpansionStates(); - } - catch (RuntimeException e) { - // It failed to add cleanly. Log, and remove the view from the panel. + } catch (RuntimeException e) { + // It failed to add cleanly. Log, and remove the view from the + // panel. Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); removeNotificationViews(key); addNotificationViews(key, notification); } } else { - if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key); - if (DEBUG) Slog.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed")); - if (DEBUG) Slog.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed")); - if (DEBUG) Slog.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top")); + if (DEBUG) + Slog.d(TAG, "not reusing notification for key: " + key); + if (DEBUG) + Slog.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed")); + if (DEBUG) + Slog.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed")); + if (DEBUG) + Slog.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top")); final boolean wasExpanded = oldEntry.userExpanded(); removeNotificationViews(key); addNotificationViews(key, notification); @@ -929,7 +1008,8 @@ public void updateNotification(IBinder key, StatusBarNotification notification) } } - // Update the veto button accordingly (and as a result, whether this row is + // Update the veto button accordingly (and as a result, whether this row + // is // swipe-dismissable) updateNotificationVetoButton(oldEntry.row, notification); @@ -945,27 +1025,37 @@ public void updateNotification(IBinder key, StatusBarNotification notification) // See if we need to update the intruder. if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) { - if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification); - // XXX: this is a hack for Alarms. The real implementation will need to *update* + if (DEBUG) + Slog.d(TAG, "updating the current intruder:" + notification); + // XXX: this is a hack for Alarms. The real implementation will need + // to *update* // the intruder. - if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): consistent logic with add() - if (DEBUG) Slog.d(TAG, "no longer intrudes!"); + if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): + // consistent + // logic + // with + // add() + if (DEBUG) + Slog.d(TAG, "no longer intrudes!"); mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER); } } } // Q: What kinds of notifications should show during setup? - // A: Almost none! Only things coming from the system (package is "android") that also + // A: Almost none! Only things coming from the system (package is "android") + // that also // have special "kind" tags marking them as relevant for setup (see below). protected boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) { if ("android".equals(sbn.pkg)) { if (sbn.notification.kind != null) { for (String aKind : sbn.notification.kind) { // IME switcher, created by InputMethodManagerService - if ("android.system.imeswitcher".equals(aKind)) return true; + if ("android.system.imeswitcher".equals(aKind)) + return true; // OTA availability & errors, created by SystemUpdateService - if ("android.system.update".equals(aKind)) return true; + if ("android.system.update".equals(aKind)) + return true; } } }