Loading core/java/android/os/DropBoxManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,8 @@ public class DropBoxManager { /** * Broadcast Action: This is broadcast when a new entry is added in the dropbox. * You must hold the {@link android.Manifest.permission#READ_LOGS} permission * in order to receive this broadcast. * in order to receive this broadcast. This broadcast can be rate limited for low priority * entries * * <p class="note">This is a protected intent that can only be sent * by the system. Loading core/res/res/values/config.xml +15 −0 Original line number Diff line number Diff line Loading @@ -3978,4 +3978,19 @@ <!-- Whether or not to enable automatic heap dumps for the system server on debuggable builds. --> <bool name="config_debugEnableAutomaticSystemServerHeapDumps">false</bool> <!-- See DropBoxManagerService. The minimum period in milliseconds between broadcasts for entries with low priority dropbox tags. --> <integer name="config_dropboxLowPriorityBroadcastRateLimitPeriod">2000</integer> <!-- See DropBoxManagerService. An array of dropbox entry tags to marked as low priority. Low priority broadcasts will be rated limited to a period defined by config_dropboxLowPriorityBroadcastRateLimitPeriod (high frequency broadcasts for the tag will be dropped) --> <string-array name="config_dropboxLowPriorityTags" translatable="false"> <item>keymaster</item> <item>system_server_strictmode</item> </string-array> </resources> core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -3730,4 +3730,7 @@ <java-symbol type="dimen" name="resolver_icon_size"/> <java-symbol type="dimen" name="resolver_badge_size"/> <!-- For DropBox --> <java-symbol type="integer" name="config_dropboxLowPriorityBroadcastRateLimitPeriod" /> <java-symbol type="array" name="config_dropboxLowPriorityTags" /> </resources> services/core/java/com/android/server/DropBoxManagerService.java +191 −20 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; Loading @@ -32,6 +33,9 @@ import android.os.FileUtils; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.ShellCommand; import android.os.StatFs; import android.os.SystemClock; import android.os.UserHandle; Loading @@ -39,8 +43,11 @@ import android.provider.Settings; import android.text.TextUtils; import android.text.format.Time; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IDropBoxManagerService; import com.android.internal.util.DumpUtils; Loading Loading @@ -76,9 +83,6 @@ public final class DropBoxManagerService extends SystemService { private static final int DEFAULT_RESERVE_PERCENT = 10; private static final int QUOTA_RESCAN_MILLIS = 5000; // mHandler 'what' value. private static final int MSG_SEND_BROADCAST = 1; private static final boolean PROFILE_DUMP = false; // TODO: This implementation currently uses one file per entry, which is Loading @@ -95,6 +99,9 @@ public final class DropBoxManagerService extends SystemService { private FileList mAllFiles = null; private ArrayMap<String, FileList> mFilesByTag = null; private long mLowPriorityRateLimitPeriod = 0; private ArraySet<String> mLowPriorityTags = null; // Various bits of disk information private StatFs mStatFs = null; Loading @@ -105,7 +112,7 @@ public final class DropBoxManagerService extends SystemService { private volatile boolean mBooted = false; // Provide a way to perform sendBroadcast asynchronously to avoid deadlocks. private final Handler mHandler; private final DropBoxManagerBroadcastHandler mHandler; private int mMaxFiles = -1; // -1 means uninitialized. Loading Loading @@ -152,8 +159,142 @@ public final class DropBoxManagerService extends SystemService { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { DropBoxManagerService.this.dump(fd, pw, args); } @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver); } }; private class ShellCmd extends ShellCommand { @Override public int onCommand(String cmd) { if (cmd == null) { return handleDefaultCommands(cmd); } final PrintWriter pw = getOutPrintWriter(); try { switch (cmd) { case "set-rate-limit": final long period = Long.parseLong(getNextArgRequired()); DropBoxManagerService.this.setLowPriorityRateLimit(period); break; case "add-low-priority": final String addedTag = getNextArgRequired(); DropBoxManagerService.this.addLowPriorityTag(addedTag); break; case "remove-low-priority": final String removeTag = getNextArgRequired(); DropBoxManagerService.this.removeLowPriorityTag(removeTag); break; case "restore-defaults": DropBoxManagerService.this.restoreDefaults(); break; default: return handleDefaultCommands(cmd); } } catch (Exception e) { pw.println(e); } return 0; } @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); pw.println("Dropbox manager service commands:"); pw.println(" help"); pw.println(" Print this help text."); pw.println(" set-rate-limit PERIOD"); pw.println(" Sets low priority broadcast rate limit period to PERIOD ms"); pw.println(" add-low-priority TAG"); pw.println(" Add TAG to dropbox low priority list"); pw.println(" remove-low-priority TAG"); pw.println(" Remove TAG from dropbox low priority list"); pw.println(" restore-defaults"); pw.println(" restore dropbox settings to defaults"); } } private class DropBoxManagerBroadcastHandler extends Handler { private final Object mLock = new Object(); static final int MSG_SEND_BROADCAST = 1; static final int MSG_SEND_DEFERRED_BROADCAST = 2; @GuardedBy("mLock") private final ArrayMap<String, Intent> mDeferredMap = new ArrayMap(); DropBoxManagerBroadcastHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SEND_BROADCAST: prepareAndSendBroadcast((Intent) msg.obj); break; case MSG_SEND_DEFERRED_BROADCAST: Intent deferredIntent; synchronized (mLock) { deferredIntent = mDeferredMap.remove((String) msg.obj); } if (deferredIntent != null) { prepareAndSendBroadcast(deferredIntent); } break; } } private void prepareAndSendBroadcast(Intent intent) { if (!DropBoxManagerService.this.mBooted) { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM, android.Manifest.permission.READ_LOGS); } private Intent createIntent(String tag, long time) { final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED); dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag); dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time); return dropboxIntent; } /** * Schedule a dropbox broadcast to be sent asynchronously. */ public void sendBroadcast(String tag, long time) { sendMessage(obtainMessage(MSG_SEND_BROADCAST, createIntent(tag, time))); } /** * Possibly schedule a delayed dropbox broadcast. The broadcast will only be scheduled if * no broadcast is currently scheduled. Otherwise updated the scheduled broadcast with the * new intent information, effectively dropping the previous broadcast. */ public void maybeDeferBroadcast(String tag, long time) { synchronized (mLock) { final Intent intent = mDeferredMap.get(tag); if (intent == null) { // Schedule new delayed broadcast. mDeferredMap.put(tag, createIntent(tag, time)); sendMessageDelayed(obtainMessage(MSG_SEND_DEFERRED_BROADCAST, tag), mLowPriorityRateLimitPeriod); } else { // Broadcast is already scheduled. Update intent with new data. intent.putExtra(DropBoxManager.EXTRA_TIME, time); final int dropped = intent.getIntExtra(DropBoxManager.EXTRA_DROPPED_COUNT, 0); intent.putExtra(DropBoxManager.EXTRA_DROPPED_COUNT, dropped + 1); return; } } } } /** * Creates an instance of managed drop box storage using the default dropbox * directory. Loading @@ -176,15 +317,7 @@ public final class DropBoxManagerService extends SystemService { super(context); mDropBoxDir = path; mContentResolver = getContext().getContentResolver(); mHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { if (msg.what == MSG_SEND_BROADCAST) { getContext().sendBroadcastAsUser((Intent)msg.obj, UserHandle.SYSTEM, android.Manifest.permission.READ_LOGS); } } }; mHandler = new DropBoxManagerBroadcastHandler(looper); } @Override Loading @@ -211,6 +344,8 @@ public final class DropBoxManagerService extends SystemService { mReceiver.onReceive(getContext(), (Intent) null); } }); getLowPriorityResourceConfigs(); break; case PHASE_BOOT_COMPLETED: Loading Loading @@ -298,17 +433,16 @@ public final class DropBoxManagerService extends SystemService { long time = createEntry(temp, tag, flags); temp = null; final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED); dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag); dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time); if (!mBooted) { dropboxIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } // Call sendBroadcast after returning from this call to avoid deadlock. In particular // the caller may be holding the WindowManagerService lock but sendBroadcast requires a // lock in ActivityManagerService. ActivityManagerService has been caught holding that // very lock while waiting for the WindowManagerService lock. mHandler.sendMessage(mHandler.obtainMessage(MSG_SEND_BROADCAST, dropboxIntent)); if (mLowPriorityTags != null && mLowPriorityTags.contains(tag)) { // Rate limit low priority Dropbox entries mHandler.maybeDeferBroadcast(tag, time); } else { mHandler.sendBroadcast(tag, time); } } catch (IOException e) { Slog.e(TAG, "Can't write: " + tag, e); } finally { Loading Loading @@ -382,6 +516,22 @@ public final class DropBoxManagerService extends SystemService { return null; } private synchronized void setLowPriorityRateLimit(long period) { mLowPriorityRateLimitPeriod = period; } private synchronized void addLowPriorityTag(String tag) { mLowPriorityTags.add(tag); } private synchronized void removeLowPriorityTag(String tag) { mLowPriorityTags.remove(tag); } private synchronized void restoreDefaults() { getLowPriorityResourceConfigs(); } public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; Loading Loading @@ -421,6 +571,10 @@ public final class DropBoxManagerService extends SystemService { out.append("Drop box contents: ").append(mAllFiles.contents.size()).append(" entries\n"); out.append("Max entries: ").append(mMaxFiles).append("\n"); out.append("Low priority rate limit period: "); out.append(mLowPriorityRateLimitPeriod).append(" ms\n"); out.append("Low priority tags: ").append(mLowPriorityTags).append("\n"); if (!searchArgs.isEmpty()) { out.append("Searching for:"); for (String a : searchArgs) out.append(" ").append(a); Loading Loading @@ -936,4 +1090,21 @@ public final class DropBoxManagerService extends SystemService { return mCachedQuotaBlocks * mBlockSize; } private void getLowPriorityResourceConfigs() { mLowPriorityRateLimitPeriod = Resources.getSystem().getInteger( R.integer.config_dropboxLowPriorityBroadcastRateLimitPeriod); final String[] lowPrioritytags = Resources.getSystem().getStringArray( R.array.config_dropboxLowPriorityTags); final int size = lowPrioritytags.length; if (size == 0) { mLowPriorityTags = null; return; } mLowPriorityTags = new ArraySet(size); for (int i = 0; i < size; i++) { mLowPriorityTags.add(lowPrioritytags[i]); } } } Loading
core/java/android/os/DropBoxManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,8 @@ public class DropBoxManager { /** * Broadcast Action: This is broadcast when a new entry is added in the dropbox. * You must hold the {@link android.Manifest.permission#READ_LOGS} permission * in order to receive this broadcast. * in order to receive this broadcast. This broadcast can be rate limited for low priority * entries * * <p class="note">This is a protected intent that can only be sent * by the system. Loading
core/res/res/values/config.xml +15 −0 Original line number Diff line number Diff line Loading @@ -3978,4 +3978,19 @@ <!-- Whether or not to enable automatic heap dumps for the system server on debuggable builds. --> <bool name="config_debugEnableAutomaticSystemServerHeapDumps">false</bool> <!-- See DropBoxManagerService. The minimum period in milliseconds between broadcasts for entries with low priority dropbox tags. --> <integer name="config_dropboxLowPriorityBroadcastRateLimitPeriod">2000</integer> <!-- See DropBoxManagerService. An array of dropbox entry tags to marked as low priority. Low priority broadcasts will be rated limited to a period defined by config_dropboxLowPriorityBroadcastRateLimitPeriod (high frequency broadcasts for the tag will be dropped) --> <string-array name="config_dropboxLowPriorityTags" translatable="false"> <item>keymaster</item> <item>system_server_strictmode</item> </string-array> </resources>
core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -3730,4 +3730,7 @@ <java-symbol type="dimen" name="resolver_icon_size"/> <java-symbol type="dimen" name="resolver_badge_size"/> <!-- For DropBox --> <java-symbol type="integer" name="config_dropboxLowPriorityBroadcastRateLimitPeriod" /> <java-symbol type="array" name="config_dropboxLowPriorityTags" /> </resources>
services/core/java/com/android/server/DropBoxManagerService.java +191 −20 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; Loading @@ -32,6 +33,9 @@ import android.os.FileUtils; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.ShellCommand; import android.os.StatFs; import android.os.SystemClock; import android.os.UserHandle; Loading @@ -39,8 +43,11 @@ import android.provider.Settings; import android.text.TextUtils; import android.text.format.Time; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.IDropBoxManagerService; import com.android.internal.util.DumpUtils; Loading Loading @@ -76,9 +83,6 @@ public final class DropBoxManagerService extends SystemService { private static final int DEFAULT_RESERVE_PERCENT = 10; private static final int QUOTA_RESCAN_MILLIS = 5000; // mHandler 'what' value. private static final int MSG_SEND_BROADCAST = 1; private static final boolean PROFILE_DUMP = false; // TODO: This implementation currently uses one file per entry, which is Loading @@ -95,6 +99,9 @@ public final class DropBoxManagerService extends SystemService { private FileList mAllFiles = null; private ArrayMap<String, FileList> mFilesByTag = null; private long mLowPriorityRateLimitPeriod = 0; private ArraySet<String> mLowPriorityTags = null; // Various bits of disk information private StatFs mStatFs = null; Loading @@ -105,7 +112,7 @@ public final class DropBoxManagerService extends SystemService { private volatile boolean mBooted = false; // Provide a way to perform sendBroadcast asynchronously to avoid deadlocks. private final Handler mHandler; private final DropBoxManagerBroadcastHandler mHandler; private int mMaxFiles = -1; // -1 means uninitialized. Loading Loading @@ -152,8 +159,142 @@ public final class DropBoxManagerService extends SystemService { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { DropBoxManagerService.this.dump(fd, pw, args); } @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver); } }; private class ShellCmd extends ShellCommand { @Override public int onCommand(String cmd) { if (cmd == null) { return handleDefaultCommands(cmd); } final PrintWriter pw = getOutPrintWriter(); try { switch (cmd) { case "set-rate-limit": final long period = Long.parseLong(getNextArgRequired()); DropBoxManagerService.this.setLowPriorityRateLimit(period); break; case "add-low-priority": final String addedTag = getNextArgRequired(); DropBoxManagerService.this.addLowPriorityTag(addedTag); break; case "remove-low-priority": final String removeTag = getNextArgRequired(); DropBoxManagerService.this.removeLowPriorityTag(removeTag); break; case "restore-defaults": DropBoxManagerService.this.restoreDefaults(); break; default: return handleDefaultCommands(cmd); } } catch (Exception e) { pw.println(e); } return 0; } @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); pw.println("Dropbox manager service commands:"); pw.println(" help"); pw.println(" Print this help text."); pw.println(" set-rate-limit PERIOD"); pw.println(" Sets low priority broadcast rate limit period to PERIOD ms"); pw.println(" add-low-priority TAG"); pw.println(" Add TAG to dropbox low priority list"); pw.println(" remove-low-priority TAG"); pw.println(" Remove TAG from dropbox low priority list"); pw.println(" restore-defaults"); pw.println(" restore dropbox settings to defaults"); } } private class DropBoxManagerBroadcastHandler extends Handler { private final Object mLock = new Object(); static final int MSG_SEND_BROADCAST = 1; static final int MSG_SEND_DEFERRED_BROADCAST = 2; @GuardedBy("mLock") private final ArrayMap<String, Intent> mDeferredMap = new ArrayMap(); DropBoxManagerBroadcastHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SEND_BROADCAST: prepareAndSendBroadcast((Intent) msg.obj); break; case MSG_SEND_DEFERRED_BROADCAST: Intent deferredIntent; synchronized (mLock) { deferredIntent = mDeferredMap.remove((String) msg.obj); } if (deferredIntent != null) { prepareAndSendBroadcast(deferredIntent); } break; } } private void prepareAndSendBroadcast(Intent intent) { if (!DropBoxManagerService.this.mBooted) { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM, android.Manifest.permission.READ_LOGS); } private Intent createIntent(String tag, long time) { final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED); dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag); dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time); return dropboxIntent; } /** * Schedule a dropbox broadcast to be sent asynchronously. */ public void sendBroadcast(String tag, long time) { sendMessage(obtainMessage(MSG_SEND_BROADCAST, createIntent(tag, time))); } /** * Possibly schedule a delayed dropbox broadcast. The broadcast will only be scheduled if * no broadcast is currently scheduled. Otherwise updated the scheduled broadcast with the * new intent information, effectively dropping the previous broadcast. */ public void maybeDeferBroadcast(String tag, long time) { synchronized (mLock) { final Intent intent = mDeferredMap.get(tag); if (intent == null) { // Schedule new delayed broadcast. mDeferredMap.put(tag, createIntent(tag, time)); sendMessageDelayed(obtainMessage(MSG_SEND_DEFERRED_BROADCAST, tag), mLowPriorityRateLimitPeriod); } else { // Broadcast is already scheduled. Update intent with new data. intent.putExtra(DropBoxManager.EXTRA_TIME, time); final int dropped = intent.getIntExtra(DropBoxManager.EXTRA_DROPPED_COUNT, 0); intent.putExtra(DropBoxManager.EXTRA_DROPPED_COUNT, dropped + 1); return; } } } } /** * Creates an instance of managed drop box storage using the default dropbox * directory. Loading @@ -176,15 +317,7 @@ public final class DropBoxManagerService extends SystemService { super(context); mDropBoxDir = path; mContentResolver = getContext().getContentResolver(); mHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { if (msg.what == MSG_SEND_BROADCAST) { getContext().sendBroadcastAsUser((Intent)msg.obj, UserHandle.SYSTEM, android.Manifest.permission.READ_LOGS); } } }; mHandler = new DropBoxManagerBroadcastHandler(looper); } @Override Loading @@ -211,6 +344,8 @@ public final class DropBoxManagerService extends SystemService { mReceiver.onReceive(getContext(), (Intent) null); } }); getLowPriorityResourceConfigs(); break; case PHASE_BOOT_COMPLETED: Loading Loading @@ -298,17 +433,16 @@ public final class DropBoxManagerService extends SystemService { long time = createEntry(temp, tag, flags); temp = null; final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED); dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag); dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time); if (!mBooted) { dropboxIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); } // Call sendBroadcast after returning from this call to avoid deadlock. In particular // the caller may be holding the WindowManagerService lock but sendBroadcast requires a // lock in ActivityManagerService. ActivityManagerService has been caught holding that // very lock while waiting for the WindowManagerService lock. mHandler.sendMessage(mHandler.obtainMessage(MSG_SEND_BROADCAST, dropboxIntent)); if (mLowPriorityTags != null && mLowPriorityTags.contains(tag)) { // Rate limit low priority Dropbox entries mHandler.maybeDeferBroadcast(tag, time); } else { mHandler.sendBroadcast(tag, time); } } catch (IOException e) { Slog.e(TAG, "Can't write: " + tag, e); } finally { Loading Loading @@ -382,6 +516,22 @@ public final class DropBoxManagerService extends SystemService { return null; } private synchronized void setLowPriorityRateLimit(long period) { mLowPriorityRateLimitPeriod = period; } private synchronized void addLowPriorityTag(String tag) { mLowPriorityTags.add(tag); } private synchronized void removeLowPriorityTag(String tag) { mLowPriorityTags.remove(tag); } private synchronized void restoreDefaults() { getLowPriorityResourceConfigs(); } public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; Loading Loading @@ -421,6 +571,10 @@ public final class DropBoxManagerService extends SystemService { out.append("Drop box contents: ").append(mAllFiles.contents.size()).append(" entries\n"); out.append("Max entries: ").append(mMaxFiles).append("\n"); out.append("Low priority rate limit period: "); out.append(mLowPriorityRateLimitPeriod).append(" ms\n"); out.append("Low priority tags: ").append(mLowPriorityTags).append("\n"); if (!searchArgs.isEmpty()) { out.append("Searching for:"); for (String a : searchArgs) out.append(" ").append(a); Loading Loading @@ -936,4 +1090,21 @@ public final class DropBoxManagerService extends SystemService { return mCachedQuotaBlocks * mBlockSize; } private void getLowPriorityResourceConfigs() { mLowPriorityRateLimitPeriod = Resources.getSystem().getInteger( R.integer.config_dropboxLowPriorityBroadcastRateLimitPeriod); final String[] lowPrioritytags = Resources.getSystem().getStringArray( R.array.config_dropboxLowPriorityTags); final int size = lowPrioritytags.length; if (size == 0) { mLowPriorityTags = null; return; } mLowPriorityTags = new ArraySet(size); for (int i = 0; i < size; i++) { mLowPriorityTags.add(lowPrioritytags[i]); } } }